Spalten mit Floats in beliebiger Reihenfolge darstellen

(Auszug aus "CSS Kochbuch" von Christopher Schmitt)

Problem

Es soll möglich sein, die Spalten eines Layouts in einer beliebigen Reihenfolge darzustellen.

Lösung

Um das grundsätzliche dreispaltige Layout mit flexiblen Spaltenbreiten zu erstellen, verwenden wir den folgenden Code. Den zusätzlichen Markup-Code brauchen wir im weiteren Verlauf dieser Lösung noch:

<div id="ContainerAussen">
  <div id="Container">
    <div id="Inhalt" class="Spalte">
      <div class="eingepackt">
        [...]
      </div>
    </div> <!-- /ENDE #Inhalt -->
    <div id="Navigation" class="Spalte">
      <div class="eingepackt">
        [...]
      </div>
    </div> <!-- /ENDE #Navigation -->
    <div id="Informationen" class="Spalte">
      <div class="eingepackt">
        [...]
      </div>
    </div> <!-- /ENDE #Informationen -->
  </div> <!-- /ENDE #Container -->
</div> <!-- /ENDE #ContainerAussen -->
<div id="Copyright">
  [...]
</div>

Hierfür definieren wir die folgenden CSS-Regeln:

.Spalte {
 float: left;
 border: 1px solid green;
}

#Inhalt {
 margin-left: 20%;
 width: 60%;
}

#Navigation {
 margin-left: -80%;
 width: 20%;
}

#Informationen {
 width: 19%;
}

/* Anpassungen für IEx \*/
* html .Spalte {
 display: inline;
}

* html #Navigation li {
 height: 1%;
}
/**/

Dieser Code erzeugt das grundsätzliche Seitenlayout, das Sie in der folgenden Abbildung sehen können. Es besteht aus zwei schmaleren Spalten an den Außenseiten und einer inneren Spalte. Alle Spalten haben flexible Breiten.

Grundsätzliches dreispaltiges Layout mit flexiblen Breiten

Abbildung: Grundsätzliches dreispaltiges Layout mit flexiblen Breiten.

Dieses noch recht schlichte Fundament erweitern wir jetzt durch zusätzliche CSS-Regeln. Wenn Sie dem vorhandenen Code die folgenden Regeln hinzufügen, erhalten Sie ein Design wie in der nächsten Abbildung:

body {
 font: normal 62.5%/1.7 Verdana, Geneva, Helvetica, Arial, sans-serif;
 margin: 0;
 padding: 0;
}
#Container:after {
 clear: both;
 content: ".";
 display: block;
 height: 0;
 visibility: hidden;
}

#Container {
 display: inline-block;
}

/* Vor IE5/Mac verstecken \*/
#Container {
 display: block;
}
/**/

#ContainerAussen {
 background: url("bg-left.gif") repeat-y 20% 0;
}

#Container {
 background: url("bg-right.gif") repeat-y 80% 0;
}

.Spalte .eingepackt {
 padding: 20px;
}

#Inhalt .eingepackt {
 padding: 20px 30px;
}

#Inhalt p {
 margin-top: 0;
}

#Inhalt p:first-child {
 font: normal 1.4em/1.6 Georgia, Times, "Times New Roman", serif;
}

#Inhalt p:first-child:first-line {
 text-transform: uppercase;
}

#Navigation ul, #Navigation ul li {
 list-style: none;
 margin: 0;
 padding: 0;
}

#Navigation ul li {
 margin-bottom: .4em;
}

#Navigation li a {
 background: #36C;
 color: #FFF;
 border-left: 7px solid #09F;
 display: block;
 padding: .4em .4em .4em 20px;
 text-decoration: none;
}

#Navigation li a:hover {
 border-left: none;
 border-right: 7px solid #09F;
 padding-left: 27px;
}

#Information {
 color: #555;
 font-style: italic;
}

#Copyright {
 border: 1px solid #B2B2B2;
 border-width: 1px 0;
 clear: both;
 padding: 10px 20px;
 text-align: center;
}

#Copyright p {
 margin: 0;
}

Vollständiges mehrspaltige Layout

Abbildung: Das vollständige mehrspaltige Layout.

Diskussion

