Yet Another Multicolumn Layout | Ein (X)HTML/CSS Framework

4.5 Subtemplates

Mit dem blanken Layout ist die Webseite natürlich noch nicht fertig. Auch die Inhalte müssen entsprechend formatiert werden. Dabei besteht erstens an vielen Stellen die Notwendigkeit, kurze Inhaltsabschnitte nebeneinander anzuordnen, wobei hier nicht von Tabellendaten die Rede ist. Zweitens erfüllt ein herkömmliches Spaltenlayout nicht in jedem Fall die Anforderungen an die heutige Layoutgestaltung. Ein Beispiel für eine deutlich freiere Gestaltung ist die Startseite von www.yaml.de.

Für diese Zwecke bietet YAML so genannte Subtemplates. Das sind XHTML-Codebausteine (basierend auf floatenden Boxen), welche eine horizontale Gliederung von Inhalten innerhalb beliebiger Container ermöglichen oder als extem vielseitige Alternative/Ergänzung zum Spaltenkonzept für die Layoutgestaltung eingesetzt werden können.

Hinweis: Alle erforderlichen CSS-Definitionen für die Subtemplates befinden sich in der Datei base.css. Die Anpassungen für das korrekte automatische Clearing im Internet Explorer befinden sich in der Datei iehacks.css. Subtemplates sind in die Grundbausteine des Frameworks integriert und stehen somit in allen Layoutvariationen zur Verfügung.

Subtemplates können zudem ineinander geschachtelt werden. Dadurch lässt sich die Raumaufteilung nahezu beliebig variieren.

Struktureller Aufbau

Der Aufbau eines solchen Codebausteins soll exemplarisch an einem einfachen Beispiel erläutert werden. Hier der erforderliche XHTML-Code für eine 50/50 Teilung, also eine Aufteilung in zwei gleich große, nebeneinander liegende Blöcke.

50/50

<!-- Subtemplate: 2 Spalten mit 50/50 Teilung -->
<div class="subcolumns">
  <div class="c50l">
    <div class="subcl">
      <!-- Inhalt linker Block -->
      ...
    </div>
  </div>

  <div class="c50r">
    <div class="subcr">
      <!-- Inhalt rechter Block -->
      ...
    </div>
  </div>
</div>

33/66

<!-- Subtemplate: 2 Spalten mit 33/66 Teilung -->
<div class="subcolumns">
  <div class="c33l">
    <div class="subcl">
      <!-- Inhalt linker Block -->
      ...
    </div>
  </div>

  <div class="c66r">
    <div class="subcr">
      <!-- Inhalt rechter Block -->
      ...
    </div>
  </div>
</div>

25/75

<!-- Subtemplate: 2 Spalten mit 25/75 Teilung -->
<div class="subcolumns">
  <div class="c25l">
    <div class="subcl">
      <!-- Inhalt linker Block -->
      ...
    </div>
  </div>

  <div class="c75r">
    <div class="subcr">
      <!-- Inhalt rechter Block -->
      ...
    </div>
  </div>
</div>

33/33/33

<!-- Subtemplate: 3 Spalten mit 33/33/33 Teilung -->
<div class="subcolumns">
  <div class="c33l">
    <div class="subcl">
      <!-- Inhalt linker Block -->
      ...
    </div>
  </div>

  <div class="c33l">
    <div class="subc">
      <!-- Inhalt linker Block -->
      ...
    </div>
  </div>

  <div class="c33r">
    <div class="subcr">
      <!-- Inhalt rechter Block -->
      ...
    </div>
  </div>
</div>

Soweit der Überblick. Nun der genaue Blick in die Details.

Der Container

Ein Subtemplate beginnt immer mit einem DIV-Container der Klasse .subcolumns, welcher die einzelnen Container zur Raumaufteilung umschließt.

<!-- Subtemplate: 2 Spalten mit 50/50 Teilung -->
<div class="subcolumns">
...
</div>

In der Datei base.css erhält der Container .subcolumns folgende CSS-Eigenschaften, die nicht

verändert werden sollten.

/**
 * @section subtemplates
 * @see     ...
 */

.subcolumns { width: 100%; overflow:hidden; }
.subcolumns_oldgecko { width: 100%; float:left; }

Die Breite des Containers beträgt per Default 100 Prozent, damit füllt er den horizontal im Layout zur Verfügung stehenden Platz voll aus. Gleichzeitig bewirkt die Definition einer konkreten Breite die Aktivierung von hasLayout im Internet Explorer, wodurch dieser die Inhalte automatisch einschließt. Alle anderen Browser benötigen dazu die CSS-Eigenschaft overflow:hidden (siehe Abschnitt 2.3: Markupfreies Clearing).

