Vor kurzem musste ich ein zeitungsähnliches Design erstellen, das mehrere Zeilen- und Spaltendurchgänge mit Trennlinien dazwischen aufwies. Werfen Sie einen Blick auf die Mockup-Grafik hier und sehen Sie, ob sie Ihnen Schweißperlen auf die Stirn treibt. Wenn Sie wie ich sind, sind Sie schon eine Weile dabei und wissen, wie schwierig das mit alten Layout-Techniken gewesen wäre.

Das Projekt hatte ein paar Anforderungen
- Die Umrisse des Grids anzeigen
- Spalten können breiter oder länger sein als andere
- Zwischen den verschiedenen Blöcken müssen Trennlinien angezeigt werden
CSS Grid: Ein altes Layout lehrt neue Tricks
Zeitungs-Layouts können Kopfschmerzen bereiten, da alltägliches CSS eindimensional ist, was bedeutet, dass sich Elemente entweder auf einer horizontalen oder vertikalen Achse bewegen. Selbst modernes Flexbox-Layout ist immer noch unidirektional.
Für ein solches Layout wünschten wir uns fast die Eigenschaften, die gute alte HTML-Tabellen einst boten: Dinge wie Zeilen- und Spaltendurchgänge, um Zellen in alle Richtungen zu dehnen. Wir hätten auch die Vorteile des modernen CSS mit all der Reaktionsfähigkeit und den flexiblen Boxen, die sich ausdehnen können, um den verfügbaren Platz zu füllen.
CSS Grid kombiniert das Beste aus Tabellen mit dem Besten aus flexiblen Boxen. Tatsächlich ist Grid noch besser, da es die Eigenschaft grid-gap für die Erstellung von Abständen zwischen den Zellen bietet und dabei den verfügbaren Platz berücksichtigt. So mächtig dies auch sein mag, wie können wir Trennlinien genau in der Mitte dieser Abstände erstellen?
Betrachten wir drei Techniken, um dies zu erreichen.
Was wir erstellen werden
Zuerst erstellen wir eine vereinfachte Version des Zeitungsdesigns, die die Kernpunkte der drei verschiedenen Techniken veranschaulicht, die wir behandeln werden. Ein täuschend einfaches Design, könnte man sagen.

