CSS/Tutorials/Grid/responsive Raster ohne Media Queries

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Im Printdesign und auch bei „CSS-Frameworks“ wie bootstrap wird zuerst ein Gestaltungsraster erstellt, in dem dann Rasterelemente fest platziert werden. Im Webdesign mit seiner Unzahl von verschiedenen Viewportgrößen ist dies zwar auch möglich, oft aber gar nicht nötig.

Mit dem Grid Layout ist es möglich Raster implizit zu erzeugen, die durch den auto-placement-Algorithmus Rasterelemente automatisch auf den verfügbaren Platz verteilen.

In diesem Tutorial soll gezeigt werden, wie Sie mit wenigen CSS-Festlegungen Raster implizit erzeugen, deren Rasterelemente sich ohne den Einsatz von media queries responsiv anordnen.

Grundlagen[Bearbeiten]

Blockelemente wie Überschriften und Absätze nehmen im Standardverhalten der Browser stets die verfügbare Breite ein. Mit der Einführung von CSS wurde es möglich, Positionierungen und Größenangaben auch außerhalb des Elementflusses festzulegen. Dies ermöglichte einerseits ein pixelgenaues Layout, wurde andererseits bei einer Änderung des Viewports zum Boomerang, da sich Inhalte außerhalb des sichtbaren Bereichs oder unter anderen Elementen befanden oder durch overflow: hidden; abgeschnitten wurden. Media queries bieten hier eine Lösung, doch die immer wiederkehrende Frage nach den richtigen Breakpoints zeigt, dass aber auch dies nicht die einfachste Lösung ist.

Grid Layout beginnt wieder von vorne: Der verfügbare Raum wird aufgeteilt, weitere Inhalte werden innerhalb des Rasters in weiteren Reihen dargestellt und wandern so nach unten, wo man sie durch Scrollen erreichen kann.

Auch hier kann die Anzahl der Spalten mit media queries an die verfügbare Viewportbreite angepasst werden, wie schon in Kapitel 4 gezeigt wurde.

Beispiel: responsives Raster mit media queries
body{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 30em) { 
  body{
    grid-template-columns: repeat(3, 1fr);
}

@media (min-width: 50em) { 
  body{
    grid-template-columns: repeat(4, 1fr);
 }
}

Fazit: Mit media queries können Sie ein Raster mit einer festen Spaltenanzahl, deren Breite sich flexibel anpasst erzeugen. Könnte man dies so umdrehen, das man als festen Wert die Breite der Spalten verwendet, die sich entsprechend der Viepwortbreite unterschiedlich oft nebeneinander anordnen? Ja, das geht!

Responsivität ohne Media queries[Bearbeiten]

Im Folgenden soll gezeigt werden, wie Raster mit flexibler Spaltenanzahl angelegt werden, die sich auch ohne Media Queries responsiv an den Viewport anpassen.

auto-fill[Bearbeiten]

Bequemer als die Lösung mit media queries ist es allerdings, mittels des Schlüsselworts auto-fill den Browser die Anzahl der Spalten automatisch festlegen zu lassen:

Beispiel: ein gefülltes Raster ansehen …
body{
  display: grid;
  grid-template-columns: repeat(auto-fill, 20em);
}

article {
  grid-area: 2 / 1 / 4 / 3;
}
Erinnern Sie sich noch an unser erstes Beispiel?
Mit grid-template-columns: auto auto auto; wurden drei Spalten, deren Breite vom Inhalt abhängig war, erstellt.
In diesem Beispiel wurde die repeat()-Funktion verwendet, die nun über den ersten Parameter auto-fill so viele Spalten wie möglich erzeugt.
Der zweite Parameter gibt die Breite der Spalten (20em) vor.
Empfehlung: Öffnen Sie das Beispiel mit Rechtsklick in einem neuen Tab. Der body hat eine schwarze Randlinie.
Was fällt Ihnenn auf?

minmax()[Bearbeiten]

Damit der autoplacement-Algorithmus seine volle Wirkung entfalten kann, muss die Breite der Spalten flexibel sein. Bisher wurde dies bei fester Spaltenanzahl mit der Einheit fr erledigt. Nun sollen die Spalten eine feste Mindestgröße, aber auch keinen überschüssigen Raum in Form eines leeren Rands haben.

Voilà: Die minmax()-Funktion erlaubt es anstelle von festen oder relativen Längenenangaben einen Mindest- und einen Maximalwert anzugeben:

Beispiel: ein gefülltes Raster ansehen …
body{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20em, 1fr));
}