Hinweis: Netscape-Browser bis einschließlich Version 7.1 bzw. alte Gecko-Browser (bis etwa Juli 2004) haben Probleme bei der Darstellung der Subtemplates aufgrund eines Bugs in Verbindung mit overflow:hidden. Ab Version 7.2 werden Subtemplates auch im Netscape korrekt dargestellt.

Wenn die alten Gecko-basierten Browser ebenfalls unterstützt werden sollen, dann können Sie alternativ die Klasse .subtemplates_oldgecko verwenden. Beachten Sie dabei die Hinweise im Abschnitt 5.3 zum overflow-Bug des Netscape-Browsers.

Die Raumaufteilung über DIV-Blöcke

Die horizontale Raumaufteilung erfolgt über die DIV-Blöcke mit den CSS-Klassen c50l und c50r. Das "c" steht dabei für column (Spalte), die Zahl "50" für 50 Prozent der verfügbaren Breite und die Buchstaben "l" und "r" für links- bzw. rechts-floatende Blöcke.

<!-- Subtemplate: 2 Spalten mit 50/50 Teilung -->
<div class="subcolumns">
  <div class="c50l">
  ...
  </div>
  <div class="c50r">
  ...
  </div>
</div>

In der Regel bilden zwei Blöcke (ein linker und ein rechter) ein Paar. In der Summe sollte die Gesamtbreite aller eingesetzten Blöcke innerhalb eines Subtemplates 100 Prozent betragen. Folgende Teilungsverhältnisse werden von YAML über vordefinierte CSS-Klassen zur Verfügung gestellt, z.B.:

  • 50% / 50% Teilung (Klassen c50l und c50r)
  • 33% / 66% Teilung (Klassen c33l und c66r sowie c66l und c33r)
  • 25% / 75% Teilung (Klassen c25l und c75r sowie c75l und c25r)
  • Goldener Schnitt (Klassen c38l und c62r sowie c62l und c38r)

Die verfügbaren Klassendefinitionen finden sich in der Datei base.css.

.c20l, .c25l, .c33l, .c40l, .c38l, .c50l,
.c60l, .c62l, .c66l, .c75l, .c80l {float: left; }
 
.c20r, .c25r, .c33r, .c40r, .c38r, .c50r,
.c60r, .c66r, .c62r, .c75r, .c80r {float: right; margin-left: -5px; }

.c20l, .c20r { width: 20%; }
.c40l, .c40r { width: 40%; }
.c60l, .c60r { width: 60%; }
.c80l, .c80r { width: 80%; }
.c25l, .c25r { width: 25%; }
.c33l, .c33r { width: 33.333%; }
.c50l, .c50r { width: 50%; }
.c66l, .c66r { width: 66.666%; }
.c75l, .c75r { width: 75%; }
.c38l, .c38r { width: 38.2%; }
.c62l, .c62r { width: 61.8%; }

Die reale Breite eines floatenden Containers wird vom Browser direkt vor dem Rendering des Containers ermittelt. Durch das Auf- und Abrunden bei der Umrechnung von Prozentwerten in Pixelmaße kann es (vorwiegend im Internet Explorer) zu Rundungsfehlern in Bezug auf die Gesamtbreite aller DIV-Blöcke innerhalb eines Subtemplates kommen.

Im Ergebnis überschreitet die Summe der Einzelcontainer die Breite des Elterncontainers .subcolumns, und es kommt zu Umbrüchen der floatenden DIV-Boxen. Um diesen Effekt zu vermeiden, erhalten alle rechts floatenden DIV-Blöcke zusätzlich die Eigenschaft margin-left: -5px. Damit wird erlaubt, dass ein rechts floatender Container ein Element, welches links neben ihm platziert ist, um maximal fünf Pixel überdecken darf. Auf diese Weise können die Rundungsfehler bei der Größenermittlung elegant ausgeglichen werden.

Wichtig: Damit der Ausgleich von Rundungsfehlern fehlerfrei funktioniert, muss sich innerhalb eines Subtemplates immer exakt ein rechts-floatender Container befinden.

Mit diesen vordefinierten CSS-Klassen lassen sich - zunächst ohne Verschachtelung der Subtemplates - folgende Raumaufteilungen bilden:

class="c80l"
class="c20r"
class="c75l"
class="c25r"
class="c66l"
class="c33r"
class="c62l"
class="c38r"
class="c60l"
class="c40r"
class="c50l"
class="c50r"
class="c40l"
class="c60r"
class="c38l"
class="c62r"
class="c33l"
class="c66r"
class="c25l"
class="c75r"
class="c20l"
class="c80r"
class="c33l"
class="c33l"
class="c33r"