Das Float-Modell hat eine sehr bewegte Geschichte. Die Autoren der CSS-Spezifikation hatten eigentlich nicht vorgesehen, dass Floats für das Layout von Seiten verwendet werden. Sie wollten nur eine Möglichkeit schaffen, den Fluss von Inhalten um bestimmte Elemente zu steuern, so ähnlich wie align="left" und align="right" den Textfluss um ein img-Element steuern können. Und trotz ihres geplanten Einsatzgebietes stellen Floats mächtige und flexible Alternativen zu den traditionellen, tabellenbasierten Layouttechniken dar.

Der Designer Alex Robinson hat einen sehr einflussreichen Artikel veröffentlicht, der sich unter anderem mit Spalten in beliebiger Reihenfolge ("Any Order Columns") befasst. Die von Robinson entwickelte Technik ermöglicht es Entwicklern, mit Hilfe von Floats auf einfache Weise mehrspaltige Layouts zu erstellen. Unabhängig davon, wo im HTML-Code sie tatsächlich stehen, können so dargestellte Spalten eine beliebige Reihenfolge in der Darstellung einnehmen.

Der Markup-Code

Bevor Sie diese Technik verwenden, müssen Sie die Spalten im Markup-Code definieren, wie hier gezeigt:

<div id="Container">
  <div id="Inhalt" class="Spalte">
    <div class="eingepackt">
      [...]
    </div>
  </div> <!-- /ENDE #Inhalt -->
  <div id="Navigation" class="Spalte">
    <div class="eingepackt">
      [...]
    </div>
  </div> <!-- /ENDE #Navigation -->
  <div id="Information" class="Spalte">
    <div class="eingepackt">
      [...]
    </div>
  </div> <!-- /ENDE #Information -->
</div> <!-- /ENDE #Container -->

Innerhalb der div-Elemente können Sie beliebigen Markup-Code verwenden. In folgender Abbildung sehen Sie, wie das unbearbeitete Dokument aussieht. Wir haben uns in diesem Beispiel für ein paar Absätze und eine ungeordnete Liste entschieden.

Seitenlayout ohne Stildefinitionen

Abbildung: Seitenlayout ohne Stildefinitionen.

In diesem Beispiel haben wir für jede der drei Spalten div-Elemente verwendet, deren id-Attribute jeweils den Inhalt beschreiben: Inhalt, Navigation und Informationen. Wir hätten die Spalten auch einfach Mitte, Links und Rechts nennen können, was allerdings nicht besonders vorausschauend gewesen wäre. Was passiert beispielsweise, wenn sich die Reihenfolge der Spalten aufgrund einer Änderung in der CSS-Datei für die Website ändert? Möglicherweise erscheint das div-Element mit dem id-Wert Links nun auf der rechten Seite.

Die Spalten festlegen

Nachdem die grundsätzliche Markup-Struktur feststeht, können wir den einzelnen Spalten jetzt die benötigten float-Regeln zuweisen:

.Spalte {
 float: left;
}

Wie Sie in folgender Abbildung sehen, hat sich das Layout noch nicht sehr stark verändert. Der Copyright-Hinweis wurde ein wenig nach oben verschoben, aber größtenteils sind noch keine Änderungen wahrzunehmen. Die Spalten-divs stehen immer noch untereinander. Dies wird sich jedoch schnell ändern, sobald wir die Dimensionen der Blöcke festlegen.

Copyright-Hinweis hat sich verschoben

Abbildung: Der Copyright-Hinweis hat sich verschoben.

Wir befassen uns zuerst mit dem Block Inhalt. Mit der folgenden Regel legen wir seine Breite auf 60% des Ansichtsbereichs fest. Links davon soll ein Bereich von 20% des Ansichtsbereichs frei bleiben, der nachher die Navigationsspalte aufnehmen soll:

#Inhalt {
 margin-left: 20%;
 width: 60%;
}

In folgender Abbildung sieht das Layout noch ein wenig durcheinander aus, langsam nimmt es aber Form an.

Layout nach Definition der Stile für Inhaltsbereich

Abbildung: Das Layout nach der Definition der Stile für den Inhaltsbereich.

Indem wir den linken Außenabstand für den Inhalt mit 20% definiert haben, haben wir quasi Platz für die linke Spalte "reserviert". Im nächsten Schritt geben wir den div-Elementen mit der ID Navigation einen negativen Außenabstand. Auf diese Weise können wir den Navigationsbereich an seinen vorgesehenen Platz auf der linke Seite verschieben:

#Navigation {
 margin-left: -80%;
 width: 20%;
}

Der Wert für den linken Außenabstand berechnet sich aus der Breite des Inhaltsbereichs (60%) und dessen linken Außenabstand (20%). Auf diese Weise wird die Navigationsspalte an ihre korrekte Position verschoben (siehe folgende Abbildung).

Navigationsspalte wird auf linke Seite verschoben

Abbildung: Die Navigationsspalte wird auf die linke Seite verschoben.

Um das Layout fertigzustellen, müssen wir dem Block mit der ID Information jetzt nur noch eine Breite zuweisen, wie in der nächsten Abbildung gezeigt:

#Information {
 width: 20%;
}

Rechte Spalte wird an ihren Platz verschoben

Abbildung: Die rechte Spalte wird an ihren Platz verschoben.

Das sieht schon ausgezeichnet aus. Allerdings steht der Copyright-Hinweis noch nicht da, wo er hin soll. Das lässt sich aber mit der Eigenschaft clear recht einfach beheben (siehe nächste Abbildung):

#Copyright {
 clear: both;
}

Copyright-Hinweis wird unterhalb der anderen Elemente angezeigt

Abbildung: Der Copyright-Hinweis wird unterhalb der anderen Elemente angezeigt.

Jetzt scheint das Layout fertig zu sein. Wie Sie in folgender Abbildung sehen können, gibt es aber noch Schwierigkeiten bei der Darstellung im Internet Explorer für Windows. Das sollten wir ändern.

Darstellungsprobleme im Internet Explorer für Windows

Abbildung: Darstellungsprobleme im Internet Explorer für Windows.

Glücklicherweise ist dieser IE-Programmierfehler dokumentiert. Er ist unter dem Namen "Doubled Float-Margin Bug" bekannt. Wird ein Element z.B. als links angeordneter Float definiert und diesem auf dessen linker Seite ein Außenabstand zugewiesen, so ist dessen Breite in der Darstellung durch den Internet Explorer doppelt so groß wie der eigentlich definierte Wert (das Gleiche gilt für rechts angeordnete Floats und auf deren rechter Seite definierte Außenabstände).

In unserer Lösung weisen wir einem links angeordneten Float einen linken Außenabstand von 20% zu. Internet Explorer für Windows verdoppelt diesen aufgrund des Programmierfehlers auf 40%.

Zum Glück lässt sich das Problem leicht beheben. Wenn wir die Darstellungsrolle des betreffenden Elements auf inline setzen, benimmt sich auch der Internet Explorer wieder anständig. Hierfür verwenden wir den folgenden CSS-Code:

/* Anpassungen für IEx \*/
* html .Spalte {
 display: inline;
}
/**/

Die seltsam formatierten Kommentare und der speziell formatierte Selektor * html sorgen dafür, dass diese Regel ausschließlich vom Internet Explorer bis zur Version 6 erkannt wird. Wie wir in folgender Abbildung sehen können, verhält sich IE nach Anwendung dieser Regel tatsächlich korrekt.

Mit speziellen CSS-Regeln funktioniert Layout nun auch im IE für Windows

Abbildung: Mit den speziellen CSS-Regeln funktioniert das Layout nun auch im Internet Explorer für Windows.

Endlich haben wir es geschafft: eine flexible dreispaltige Layout-Vorlage. Aber was können wir sonst noch alles damit anstellen?

Leerraum schaffen

Der Spaltenabstand wird in der Typografie auch als Zwischenschlag (engl. gutter) bezeichnet. Eine Möglichkeit, den Raum zwischen den Spalten zu vergrößern, besteht darin, die Spalten mit Außenabständen zu versehen. Es gibt aber noch weitere Möglichkeiten, diesen Effekt zu erzielen. Zuerst müssen wir die einzelnen Spalten allerdings mit zusätzlichen div-Elementen umgeben:

<div id="Container">
  <div id="Inhalt" class="Spalte">
    <div class="eingepackt">
      [...]
    </div>
  </div> <!-- /ENDE #Inhalt -->
  <div id="Navigation" class="Spalte">
    <div class="eingepackt">
      [...]
    </div>
  </div> <!-- /ENDE #Navigation -->
  <div id="Information" class="Spalte">
    <div class="eingepackt">
      [...]
    </div>
  </div> <!-- /ENDE #Information -->
