W3C hat heimlich mein alten Freund die Tabelle neu erfunden

Titel CSS Grid

Als ich anfangs März ein Artikel über die Integration von Grid in Firefox von Rachel Andrew gelesen habe, hätte ich fast übersehen, dass ein alter Freund vom W3C wieder erweckt wurde. CSS Grid soll laut Chris House das leistungsstärkste Layoutsystem im CSS sein. Rachel spricht gar vom Auslöser der grössten Party in der Szene. Andere…

Seit einer halben Ewigkeit befasse ich mich mit den Aspekten des Webdesigns. Wobei am Anfang ja alles ganz einfach war. Da gab es nur HTML, mit dem wir uns befassen mussten. Einfache Tags wie zum Beispiel <h1>Headline</h1> kapierten wir alle schnell und bastelten daraus unsere Webseiten. Das Layout war zwar zum Fürchten, aber wir waren ja alle total fasziniert über die Möglichkeiten, überhaupt was ins Netz stellen zu können. Die Wilden unter uns peppten die Webseiten mit animierten GIFs auf, sodass bald alles blinkte und sich bewegte. Damit alle diese animierten GIFs auch da platziert werden konnten, wo wir sie haben wollten, nutzten wir versteckte Tabellen. In diese Tabellen klebten wir die Bilder, die wir so an der gewünschten Stelle platzierten.

Plötzlich geisterte in der Szene herum, dass es nun Cascading Style Sheets (CSS) gibt und nun alles besser wird. Damit war es nun endlich möglich, den Content vom Design zu trennen. Aber dass hiess auch, dass ich von meinen lieb gewonnen Tabellen Abschied nehmen musste. Denn Tabellen sind Content und nicht Design. Mit den verrücktesten Tricks haben wir nun versucht, alles da zu platzieren, wo es hingehörte. Div Verschachtelung bis zum Abwinken war die Folge. Natürlich haben die Smartphones das nicht gerade einfacher gemacht.  Denn natürlich muss alles responsiv und auf jedem noch so verrückten Bildschirm darstellbar sein. Eine Webseite zu bauen, die gut aussieht, sowohl auf einem Handy mit einer Bildschirmbreite vom 6 cm wie auch auf einem Datenmonitor mit einer Breite von 3 Metern, ist nicht ganz einfach. Dann gibt es da ja noch die Webapplikationen, bei denen Tausende Elemente genau am richtigen Ort sein müssen, damit das Interface funktioniert.

Viele trauerten den verlorenen Tabellen nach. Die Flexboxen sind zwar toll, doch einfach auch nicht immer das Gelbe vom Ei. Es gab diverse Ansätze meine geliebten Tabellen zurückzubringen. Da kam der sogenannten Grid Ansatz. An dem wird bereits seit 2012 herumgebastelt. Leider wurde aber kein Standard definiert, was den Einsatz auf den verschiedenen Plattformen eher zu einem Glücksspiel machte. Anfangs März stolperte ich über einen Blogartikel von Rachel Andrew „CSS Grid lands in Firefox 52“. Darin machte sie, ein riesen Tamtam um dieses Grid, das in der Firefox Version 52 integriert worden war. Ich dachte, dass nun Firefox auch wieder eine eigene Definition vom Grid erschaffen hatte. Als ich dann noch über den Artikel von Chris House „A Complete Guide to Grid“ gestolpert bin, wurde ich hellhörig. Es stellt sich heraus, dass am 9. Februar 2017 das W3C still und heimlich die „finale“ Version des CSS-Grids veröffentlicht hat. Zudem haben alle Browser die Definitionen bereits integriert. Na ja fast alle, denn in Microsoft Edge natürlich noch nicht. Da ist noch eine alte Version integriert. Aber das wird noch kommen. Microsoft braucht in allem etwas länger, aber machen es dann doch recht gut.

Aber wieder zurück zum CSS Grid. Ich habe mir das also ganz genau angeschaut. Jetzt verstehe ich die Aufregung von Rachel und wieso sie 5 Jahre mitgeholfen hat, daran zu bauen. Es ist wirklich sehr gut gelungen. Denn nicht nur, dass jetzt alles wieder sauber platziert werden kann, auch resposives Design ist damit möglich. Die Flexboxen, dynamischen Spalten das ganze Liquid Design macht mit CSS-Grid nun endlich wirklich Sinn und funktioniert.

