Ein dreispaltiges Layout auf dem Desktop soll auf dem Smartphone nicht gequetscht nebeneinander stehen, sondern sauber untereinander umbrechen. Genau darum ging es im ursprünglichen Arbeitsverlauf zu GeneratePress und GenerateBlocks: Wie muss der Block eingestellt sein, welches Layout ist richtig und soll Display auf Grid stehen?
Die wichtigste Entscheidung lautet: Für gleichmäßige Karten oder Spalten ist CSS Grid meistens die klarste Lösung. Flexbox funktioniert ebenfalls, ist aber stärker auf eine Zeile beziehungsweise einen Fluss ausgerichtet. Grid beschreibt direkt, wie viele Spalten pro Bildschirmgröße vorhanden sein sollen.
Grundstruktur: ein äußerer Grid-Container
Du brauchst einen äußeren Container und darin drei Kind-Container beziehungsweise Karten:
- Grid-Container
- Karte 1
- Karte 2
- Karte 3
Der äußere Container bestimmt die Spalten. Die Karten selbst müssen keine feste Breite erhalten.
Desktop: drei gleich breite Spalten
Als klassisches CSS sähe die Grundregel so aus:
.service-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 30px;
}
repeat(3, ...) erzeugt drei Spalten. 1fr bedeutet, dass jede Spalte denselben Anteil des verfügbaren Platzes erhält.
Warum minmax(0, 1fr) robuster ist als nur 1fr
Bei langen Wörtern, URLs oder breiten Kind-Elementen kann ein Grid-Item sonst versuchen, breiter als seine Spalte zu werden. minmax(0, 1fr) erlaubt der Spalte, wirklich bis auf die verfügbare Breite zu schrumpfen.
Für normale Karten ist das eine sehr robuste Standarddefinition.
Tablet: zwei Spalten
Auf mittleren Bildschirmbreiten sind oft zwei Spalten angenehmer:
@media (max-width: 1024px) {
.service-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
Bei drei Karten entsteht dann eine zweite Zeile mit einer einzelnen Karte. Das ist technisch sauber; gestalterisch kannst du entscheiden, ob die letzte Karte linksbündig bleiben oder eine andere Anordnung erhalten soll.
Smartphone: eine Spalte
@media (max-width: 767px) {
.service-grid {
grid-template-columns: 1fr;
gap: 20px;
}
}
Jetzt stehen alle Karten untereinander und nutzen die verfügbare Breite.
In GenerateBlocks möglichst direkt im Panel einstellen
Wenn deine GenerateBlocks-Version die Grid-Einstellungen direkt im Block-Panel bereitstellt, brauchst du dafür nicht zwingend eigenes CSS. Wähle den äußeren Container beziehungsweise Grid-Block und stelle im Layout-Bereich Display: Grid ein.
Danach definierst du je Gerät beziehungsweise Breakpoint die Spaltenanzahl. Die genaue Benennung kann sich zwischen GenerateBlocks-Versionen unterscheiden, das Prinzip bleibt aber:
- Desktop: 3 Spalten
- Tablet: 2 Spalten
- Mobil: 1 Spalte
Keine festen Pixelbreiten für die Karten
Ein häufiger Fehler ist, dem Grid drei Spalten zu geben und den inneren Karten zusätzlich width: 400px zuzuweisen. Auf einem schmaleren Bildschirm passen diese festen Breiten nicht mehr.
Die Kind-Container sollten normalerweise einfach die Breite ihrer Grid-Zelle übernehmen.
Gap statt Einzel-Margins verwenden
Für den Abstand zwischen Karten ist gap wesentlich angenehmer als individuelle Margins:
gap: 30px;
Das Grid berücksichtigt den Abstand automatisch zwischen den Elementen, ohne außen unnötige zusätzliche Ränder zu erzeugen.
Warum drei mal 33,33 Prozent problematisch sein können
Man kann drei Spalten auch mit Prozentwerten bauen. Wenn du aber 33.33% + 33.33% + 33.33% verwendest und zusätzlich einen Gap hinzufügst, überschreitet die Gesamtsumme schnell die verfügbare Breite.
1fr 1fr 1fr beziehungsweise repeat(3, 1fr) verteilt dagegen den nach Abzug des Gaps verbleibenden Platz.
Wenn du wirklich automatisches Wrapping ohne feste Breakpoints möchtest
CSS Grid kann die Anzahl der Spalten auch anhand einer Mindestbreite automatisch bestimmen:
.service-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
gap: 30px;
}
Der Browser erzeugt so viele Spalten, wie bei mindestens 260 Pixeln Kartenbreite in den Container passen.
Das kann sehr elegant sein, wenn das Layout flexibel reagieren soll. Wenn du dagegen exakt 3/2/1 Spalten für Desktop/Tablet/Mobil möchtest, sind definierte Breakpoints besser kontrollierbar.
Grid oder Flexbox?
Für drei gleichartige Karten ist Grid normalerweise meine erste Wahl. Flexbox ist sinnvoll, wenn die Elemente eher als Reihe gedacht sind und frei umbrechen sollen.
Eine Flex-Variante könnte so aussehen:
.service-row {
display: flex;
flex-wrap: wrap;
gap: 30px;
}
.service-row > * {
flex: 1 1 calc(33.333% - 20px);
}
Für Mobil müssten die Kinder anschließend auf 100 Prozent Basisbreite gesetzt werden.
Warum Grid in diesem Fall leichter zu pflegen ist
Mit Grid definierst du die Spalten am Eltern-Element. Bei Flexbox musst du zusätzlich die Basisbreite der Kinder sauber berechnen. Gerade im GenerateBlocks-Panel ist Grid deshalb bei klassischen Kartenrastern oft verständlicher.
Innenabstände nicht mit Grid-Abständen verwechseln
Zwei Abstandstypen sind zu unterscheiden:
- Gap: Abstand zwischen den Karten.
- Padding: Innenabstand innerhalb einer Karte.
Ein typischer Aufbau könnte sein:
- Grid Gap Desktop: 30 px
- Grid Gap Mobil: 18–20 px
- Karten-Padding Desktop: 30 px
- Karten-Padding Mobil: 20–24 px
Unterschiedlich lange Inhalte
Bei Karten mit verschieden langen Texten sieht ein dreispaltiges Grid oft trotzdem ordentlich aus, weil die Grid-Zellen derselben Reihe standardmäßig gleich hoch werden können. Wenn Buttons immer am unteren Rand stehen sollen, kann der innere Karten-Container zusätzlich als Flexbox aufgebaut werden:
.card {
display: flex;
flex-direction: column;
}
.card .button-wrap {
margin-top: auto;
}
Bilder im Grid
Wenn jede Karte ein Bild besitzt, sollten die sichtbaren Bildflächen möglichst dasselbe Seitenverhältnis erhalten. Sonst bleibt zwar das Grid sauber, aber die Textanfänge springen vertikal.
Eine typische Lösung:
.card img {
width: 100%;
aspect-ratio: 4 / 3;
object-fit: cover;
}
Was passiert bei sehr schmalen Smartphones?
Auch in einer einspaltigen Darstellung können feste Breiten im Inneren Überläufe verursachen. Prüfe deshalb Buttons, Bilder, Tabellen, lange URLs und Elemente mit min-width.
Die Grid-Umstellung allein kann einen inneren 500-Pixel-Block nicht responsiv machen.
Die Browser-Entwicklerwerkzeuge nutzen
Wenn das Grid nicht wie erwartet umbricht, prüfe im Browser:
- welcher Breakpoint aktuell aktiv ist,
- welcher Wert für
grid-template-columnsberechnet wird, - ob eigenes CSS die GenerateBlocks-Werte überschreibt,
- ob ein Kind-Element eine Mindestbreite erzwingt.
Typischer Fehler: Responsive Wert wurde nur für den falschen Breakpoint geändert
GenerateBlocks speichert Werte für unterschiedliche Geräte. Wenn du im Mobilmodus 1 Spalte einstellst, aber anschließend unbemerkt wieder im Desktopmodus speicherst, kann der falsche Wert verändert werden.
Nach dem Speichern solltest du das Frontend daher nicht nur durch Verkleinern des Editors, sondern im echten Browser testen.
Beispiel für eine komplette CSS-Lösung
.service-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 30px;
}
@media (max-width: 1024px) {
.service-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 24px;
}
}
@media (max-width: 767px) {
.service-grid {
grid-template-columns: 1fr;
gap: 20px;
}
}
Fazit
Für ein dreispaltiges GeneratePress-/GenerateBlocks-Raster ist Display: Grid eine sehr gute Grundlage. Definiere die Spalten am äußeren Container und vermeide feste Breiten an den Karten. Ein kontrolliertes 3/2/1-Schema für Desktop, Tablet und Mobil ist leicht verständlich und stabil. Wer ein noch flexibleres Raster möchte, kann alternativ auto-fit mit minmax() verwenden.