Nicht ermittelbare Höhe von Listenelementen

Vor ein paar Tagen bin ich auf ein Problem aus der Kategorie „Wald vor lauter Bäumen“ gestoßen, das eigentlich ganz einfach ist, aber bei dem ich extrem knobeln musste, bis ich es verstanden hatte. Das sah so aus: Eine Liste wurde im Stil von großen Buttons angezeigt. Ich brauchte die Höhe eines Buttons, um mit JavaScript eine Scroll-Lösung erstellen zu können (das Ganze war für einen Touchscreen gedacht). Eigentlich ja nicht so schwer, aber als Höhe der Listenelemente wurde mir immer 0 ausgegeben! Auch die ganze Liste hatte nur eine Höhe weniger Pixel! Und zwar in allen Browsern, also war es auch kein Browser-Bug. Gleichzeitig konnte ich die Buttons aber ja sehen, und bin daran ein bisschen irre geworden für einige Zeit. Das sah in etwa wie folgt aus:

Listenelemente

Erst nach viel Herumprobieren mit Firebug kam ich dann der Ursache auf die Spur: Die Listen-Inhalte waren gefloatet, innen drin hatte jedes Listenelement ein div mit einem Link, der schön als Button gestaltet war. Was passiert aber mit Floats, wenn kein clear benutzt wird? Richtig, die Elemente dehnen sich nicht auf die Höhe ihres Inhaltes aus. Den Inhalt sieht man nur, weil nichts anderes für overflow definiert ist. Hier war es auch so: Die div-Elemente waren gefloatet und die darin enthaltenen a-Elemente auch. Das führte dazu, dass die li-Elemente sich so verhielten, als wären sie leer. Das wiederum führte dazu, dass auch das ul-Element sich wie ein leeres Element verhielt!

Sehr vereinfacht sah der Code also so aus:

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Float-Test</title>
	<style type="text/css">
	  #button_list {
	    list-style: none;
	    width: 300px;
	  }
	  
	  #button_list li {
	    display: block;
	  }
	  
	  .button {
	    display: block;
	    width: 300px;
	    height: 50px;
	    background-color: #FFFF00;
	    margin: 5px 0px;
	    text-align: center;
	  }
	  
	  a, div {
	    float: left;
	  }
	</style>
  </head>
  <body onload="alert('Listenhöhe=' + document.getElementById('button_list').clientHeight + ', li-Höhe=' + document.getElementById('test_li').clientHeight);">
    <ul id="button_list">
	  <li id="test_li"><div><a href="#" class="button">Lorem</a></div></li>
	  <li><div><a href="#" class="button">Ipsum</a></div></li>
	  <li><div><a href="#" class="button">Dolor</a></div></li>
	</ul>
  </body>
</html>

Das Float war in diesem Fall übrigens keine Notwendigkeit, sondern es wirkte sich ein anderes Stylesheet des verwendeten Frameworks unabsichtlich aus. Hätten die Listen-Elemente eine ermittelbare Höhe gehabt und nur die Liste nicht, wäre ich sicher schneller drauf gekommen, aber dadurch dass beides die Höhe 0 hatte, habe ich lange Zeit in die falsche Richtung gedacht. Zudem gibt es mehrere verschiedene Höhen-Attribute plus weitere Methoden durch Frameworks wie Prototype. Auch hier kann man mit dem Druchprobieren viel Zeit verbringen.

Um sich das ganze zu verdeutlichen, kann man der Liste einen roten Rand und ein Padding von 2px geben, dann sieht es so aus:

Liste mit Rahmen

Wie kann man das Problem nun lösen? Wenn man das float nicht loswerden kann, dann braucht es ein clear, welches die Eltern-Elemente zwingt, die Höhe ihrer Kinder anzunehmen. Das clearende Element kommt nach den gefloateten Elementen in die Listenelemente hinein. Achtung: Normalerweise würde man ein div dafür verwenden. Nun haben wir dummerweise mit der unbedachten Float-Anweisung alle div-Elemente gefloatet – also auch das clear-Element, was dann nicht mehr funktionieren würde. Man kann das float für das clear-Element explizit wieder ausstellen, oder man nimmt ein anderes Element, Hauptsache es ist kein Inline-Element. Folgendes Beispiel verdeutlicht das, man sollte natürlich stattdessen lieber eine Klasse benutzen:

<ul id="button_list">
  <li id="test_li"><div><a href="#" class="button">Lorem</a></div><span style="display: block; clear: left;"></span></li>
  <li><div><a href="#" class="button">Ipsum</a></div><span style="display: block; clear: left;"></span></li>
  <li><div><a href="#" class="button">Dolor</a></div><span style="display: block; clear: left;"></span></li>
</ul>

Und das sieht dann so aus:

Korrigierte Listenelemente

Auf diese Weise funktioniert nun auch wieder das Auslesen der Höhe der „Buttons“!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Bitte beachte die Kommentarregeln: 1) Kein Spam, und bitte höflich bleiben. 2) Ins Namensfeld gehört ein Name. Gerne ein Pseudonym, aber bitte keine Keywords. 3) Keine kommerziellen Links, außer es hat Bezug zum Beitrag. mehr Details...

So, noch mal kurz drüber schauen und dann nichts wie ab damit. Vielen Dank fürs Kommentieren! :-)