article {
  grid-area: 2 / 1 / 4 / 3;
}

#news {
  grid-column: span 2;
}
In diesem Beispiel wurde die repeat()-Funktion verwendet, die nun über den ersten Parameter auto-fill so viele Spalten wie möglich erzeugt.
Der zweite Parameter besteht aus der minmax()-Funktion, die als Minimum einen Wert von 20em und, damit es z. B. bei 50em keine leeren Räume gibt, einen Maximalwert von 1 fr hat. Dann würden die 50em Breite in 2 Spalten a 25em Breite aufgeteilt.
Empfehlung: Öffne Sie das Beispiel mit Rechtsklick in einem neuen Tab und beobachten Sie.

Durch die Platzierung des article-Elements und des #news-Box über mehrere Spalten bleibt bei einem Dreispaltenlayout ein Rasterfeld frei.

Sie könnten hier eines der weiter hinten gelegenen Elemente mittels einer Angabe von Grid-column, Grid-row, etc. nach vorne bringen. Dies würde bei kleineren Viewports aber nicht nötig und deshalb kontraproduktiv sein. Überlassen Sie dies dem autoplacement-Algorithmus!

grid-auto-flow[Bearbeiten]

Wenn Sie Rasterelemente fest positionieren oder Gridbereiche festlegen, können im Raster wie im oberen Beispiel Lücken entstehen. Diese können mit im Markup nachfolgenden Elementen gefüllt werden.

Der autoplacement-Algorithmus kann durch die grid-auto-flow-Eigenschaft gesteuert werden.

Folgende Angaben sind möglich:

  • row: (Standardwert) Die Spalten werden mit grid-template-columns explizit erzeugt; je nach Menge der Inhalte werden Zellen implizit erzeugt und in weiteren Reihen angefügt.
  • columns: Weitere Inhalte werden in implizit erzeugten Spalten angehängt.
  • dense: optionales Schlüsselwort, dass kleinere Zellen in vorher entstandene Lücken platziert, sodass es zu einem gefüllten Raster kommt.
    Ohne dieses Schlüsselwort kommt der sparse-Modus zum Zug, der Elemente, wenn kein Platz vorhanden ist, in die nächste Reihe schiebt.
  • row dense:
  • column dense:
Beispiel: ein gefülltes Raster ansehen …
body{
  display: grid;
  grid-template-columns: auto auto auto;
  grid-auto-flow: dense;			
}

article {
  grid-area: 2 / 1 / 4 / 3;
}

#news {
  grid-column: span 2;
}
Durch das Schlüsselwort dense wird der Algorithmus so geändert, dass die vorher leeren Bereiche durch im Markup hinten stehende Elemente aufgefüllt werden.
Beachten Sie, dass Sie das Schlüsselwort dense nur verwenden sollten, wenn es innerhalb des Grids keine fokussierbaren Elemente gibt, da eine Umordnung immer zu unlogischer Tab-Reihenfolge führt.

Anwendungsbeispiele[Bearbeiten]

Ein solch flexibles Raster eignet sich vor allem für gleichförmige Elemente, bei denen unter Umständen die Reihenfolge verändert werden kann, ohne dass es zu Irritationen wie einem weit oben stehenden Seitenfooter kommt.

Responsives Grid[Bearbeiten]

