Archive for the ‘Uncategorized’ Category

Per CSS zwei Spalten gleich hoch gestalten beim Einsatz von Responsive Design

Heute habe ich mich mit einem interessanten CSS-Problem beschäftigt, dass vielleicht noch ein paar mehr Leute beschäftigt:

Wir hatten auf der Startseite zwei Spalten innerhalb des Hauptcontents, welche in ihrer Größe unabhängig voneinander sind und bei denen sich der Inhalt immer wieder verändern kann und damit auch keine Aussage getroffen werden kann, welche Spalte höher sein wird. In der ersten Version waren beide Spalten einfach mit float nebeneinander angeordnet, aber dadurch schloßen sie nicht auf der gleichen Höhe ab.

Der HTML-Code Aufbau

 <div class="content"> . . . <div class="content-bottom"> < div class="column left"> < /div> < div class="column right"> < /div> </div> </div> 

Innerhalb der beiden inneren divs befindet sich der eigentliche Inhalt mit mehren Überschriften, Links und Textabschnitten.

Ein Problem, viele Lösungswege

Grundsätzlich gibt es an mehrere Möglichkeiten dieses Problem zu lösen und gibt dazu auch einige sehr gute Übersichtspost mit unterschiedlichen Möglichkeiten und ihren Vor- und Nachteilen. Doch in meinem speziellen Fall fielen viele Möglichkeiten aus der Auswahl heraus, denn

  • Der Inhalt der Spalten ist dynamisch und die Höhe somit nicht vorher bestimmbar
  • Die Seite nutzt ein Responsive Design und muss somit in jeder Breite gut aussehen
  • Alle Breiten sind in % angegeben und dies ist z.b. mit Border nicht nutzbar

Dadurch waren Möglichkeiten, die mit Bildern arbeiten ausgeschlossen, da diese beim verkleinern nicht ideal sind und Lösungen mit negativem Padding-bottom finde ich persönlich recht unschön, dadurch vielen auch solche aus dem Rennen. Auch wollte ich keine weiteren unnötigen Elemente ins HTML einführen um ein CSS-Problem zu lösen oder den Inhalt in einen HTML-Table bauen.

Die Lösung? Display:table

Ich habe mich dann dazu entschlossen mit display:table-cell zu arbeiten. Hiermit stellt man das Verhalten von HTML Tables im CSS nach um gewisse Vorteile der Tables nutzen zu können ohne sie semantisch falsch im HTML Code nutzen zu müssen. Im konkreten Fall bedeutet dass, dass äußere div-Element im CSS display:table bekommt und die inneren Elemente display:table-cell. Teilweise liest man, dass man noch zusätzlich ein div mit display:table-row braucht aber es funktioniert definitiv auch ohne!

Im CSS haben wir somit

 .content { width:100%; max-width:1000px } .content-bottom { display:table; width:100%; } .column { display:table-cell; width:46.9387755%; //übrig von dem alten Code }

Das nächste Problem: einen Abstand zwischen den Spalten

Damit waren die Element gleich hoch (nachdem der Code noch etwas aufgeräumt wurde) aber er spannte auch die gesamte 100% Breite – es sollen aber zwei Spalten mit Abstand zwischen den Spalten sein, welche eine andere Farbe haben als der Hintergrund (und Abstand). Durch den Einsatz von display:table kann man nicht mit margin arbeiten, sondern muss sich dem von HTML-Tables bekannte border-spacing bedienen. Der große Nachteil: Zum einen kann man nur mit Pixel-Werten arbeiten, nicht mit prozentualen Breiten und zum anderen wird es auf alle Kanten des Table angewandt: somit auch oben und unten und viel wichtiger: links und rechts! Da die Spalten aber links und rechts mit dem Element oben drüber Kantengleich abschließen sollte und diese 100% der Breite nutzt, wurde es Zeit in die Trickkiste zu greifen…
Nach einigem Überlegen viel mir ein, dass ich das umliegende div (content-bottom) einfach Breiter als 100% machen konnte und somit die inneren Elemente auf gleiche Breite wie die restliche Seite zu bringen.

 .content { width:100%; max-width:980px; overflow:hidden; } .content-bottom { display:table; width: 104.0816327%; //bei einer Breite von 980px für den Inhalt entspricht dies 1020px overflow: auto; border-spacing: 20px; } .column { display:table-cell; width:50%; }

Somit waren die Elemente gleich breit wie der restliche Inhalt und haben die gleiche Höhe, egal wie hoch die einzelnen Elemente werden. Damit in den kleineren breiten keine Scroll-Balken am unteren Rand entstehen, hat das .content-div noch ein overflow:hidden bekommen, wodurch der überliegende, inhaltsleere Bereich von .content-bottom einfach verschwindet und keine Scrollbalken auslöst.

Browser-Support

Der Browser-Support für display:table ist erstaunlich gut: alle aktuellen Browser unterstützen es und selbst IE versteht ab Version 8 damit umzugehen. IE6 berücksichtigen wir zum Glück nicht mehr, für IE7 habe ich aber über den *-Hack einfach den alten Code für die Breiten und float:left eingebaut, so dass der Inhalt genauso wie vorher erscheint und die Boxen nur nicht gleich hoch sind.

UPDATE 19.6.2012: Inzwischen habe ich display:table auch auf einer anderen Webseite für die Unterteilung von Blog-Content und Seitenleiste verwendet. Firefox hat das gar nicht gefallen, obwohl es in allen anderen Browsern funktioniert hat. Für den Moment benutze ich einen “dirty fix” mit einem zusätzlichen display:table auf dem umschließenden div, ich werde aber in den nächsten Tagen auf genauere Fehlersuche gehen.