Diese Blöcke können durch Einfügen weiterer Subtemplates beliebig tief ineinander verschachtelt werden. Auf diese Weise lassen sich fast beliebig strukturierte Raumaufteilungen erzeugen.

Die Inhaltscontainer

Wie schon bei den Layoutspalten des YAML-Frameworks übernehmen die äußeren Container (z.B. die DIV-Blöcke c50l und c50r) die Raumaufteilung, während über die inneren Container subc, subcl bzw. subcr die Abstände und Rahmen der Inhalte (padding, margin, border) geregelt werden.

<div class="subcolumns">
  <div class="c50l">
    <div class="subcl">
      <!-- Inhalt linker Block -->
      ...
    </div>
  </div>

  <div class="c50r">
    <div class="subcr">
      <!-- Inhalt rechter Block -->
      ...
    </div>
  </div>
</div>
.subc { padding: 0 0.5em 0 0.5em; }
.subcl { padding: 0 1em 0 0; }
.subcr { padding: 0 0 0 1em; }

Die Endbuchstaben "l" und "r" stehen wiederum für Inhaltsblöcke am linken oder rechten Rand des Subtemplates. Dies hat Einfluss auf die Innenabstände (padding). Für Inhaltsblöcke, die sich nicht in Randlage befinden (z.B. der mittlere Block einer 33/33/33 Teilung), steht der Container subc zur Verfügung, der ein beidseitiges Padding besitzt.

Damit die Spalten wirklich gleich breit werden, muss bei der Festlegung der Innenabstände (padding) für die Inhaltscontainer subc, subcl und subcr darauf geachtet werden, dass die Summe der jeweils vergebenen Paddings identisch ist.

Die Container subcl und subcr befinden sich planmäßig in Randlage und erhalten daher jeweils ein einseitiges Padding von 1em. Der Container subc benötigt demzufolge ein beidseitiges Padding, welches in der Summe ebenfalls 1em ergeben muss,  also ein linkes und rechtes Padding von jeweils 0.5 em.

Anpassungen der Subtemplates für den Internet Explorer

Bei den Subtemplates wird intensiver Gebrauch von der CSS-Eigenschaft float gemacht. Demzufolge muss natürlich auch mit den entsprechenden IE-Bugs (Escaping Floats Bug, Doubled-Float-Margin Bug) gerechnet werden. Des weiteren wird speziell bei der Arbeit mit flexiblen Containerbreiten das Expanding Box Problem sehr schnell spürbar.

Analog zu den Bugfixes für das YAML-Basislayout, lassen sich die bekannten Bugfixes natürlich auch auf die Subcolumns anwenden.

.c20l, .c25l, .c33l, .c38l, .c40l, .c50l, .c60l,
.c62l, .c66l, .c75l, .c80l, .c20r, .c25r, .c33r,
.c38r, .c40r, .c50r, .c60r, .c66r, .c62r, .c75r, .c80r {
   display:inline;
}

/* avoid growing widths */
* html .subc,
* html .subcl,
* html .subcr { word-wrap:break-word; o\verflow:hidden; }

Der Escaping Floats Bug wird bereits durch die Vorgabe von width:100% für den Container .subcolumns ausgeschaltet (über hasLayout). Die Eigenschaft display:inline beseitigt den Doubled-Float-Margin Bug und die beiden Eigenschaften word-wrap:break-word und overflow:hidden sorgen in den älteren IE-Generationen (IE5.x und IE6) dafür, dass übergroße Inhalte zuverlässig abgeschnitten werden und das Layout nicht zerstören.

Hinweis: Für die Druckausgabe wird die Eigenschaft word-wrap in der Datei iehacks.css wieder auf Ihren Standardwert word-wrap:normal zurück gesetzt.

Beispiele für die Anwendung von Subtemplates

Die nachfolgenden Beispiele zeigen exemplarisch die einfache Anwendung sowie die Möglichkeiten zur Verschachtelung von Subtemplates. Schauen Sie sich den Quelltext dieser Beispiele an, um sich mit der Vorgehensweise vertraut zu machen.

Hinweis: Weitere Anwendungsbeispiele für den Einsatz zur Content- und Layoutgestaltung finden Sie in den Layoutbeispielen, welche auch dem Download-Paket beiliegen.

50 / 50 Teilung

Block 1: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. Aliquam ut sem ut leo mattis ultricies. Aliquam aliquam ligula ut purus. ...

Block 2: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. Aliquam ut sem ut leo mattis ultricies. Aliquam aliquam ligula ut purus. ...

33 / 33 / 33 Teilung

Block 1: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. ...

Block 2: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. ...

Block 3: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. ...

Teilung nach dem Goldenen Schnitt