Die 30 Artikel der Erklärung der Menschenrechte sollen sich flexibel über den verfügbaren Viewport verteilen. Dabei soll keine Spaltenanzahl vorgegeben werden:

Beispiel: flexibles Grid Layout ohne media queries ansehen …
main {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(20em, 1fr));
  color: black;
  font: 1em/1.3 Cambria, serif;
}

main > section {
  padding: 1rem;
  background: hsl(220, 80%, 90%);
}
Für die 30 section-Blöcke werden mit grid-template-columns Spalten erzeugt. Dabei werden mit der repeat()-Funktion über das autofill-Schlüsselwort so oft wie nötig Spalten mit einer durch die minmax(20em, 1fr)-Funktion ermittelten Breite von mindestens 20em Breite und maximal einem Bruchteil erzeugt.

Bildergalerie[Bearbeiten]

Der auto-placement-Algorithmus eignet sich besonders für Listen und Galerien, bei denen die genaue Reihenfolge unwichtig ist. In dieser Bildergalerie werden die unterschiedlich großen Bilder auf den verfügbaren Platz verteilt. Durch grid-auto-flow: dense; wird das Raster lückenlos gefüllt.

Beispiel: Bildergalerie ansehen …
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(133px, 1fr));
  grid-gap: 10px;
  grid-auto-flow: dense;
}

.gallery figure.landscape {
  grid-column-end: span 2;
}

.gallery figure.panorama {
  grid-column-end: span 3;
}
In diesem Beispiel findet das entscheidende CSS nur im Elternelement statt:
  • display: grid; macht das div mit der id gallery zum Grid Container
  • grid-template-columns: repeat(auto-fill, minmax(133px, 1fr)); erzeugt Spalten, die mindestens 133px breit sind. Wenn die Gesamtbreite größer als ein Vielfaches der Mindestbreite ist, sodass normalerweise rechts ein Rand bliebe, verteilen die Spalten sich jedoch gleichmäßig über den verfügbaren Platz.
  • grid-auto-flow: dense; füllt das Raster lückenlos mit weiter hinten im Markup stehenden Elementen auf.


Neben dem Portrait-Modus, der eine Zelle umfasst, gibt es noch ein landscape-Format, das sich durch grid-column-end: span 2; über zwei, sowie ein panorama-Format, das sich über 3 Zellen erstreckt.
.gallery figure {
  border: 1px solid #ccc;
  position: relative;	
  margin: 0;
  counter-increment: posMarkup;	
}

.gallery figure img {
  display: block;
  object-fit: cover;
  width: 100%;
  height: 100%;
}

.gallery figure::after {
  content: counter(posMarkup, decimal);
  position: absolute;
  bottom: 0;
  color: red;
}
Die Bilder werden in ein figure-Element verpackt, dass den browsereigenen Abstand durch margin: 0; normalisiert.

Die Bilder werden durch object-fit: cover; passend skaliert, ohne das Seitenverhältnis zu ändern.
Zur besseren Übersicht wie durch die Verwendung von dense kleinere Zellen in vorher entstandene Lücken platziert werden, wird in einem absolut positioniertem Pseudoelement die Reihenfolge jedes Bildes gekennzeichnet. Dabei werden zur Bildnummerierung CSS-Counter verwendet:

  • counter-increment erzeugt eine Variable, die dann im Pseudoelement ::after über content: counter(posMarkup, decimal); wieder ausgegeben wird.

Masonry Tiles[Bearbeiten]

Eine moderne Variante einer Bildergalerie ist das Masonry Layout, indem Bilder sich innerhalb von flexiblen Spalten passend anordnen. Bis jetzt musste der Platzbedarf mit JavaScript verteilt werden - mit Grid Layout ist dies auch nur mit CSS möglich.

Der Webdesigner Kseso stellt in einem CodePen ein solches Layout vor:

Weblinks[Bearbeiten]