Technik 1: Die Schein-Spalte
Diese Lösung erstellt „Schein“-Spalten, die es uns ermöglichen, vertikale Linien zu zeichnen und dann ein Grid darüber zu legen. Horizontale Trennlinien werden bei Bedarf gezeichnet. Die „Schein“-Spalten werden durch die Verwendung von Pseudo-Selektoren im Grid-Container erstellt.
<div class="frontpage">
<div class="fp-cell fp-cell--1">
<div class="fp-item">1</div>
</div>
<div class="fp-cell fp-cell--2">
<div class="fp-item">2</div>
</div>
<div class="fp-cell fp-cell--3 fp-cell--border-top">
<div class="fp-item">3</div>
</div>
<div class="fp-cell fp-cell--4 fp-cell--border-top">
<div class="fp-item">4</div>
</div>
</div>
Sehen Sie den Pen
Zeitungsdesign, „Schein-Spalten“-Technik von Marco Troost (@marco-troost)
auf CodePen.
Einrichtung der Linien zwischen den Spalten
Erstellen wir einen Drei-Spalten-Container mit display: grid und Pseudo-Selektoren (:before und :after), um zwei Spalten zu erstellen, die 100 % der Höhe des Containers einnehmen.
.frontpage {
position: relative;
display: grid;
/* Three columns */
grid-template-columns: 1fr 1fr 1fr;
grid-column-gap: 32px;
border: 1px solid transparent;
border-top: 1px solid #DADCE0;
border-bottom: 1px solid #DADCE0;
overflow: hidden;
}
/* Two faux columns */
.frontpage:before,
.frontpage:after {
position: absolute;
top: 0;
height: 100%;
content: '';
width: calc(33.3% - 4px);
}
.frontpage:before {
left: 0;
border-right: 1px solid #DADCE0;
}
.frontpage:after {
right: 0;
border-left: 1px solid #DADCE0;
}
Hinweis: 33 % des Containers berücksichtigen nicht die Breite des Abstands, daher müssen Sie dies entsprechend kompensieren.
Dies wird berechnet als
33% minus (gutter-width divided by (amount of gutters times amount of gutters)) divided by amount of gutters)
Oder mit tatsächlichen Zahlen
33% - (32 / (2* 2)) / 2 = 4
Wir könnten stattdessen einen Pseudo-Selektor verwenden
.frontpage {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-column-gap: 32px;
border: 1px solid transparent;
border-top: 1px solid #DADCE0;
border-bottom: 1px solid #DADCE0;
overflow: hidden;
}
.frontpage:before {
box-sizing: border-box;
position: absolute;
top: 0;
height: 100%;
content: '';
left: calc(33.3% - 5.3px);
width: calc(33.3% + 10.7px);
border-left: 1px solid #DADCE0;
border-right: 1px solid #DADCE0;
}
Sehen Sie den Pen
Newsgrid-Layout „Schein-Spalten“ (nur mit :before) von Marco Troost (@marco-troost)
auf CodePen.
Hinweis: Bei Verwendung von nur einem Pseudo-Selektor ist eine andere Berechnung erforderlich: Eine für die Positionierung und eine für die Breite.
Die Breite wird berechnet als
33% plus (amount of gutters times gutter-width) / (amount of gutters times amount of columns)
Wieder mit tatsächlichen Zahlen
33% + (2 * 32) / (2 * 3) = 10.7
Die Position wird berechnet als
33% minus (amount of gutters times gutter-width) / (amount of gutters times amount of columns) divided by 2)
Das Grid erstellen
Das Design besteht aus vier Inhaltsblöcken. Wir platzieren sie im Container und geben ihnen eine Modifikatorklasse für zukünftige Referenz, während wir sicherstellen, dass ihr z-index höher ist als der der Pseudo-Selektoren des Grids.
<div class="frontpage">
<div class="fp-cell fp-cell--1"></div>
<div class="fp-cell fp-cell--2"></div>
<div class="fp-cell fp-cell--3"></div>
<div class="fp-cell fp-cell--4"></div>
</div>
Lassen Sie uns nun die Hintergrundfarbe für die Zellen (.fp-cell) auf Weiß setzen. Auf diese Weise werden die vertikalen Linien nicht durchscheinen. Wir können auch den vertikalen Abstand für die Zelle auf 16px setzen, um die Hälfte des Abstands zu erreichen.
Der erste und zweite Inhaltsblock sollten ihre eigenen einzigartigen Durchgänge erhalten, wie im Design gezeigt. Der erste Block reicht nach unten und der zweite Block erstreckt sich über die zweite und dritte Spalte.
.fp-cell {
position: relative;
z-index: 2;
padding: 16px 0;
background-color: #fff;
}
/* Span all the way down! */
.fp-cell--1 {
grid-row: 1 / span 2;
}
/* Span the second and third columns */
.fp-cell--2 {
grid-column: 2 / span 2;
}
Vertikale Linientrenner
Wenn Sie sich das Design ansehen, benötigen nur die letzten beiden Zellen einen horizontalen Rand. Wir können ihnen eine hübsche Modifikatorklasse geben.
<div class="frontpage">
<div class="fp-cell fp-cell--1"></div>
<div class="fp-cell fp-cell--2"></div>
<div class="fp-cell fp-cell--3 fp-cell--border-top"></div>
<div class="fp-cell fp-cell--4 fp-cell--border-top"></div>
</div>
.fp-cell--border-top:before {
content: '';
position: absolute;
top: 0;
left: -16px;
right: -16px;
border-top: 1px solid #DADCE0;
}
Die negativen Abstände betragen die Hälfte der Abstandbreite.
Technik #2: Verwendung von Hintergrundfarbe
Eine andere Möglichkeit, die Trennlinien zu erstellen, ist die Nutzung der Eigenschaft grid-gap. Diese Lösung erzeugt nicht unbedingt einen „echten“ Abstand zwischen den Zellen, sondern lässt stattdessen etwas freien Platz, wo der background-color des Grids durchscheinen kann. Die Abstandbreite wird durch Polsterung innerhalb der Grid-Zellen verwaltet.
<div class="container">
<div class="frontpage">
<div class="fp-cell fp-cell--1">
<div class="fp-item">1</div>
</div>
<div class="fp-cell fp-cell--2">
<div class="fp-item">2</div>
</div>
<div class="fp-cell fp-cell--3">
<div class="fp-item">3</div>
</div>
<div class="fp-cell fp-cell--4">
<div class="fp-item">4</div>
</div>
</div>
</div>
.container {
overflow-x: hidden;
border-top: 1px solid #DADCE0;
border-bottom: 1px solid #DADCE0;
}
.frontpage {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1px;
margin: 0 -16px;
background-color: #DADCE0;
}
.fp-cell {
background-color: #fff;
padding: 16px;
}
.fp-cell--1 {
grid-row: 1 / span 2;
}
.fp-cell--2 {
grid-column: 2 / span 2;
}
.fp-cell--3 {
grid-column: 2;
}
.fp-item {
background-color: #efefef;
display: flex;
align-items: center;
justify-content: center;
min-height: 200px;
height: 100%;
}
Sehen Sie den Pen
Zeitungsdesign, Hintergrundfarbe-Technik von Marco Troost (@marco-troost)
auf CodePen.
Da alle Zellen einen zusätzlichen horizontalen Abstand von 16 Pixeln haben, muss das Grid um denselben Betrag versetzt werden. Ein Wrapper-Container kümmert sich um den Überlauf.
<div class="container">
<div class="frontpage">
<!-- ... -->
</div>
</div>
.container {
border-top: 1px solid #DADCE0;
border-bottom: 1px solid #DADCE0;
overflow-x: hidden;
}
.frontpage {
position: relative;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1px;
background-color: #DADCE0;
margin: 0 -16px;
}
Technik #3: Erstellung eines Zellrandes
Diese Lösung fügt jeder Zelle einen rechten und unteren Rand hinzu. Wie im letzten Beispiel wird der grid-gap durch Hinzufügen von Polsterung zum Zellinhalt nachgeahmt. Das bedeutet, dass auch dies in einem zusätzlichen Container verpackt werden muss.
<div class="container">
<div class="frontpage">
<div class="fp-cell fp-cell--1">
<div class="fp-item">1</div>
</div>
<div class="fp-cell fp-cell--2">
<div class="fp-item">2</div>
</div>
<div class="fp-cell fp-cell--3">
<div class="fp-item">3</div>
</div>
<div class="fp-cell fp-cell--4">
<div class="fp-item">4</div>
</div>
</div>
</div>
.container {
border-top: 1px solid #DADCE0;
overflow-x: hidden;
}
.frontpage {
margin: 0 -17px 0 -16px;
position: relative;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.fp-cell {
padding: 16px;
background-color: #fff;
border-right: 1px solid #DADCE0;
border-bottom: 1px solid #DADCE0;
}
.fp-cell--1 {
grid-row: 1 / span 2;
}
.fp-cell--2 {
grid-column: 2 / span 2;
}
.fp-cell--3 {
grid-column: 2;
}
.fp-item {
background-color: #efefef;
display: flex;
align-items: center;
justify-content: center;
min-height: 200px;
height: 100%;
}
Sehen Sie den Pen
Zeitungsdesign, „Zellrand“-Technik von Marco Troost (@marco-troost)
auf CodePen.
Wie erwähnt, erhält jede Zelle einen Rand rechts und unten. Der Haupttrick hier ist die Verwendung des (asymmetrischen) negativen Abstands auf dem Grid. Dies ist notwendig, um den rechten Rand der Zelle zu kompensieren.
.frontpage {
margin: 0 -17px 0 -16px;
position: relative;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
Fazit
Ockhams Rasiermesser besagt, dass die einfachste Lösung gewinnt. In unserem Fall ist das Technik Nummer zwei. Aber dann haben die anderen Lösungen viel Wert und könnten nützlich sein, wenn zum Beispiel kein Zugriff auf das DOM möglich ist.
All diese Techniken werden funktionieren. Die Wahl der richtigen hängt von Ihrem Anwendungsfall ab. Die erste Technik verwendet die eigentliche Eigenschaft grid-gap, um die Abstände zu erzeugen, aber die anderen sind auf den ersten Blick vielleicht leichter zu verstehen ... und vielleicht auch einfacher zu warten.
Ich habe mich buchstäblich bis zu der Minute, bevor Thunderbird mich über Ihren Beitrag benachrichtigte, mit diesem Thema herumgeschlagen.
Ich habe versucht, das Problem mit %-abgestimmten Hintergrundbild-Gradientenstopps zu lösen, aber mein Design ist einfacher (nur Spalten), also lese ich Ihren Artikel mit Vergnügen.
Danke!
„Diese Lösung erzeugt nicht unbedingt einen „echten“ Abstand zwischen den Zellen…“
Sollte das nicht „Rand“ statt „Abstand“ heißen?
Hallo Gust, „diese Lösung“ in Technik #2 bezieht sich darauf, dass grid-gap nicht als „Abstandshalter“ (zwischen den Spalten) verwendet wird.
Es wird grid-gap verwendet, um einen 1px breiten Rand nachzuahmen, so dass diese Lösung die grid-gap-Eigenschaft nicht in ihrer ursprünglichen Form verwendet.
Technik 2 scheint die sauberste zu sein. Vielen Dank für das Teilen dieser Tipps!
Zwei Anmerkungen dazu
Erstens sagt der Artikel, dass Grid besser als Flexbox ist, weil es die Eigenschaft
grid-gapbietet. Beachten Sie, dassgrid-gapingapumbenannt wurde, um auch für Flexbox und Multi-Column-Layout zu gelten. (Bisher unterstützt nur Firefox dies im Flexbox-Layout.)Zweitens gibt es bereits einige Diskussionen im Issue Tracker der CSS Working Group, um eine ordnungsgemäße Möglichkeit zur Gestaltung der Abstände zwischen den Zellen einzuführen, siehe https://github.com/w3c/csswg-drafts/issues/2748.
Ich habe es auf Reddit gesehen und meine eigene Version gemacht. Sehr coole Herangehensweise.
https://codepen.io/MichaelAndreuzza/pen/XWWLQyb?editors=1000
Warum nicht Box-Schatten statt Ränder? Vielleicht gibt es einen bestimmten Grund, den ich nicht sehe, aber Box-Schatten scheint einfacher zu sein, Sie können die gleiche Regel für alle Blöcke verwenden und Schatten werden übereinander gezeichnet, sie nehmen keinen zusätzlichen Platz ein oder zeigen eine doppelte Linie.