Techniken für ein Zeitungs-Layout mit CSS Grid und Trennlinien zwischen Elementen

Avatar of Marco Troost
Marco Troost am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

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.

Zeitungsdesign mit Linientrennern zwischen den Zellen

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.

Spalten- und Zeilendurchgänge in einem CSS Grid-Layout

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.