</div> <!-- /ENDE #Container -->

Den zusätzlichen div-Elementen haben wir über das Attribut class den Wert eingepackt zugewiesen. (Vom Englischen "to wrap" – umgeben, einpacken. Anm. d. Ü.) Diesem können Sie über einen Klassenselektor etwas mehr Platz verschaffen (siehe folgende Abbildung):

Spaltenabstand wurde vergrößert

Abbildung: Der Spaltenabstand wurde vergrößert.

.Spalte .eingepackt {
 padding: 20px;
}

#Inhalt .eingepackt {
 padding: 20px 30px;
}

Die Reihenfolge der Spalten ändern

Wie Sie vielleicht schon bemerkt haben, basiert die Methode der "Spalten mit beliebiger Reihenfolge" auf der intelligenten Verwendung von Außenabständen. Positive Außenabstände sorgen dafür, dass Platz "reserviert" wird, während negative Außenabstände benutzt werden können, um Spalten von ihrer normalen Position zu verschieben.

Wir wollen uns für einen Moment nur die Breitenangaben für die Spalten ansehen:

#Inhalt {
 width: 60%;
}
#Navigation {
 width: 20%;
}
#Informationen {
 width: 19%;
}

Ohne definierte Außenabstände werden die Spalten nun als Floats in der Reihenfolge ihrer Definition im HTML-Code dargestellt, wie in folgender Abbildung gezeigt.

Navigationsspalte wird zwischen den beiden anderen Spalten dargestellt

Abbildung: Die Navigationsspalte wird zwischen den beiden anderen Spalten dargestellt.

Wenn wir dem Navigationselement (<div class="Navigation">) einen linken Außenabstand und dem Informationselement (<div class="Information">) einen negativen Außenabstand zuweisen, können wir die Reihenfolge der zwei hinteren Spalten in der Darstellung umkehren. Der folgende CSS-Code erzeugt die Darstellung in der nächsten Abbildung:

#Inhalt {
 width: 60%;
}
#Navigation {
 margin-left: 20%;
 width: 20%;
}
#Informationen {
 margin-left: -39%;
 width: 19%;
}

Position der letzten beiden Spalten wurde vertauscht

Abbildung: Die Position der letzten beiden Spalten wurde vertauscht.

Wir wollen das Beispiel beschließen, indem wir die Inhaltsspalte (<div class="Inhalt">) auf die rechte Seite verschieben (siehe nächste Abbildung).

Hierfür verwenden wir den folgenden CSS-Code:

#Inhalt {
 margin-left: 40%;
 width: 60%;
}
#Navigation {
 margin-left: -100%;
 width: 20%;
}
#Informationen {
 margin-left: -80%;
 width: 19%;
}

Inhaltsspalte wurde auf rechte Seite verschoben

Abbildung: Die Inhaltsspalte wurde auf die rechte Seite verschoben.

Wie beim ersten Layout wurde auch der Inhaltsspalte ein Außenabstand zugewiesen, um links auf der Seite Platz zu reservieren. Mit Hilfe negativer Außenabstände können danach die div-Elemente für Navigation und Informationen an ihre neue Position auf der Seite verschoben werden.

Algorithmus für das Seitenlayout

Mit dem folgenden Algorithmus können Sie die negativen Außenabstände einer Spalte berechnen:

  1. Ermitteln Sie für die betreffende Spalte zuerst für alle im Quellcode vorher genannten Spalten den am weitesten rechts liegenden Punkt.
  2. Führen Sie das gleiche Verfahren für den am weitesten links liegenden Punkt durch.
  3. Subtrahieren Sie nun den rechten Wert vom linken Wert, und Sie erhalten die Angabe für den linken Außenabstand der Spalte, die verschoben werden soll.

Sollte dieses Verfahren einmal nicht funktionieren, gibt es immer noch die gute alte "Versuch- und-Irrtum"-Methode.

"Gefälschte" Spalten

Wir wollen nun zum ursprünglichen Layout (siehe folgende Abbildung) zurückkehren und einmal sehen, wie wir die Darstellung der Spalten ein wenig aufpolieren können. Der erste Schritt: Hintergrundbilder!

Fertiges Layout ohne Grafiken

Abbildung: Das fertige Layout ohne Grafiken.