Machen wir mal ein konkretes Beispiel. Folgender HTML Code nehme ich mal als Ausgangslage:

      <div class=»header»>Header</div>
      <div class=»navigation»>Navigation</div>
      <div class=»content»>
 
        Content
        <div class=»content_container»>
           <div>Content 1</div>
           <div>Content 2</div>
           <div>Content 3</div>
           <div>Content 4</div>
           <div>Content 5</div>
        </div>
 
      </div>
      <div class=»aside»>Aside</div>
      <div class=»footer»>
 
        Footer
        <div class=»footer_container»>
            <div>Footer left</div>
            <div>Footer middle</div>
            <div>Footer right</div>
        </div>
 
      </div>
    </div>
Die üblichen Bereiche die wir in dem meisten Seiten finden. Im Content Bereich habe ich mit Content 1 – 5 die einzelnen Inhaltscontainer vorgesehen, die für Artikel Bilder etc. zur Verfügung stehen. Im Bereich Aside können zusätzlich Informationen platziert werden. Der Footer Bereich habe ich noch unterteilt, da ich da vielleicht die Links zu den sozialen Medien, Copyright Hinweise und Link zum Impressum etc. trennen möchte. Das Ganze in einer einfachen div Verschachtelung.
Nun zum spannenderen Tail dem CSS. Zuerst definieren wir die einzelnen Bereiche und weisen ihnen einer Grid Area zu. Diese benötigen wir später für die Einteilung des Grids. Hier zum Beispiel der Bereich header, dem die Area head zugewiesen wird:
      .header {
        grid-area: head;
      }
Dies machen wir mit allen Bereichen.
Dann definiere wir das Grid und sagen, welche Bereiche wo auftauchen sollen.
        .main_container {
          display: grid;
          grid-gap: 1em;
          grid-template-columns: 200px 1fr 200px;
          grid-auto-rows: auto;
          grid-template-areas:
            «head head head»
            «navi cont asid»
            «foot foot foot»
        }

Hier haben wir definiert, dass das Grid drei Spalten haben wird.
Mit grid-teplate-columns: 200px 1fr 200px; definieren wir, dass die links Spalte 200 Pixel breit sein soll. Die mittlere Spalte soll sich an den Bildschirm anpassen. Die rechte Spalte hat ebenfalls eine Breite von 200 Pixel. Mit den Zeilen machen wir es uns einfach und definieren mit grid-auto-row: auto; dass so viel Zeilen erstellt werden sollen, wie wir Areas zuweisen.

Jetzt zur eigentlichen Magie. Im Befehl grid-template-areas: definieren wir, wo die einzelnen Bereiche auftauchen sollen.

«head head  head»
«navi  cont asid»
«foot  foot    foot»

Hier habe ich ein 3 mal 3 grosses Gitter definiert. In der ersten Zeile soll der Header Bereich erscheinen. In der zweiten Zeile kommt zuerst der Bereich für die Navigation. In der Mitte der Content und rechts der Bereich Aside. Die letzte Zeile ist dann für den Footer Bereich reserviert.
Wenn wir nun bevorzugen würden, dass die Navigation über die gesamte linke Seite gehen soll, dann definiere wir einfach das Gitter so:

navi  head  head»
«navi  cont   asid»
«navi  foot    foot»

Damit können wir sehr schnell die Grundstruktur der Seite umstellen.

Mein gesamter Beispielcode sieht dann wie folgt aus. Ich habe den Code ganz einfach gehalten, damit du ihn einfach in eine HTML-Datei kopieren und damit herum experimentieren kannst.