Block 1: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. Aliquam ut sem ut leo mattis ultricies. Aliquam aliquam ligula ut purus. ...

Block 2: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac ...

Endlose Vielfalt durch Schachtelung

Subtemplates können beliebig ineinander geschachtelt werden, so dass sich beinahe beliebige Raumaufteilungen ergeben. Einzige Bedingung: Innerhalb einer Schachtelungsebene sollte die Summe der Blöcke immer 100 Prozent ergeben.

Das nachfolgende Beispiel zeigt exemplarisch eine solche Schachtelung. Innerhalb des linken 50-Prozent-Blocks werden in der zweiten Ebene zwei weitere 50-Prozent-Blöcke platziert. Der rechte 50 Prozent breite Block wird in der zweiten Ebene nach dem Goldenen Schnitt geteilt.

Block 1: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. ...

 

Block 2: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. ...

Block 3: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor ...

Block 4: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ac lectus. Aenean tincidunt metus nec orci. Nulla dapibus mattis tellus. Ut dui nunc, ultrices ut, egestas vitae, feugiat ac, tortor. Nullam velit. Nunc ac urna. Nullam sed quam ac turpis porta porta. ...

Spezialfall: Gleichhohe Boxen

Ab der Version 3.1 unterstützt YAML von Haus aus die Erstellung von Inhaltscontainern mit gleichhohen Spalten - unabhängig von deren Inhalten - auf Basis von CSS.  Das dahinterstehende Konzept basiert auf dem Markup der Subtemplates, kombiniert jedoch zur Realisierung einer crossbrowser-tauglichen Lösung mehrere CSS-Layoutkonzepte.

Technischer Hintergrund

In modernen Browsern mit vollständiger CSS2-Unterstützung werden hierzu die Subtemplates in CSS-Tabellen umgewandelt. Im Internet Explorer 5.x - 7.0 wird diese Layouttechnik noch nicht unterstützt, daher kommt in diesen Browsern weiterhin das Float-Konzept zur Anwendung, erweitert um einen CSS-Hack zur Simulation gleichhoher Spalten mit Hilfe großer Paddings. Diese Technik wird ausführlich von Alex Robinson im Rahmen seines "one true layout" Artikels beschrieben. 

Die entsprechenden CSS-Regeln für die Kombination der verschiedenen Techniken sind in der base.css und iehacks.css vollständig integriert, sodass sie allgemein verfügbar sind. Regeln sind an die CSS-Klasse equalize gebunden, welche über die CSS-Kaskade einige Eigenschaften der normalen Subtemplates überschreibt. Auf eine detaillierte Erläuterung der Technik wird aufgrund der Komplexität verzichtet.

Anwendung

Die Erstellung gleichhoher Boxen innerhalb von YAML ist denkbar einfach. Sie aktivieren diese Eigenschaft der Subtemplates, in dem Sie dem umschließenden Container der Subtemplates zusätzlich die CSS-Klasse equalize zuweisen. Die damit zugewiesenen Eigenschaften werden vererbt, weswegen auch verschachtelte Subtemplates die gleichhohen Spalten übernehmen.

<!-- Subtemplate: 2 Spalten mit 50/50 Teilung -->
<div class="subcolumns equalize">
...
</div>

Durch die Zuweisung der CSS-Klasse .equalize werden die Container zur Raumaufteilung (.cxxl, .cxxr) auf gleiche Höhe gebracht. Die Inhaltscontainer (.subcl, .subcr, .subc) verhalten sich zunächst unverändert.

Das folgende Anwendungsbeispiel demonstriert die Möglichkeiten dieser Technik anhand von drei nebeneinander liegenden, flexiblen Boxen mit grafischer Umrandung.

/examples/06_layouts_advanced/equal_height_boxes.html

Wichtig: Aufgrund der für den Internet Explorer 5.x - 7.0 verwendeten technischen Lösung, ist eine Ausrichtung an der Unterkante der höhengleichen Container mittels absoluter Positionierung oder Hintergrundgrafiken nicht möglich.

Wird diese Positionierung aus Gestaltungsgründen benötigt, so steht die CSS-Klasse .no-ie-padding zur Verfügung, um die Erweiterung der Container im Internet Explorer zu deaktivieren. In diesem Fall müssen Sie als Layoutersteller selbst für Höhengleichheit sorgen - entweder durch Inhalte oder durch Vorgabe einer expliziten Höhe.

Wie dieser kompliziert klingende Workaround praktisch angewandt wird, demonstriert das Layoutbeispiel "equal height boxes" anhand der positionierten "more" Links. Für nähere Informationen werfen Sie einen Blick in den Quelltext dieses Beispiellayouts.