Die Technik der sogenannten Faux Columns wurde vom Webdesigner Dan Cederholm entwickelt. Sie basiert auf horizontal gekachelten Hintergrundbildern für die Spalten.

Durch die Verwendung eines gekachelten Hintergrundbildes funktioniert Cederholms Technik besonders gut bei Designs mit festen Breiten. Das Verfahren ist aber so vielseitig, dass wir nur geringfügige Änderungen vornehmen müssen, damit es auch in einem flexiblen Layout funktioniert.

Zuerst benötigen Sie für beide Seiten der Inhaltsspalte je ein Bild (siehe die folgenden beiden Abbildungen).

Grafik für linke Seite der Spalte

Abbildung: Grafik für die linke Seite der Spalte.

Grafik für rechte Seite der Spalte

Abbildung: Grafik für die rechte Seite der Spalte.

Als Nächstes müssen Sie den Container-Block mit einem zusätzlichen div-Element umgeben:

<div id="ContainerAussen">
  <div id="Container">
    [hier steht der Rest der Layout-Schablone]
  </div> <!-- /ENDE #Container -->
</div> <!-- /ENDE #ContainerAussen -->

Schließlich muss das Stylesheet noch um die folgenden Regeln erweitert werden:

#Container:after {
 clear: both;
 content: ".";
 display: block;
 height: 0;
 visibility: hidden;
}

#Container {
 display: inline-block;
}
/* Vor IE5/Mac verstecken \*/
#Container {
 display: block;
}
/**/

#ContainerAussen {
 background: url("bg-left.gif") repeat-y 20% 0;
}

#Container {
 background: url("bg-right.gif") repeat-y 80% 0;
}

Wie in der folgenden Abbildung zu sehen ist, werden die Spalten nun, unabhängig von der Länge ihres Inhalts, immer in voller Länge dargestellt.

Layout wird mit Grafiken versehen

Abbildung: Das Layout wird mit Grafiken versehen.

Diesem Grundlayout können Sie nun weitere, nicht nur typografische, Stildefinitionen zuweisen. Die in unserer Lösung verwendeten Regeln funktionieren schon recht gut. Das Ergebnis sehen Sie in der nächsten Abbildung.

Fertiges Seitenlayout

Abbildung: Das fertige Seitenlayout.

Eine alternative Lösung

Die Verwendung von Floats für das Seitenlayout ist sehr mächtig, hat aber auch eine sehr steile Lernkurve. Viele Designer bevorzugen daher die Verwendung von absoluter Positionierung, um die verschiedenen Elemente ihres Designs anhand von x- und y-Koordinaten exakt zu positionieren.

Leider werden absolut positionierte Elemente vom Dokumentenfluss ausgenommen. Der Inhalt wird innerhalb des umgebenden Blocks umbrochen. Als Ergebnis kann bei "positionierten" Layouts die Eigenschaft clear nicht verwendet werden. Im Gegensatz dazu können bei der Verwendung von Floats bestimmte Teile Ihres Layouts "kontext-sensitiv" gestaltet werden. Durch die Regel clear: both; können Sie bei Floats beispielsweise festlegen, dass eine Fußzeile prinzipiell unterhalb der Spalten erscheinen soll. Bei "positionierten" Layouts ist das nicht ohne Weiteres möglich.

Shaun Inman, ein talentierter Webdesigner, hat eine JavaScript-Funktion geschrieben, die dieses Problem umgeht. Wenn Sie dieses Skript in Ihre Webseiten integrieren, werden entsprechend markierte Elemente automatisch von den positionierten Elementen "freigestellt" (siehe nächste Abbildung).

Layout mit absoluter Positionierung

Abbildung: Ein Layout mit absoluter Positionierung.

Der einzige mögliche Nachteil dieser Methode besteht darin, dass sie nur funktioniert, wenn JavaScript im Browser aktiviert ist. Daher sollten Sie Ihre Seiten auf jeden Fall testen. Ist der Inhalt im Zielbrowser auch ohne JavaScript noch zugänglich, ist alles in Ordnung.

Siehe auch

Das Rezept Asymmetrische Layouts zum Erstellen asymmetrischer Layouts mit Hilfe absoluter Positionierung.

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema CSS bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright der deutschen Ausgabe © 2007 by O’Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "CSS Kochbuch" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O’Reilly Verlag GmbH & Co. KG, Balthasarstr. 81, 50670 Köln