<!DOCTYPE html>
<html>
  <head>
    <meta name=»viewport» content=»width=device-width, initial-scale=1.0″>
    <style>
 
      .header {
        grid-area: head;
      }
 
      .navigation {
        grid-area: navi;
      }
 
      .content {
        grid-area: cont;
      }
 
      .aside {
        grid-area: asid;
      }
 
      .footer {
        grid-area: foot;
      }
 
      .main_container {
        display: grid;
        grid-gap: 1em;
        grid-template-columns: 1fr;
        grid-auto-rows: auto;
        grid-template-areas:
          «head»
          «navi»
          «cont»
          «asid»
          «foot»
      }
 
      .footer_container {
         display: grid;
         grid-gap: 1em;
      }
 
      @media only screen and (min-width: 481px) {
        .main_container {
          display: grid;
          grid-gap: 1em;
          grid-template-columns: 1fr 200px;
          grid-auto-rows: auto;
          grid-template-areas:
            «head head»
            «navi navi»
            «cont asid»
            «foot foot»
        }
 
      }
 
      @media only screen and (min-width: 1024px) {
        .main_container {
          display: grid;
          grid-gap: 1em;
          grid-template-columns: 200px 1fr 200px;
          grid-auto-rows: auto;
          grid-template-areas:
            «head head head»
            «navi cont asid»
            «foot foot foot»
        }
        .footer_container {
          display: grid;
          grid-gap: 1em;
          grid-template-columns: repeat(3, minmax(200px, 1fr));
        }
      }
 
      .content_container {
          display: flex;
          flex-flow: row wrap;
          display: -webkit-flex;
          -webkit-flex-flow: row wrap;
      }
 
      .content_container > div {
         flex: 1 1 300px;
         -webkit-flex: 1 1 300px;
      }
 
      .main_container > div{
        background-color: gray;
        color: #fff;
        border-radius: 5px;
        padding: 20px;
        font-size: 150%;
      }
 
      .content_container > div {
        margin: 1em;
        background-color: green;
        color: #fff;
        border-radius: 5px;
        padding: 20px;
        font-size: 150%;
      }
 
      .footer_container > div {
        background-color: red;
        color: #fff;
        border-radius: 5px;
        padding: 20px;
        font-size: 150%;
      }
 
    </style>
    <title>Webseiten-Aufteilung</title>
  </head>
  <body>
    <div class=»main_container»>
      <div class=»header»>Header</div>
      <div class=»navigation»>Navigation</div>
      <div class=»content»>
 
        Content
        <div class=»content_container»>
           <div>Content 1</div>
           <div>Content 2</div>
           <div>Content 3</div>
           <div>Content 4</div>
           <div>Content 5</div>
        </div>
 
      </div>
      <div class=»aside»>Aside</div>
      <div class=»footer»>
 
        Footer
        <div class=»footer_container»>
            <div>Footer left</div>
            <div>Footer middle</div>
            <div>Footer right</div>
        </div>
 
      </div>
    </div>
  </body>
</html>
Zusätzlich habe ich für den Content noch Flexboxen eingebunden, damit bei grösseren Bildschirmauflösungen die Contentelemente nebeneinander angezeigt werden. Die Footerelemente habe ich in eine Grid-Verschachtelung gepackt und das Ganze mit Media Queries an verschiedenen Bildschirmgrössen angepasst.
Das ist doch ganz einfach oder? Einige werden jetzt die Nase rümpfen, da doch die Maxime gilt, alles im Liquid Design zu gestalten. Ja klar, doch es gibt immer wieder Situationen, wo wir einzelne Bereiche gar nicht auf dem Bildschirm haben wollen oder an einem ganz anderen Ort platzieren wollen. Gerade dafür ist das CSS Grid ausgezeichnet geeignet.
Mein alter Freund die Tabelle ist wieder da! Auch wenn sie jetzt anders heisst. Doch dafür ist sie nun intelligent und flexibel geworden und vor allem standardisiert. Also alles umbauen und das Intranet wieder Mal viel schöner machen. Aber dieses Mal lassen wir die animierten GIFs weg. Es gibt da ja noch die CSS-Animationsfunktionen ;-).
Ich hoffe, Du hast einen kleinen Einblick in CSS Grid bekommen. Vielleicht hast du genau so viel Spass wie ich damit herumzuexperimentieren und bald viele spannende Webprojekte zu realisieren.
Weiterführende Information
Die Definition vom W3C zum CSS Grid
Blogartikel von Rachel Andrew der mich aufhorchen liess
Eine Ausführliche Beschreibung aller Eigenschaften von Chris House
Verständliche Beschreibung der CSS Grid definition
Viele Informationen und Anwendungsbeispiele von CSS Grid einfach erklärt.

Autor: Rico F. Lüthi
Bilder: Copyright by 123RF Stock Photo tycoon751, rclassenlayouts, Mats-Peter Forss