Nach Teil 1 und Teil 2 bin ich mit einem dritten Artikel zurück, um weitere schicke Formen zu erkunden. Wie in den vorherigen Artikeln werden wir CSS Grid mit Clipping und Maskierung kombinieren, um schicke Layouts für Bildergalerien zu erstellen.
Sollte ich die vorherigen Artikel zuerst lesen?
Das ist nicht zwingend erforderlich, aber sehr empfehlenswert, um möglichst viele Tricks abzudecken. Sie können sie auch in beliebiger Reihenfolge lesen, aber eine chronologische Verfolgung ist eine gute Idee, um zu sehen, wie wir hierher gekommen sind.
Genug geredet, springen wir direkt zu unserem ersten Beispiel.
Die gestanzte Fotogalerie
Bevor wir uns mit dem CSS beschäftigen, werfen wir einen Blick auf den Markup
<div class="gallery">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
<img src="..." alt="...">
</div>
Nichts als ein paar <img>-Tags in einem div-Wrapper, richtig? Denken Sie daran, die größte Herausforderung für diese Serie besteht darin, mit der geringstmöglichen HTML-Menge zu arbeiten. Alle Beispiele, die wir in dieser Serie gesehen haben, verwenden exakt den gleichen HTML-Markup. Keine zusätzlichen Divs, Wrapper und dergleichen. Alles, was wir brauchen, sind Bilder, die in einem Wrapper-Element enthalten sind.
Werfen wir nun einen Blick auf das CSS
.gallery {
--g: 6px; /* the gap */
display: grid;
width: 450px; /* the size */
aspect-ratio: 1; /* equal height */
grid: auto-flow 1fr / repeat(3, 1fr);
gap: var(--g);
}
.gallery img:nth-child(2) {
grid-area: 1 / 2 / span 2 / span 2;
}
.gallery img:nth-child(3) {
grid-area: 2 / 1 / span 2 / span 2;
}
Grundsätzlich handelt es sich um ein quadratisches Raster mit drei gleichen Spalten. Von dort aus werden lediglich das zweite und dritte Bild explizit im Raster platziert, sodass sich das erste und letzte Bild automatisch um sie herum anordnen können.
Dieses automatische Verhalten ist eine leistungsstarke Funktion von CSS Grid namens „Auto-Placement“. Dasselbe gilt für die Anzahl der Zeilen – keine davon ist explizit definiert. Der Browser erstellt sie „implizit“ basierend auf der Platzierung der Elemente. Ich habe einen sehr detaillierten Artikel, der beide Konzepte behandelt.
Sie fragen sich vielleicht, was es mit diesen grid und grid-area Eigenschaftswerten auf sich hat. Sie sehen seltsam aus und sind schwer zu verstehen! Das liegt daran, dass ich die CSS grid Kurzschreibweise gewählt habe, die super nützlich ist, aber eine unansehnliche Anzahl von Werten aus ihren einzelnen Eigenschaften akzeptiert. Sie können sie alle im Almanach sehen.
Aber was Sie wirklich wissen müssen, ist das
grid: auto-flow 1fr / repeat(3, 1fr);
…entspricht dem
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 1fr;

Gleiches gilt für die grid-area Eigenschaft. Wenn wir DevTools öffnen und unsere Deklaration inspizieren: grid-area: 1/2/span 2/span 2; erhalten wir Folgendes
grid-area: 1 / 2 / span 2 / span 2;
…das ist dasselbe, als würde man all dies ausschreiben
grid-row-start: 1; /* 1st row */
grid-column-start: 2; /* 2nd column */
grid-row-end: span 2; /* take 2 rows */
grid-column-end: span 2; /* take 2 columns */
Gleiches Spiel für die andere grid-area Deklaration. Wenn wir alles zusammenfügen, erhalten wir Folgendes

Ja, das zweite und dritte Bild überlappen sich in der Mitte. Das ist kein Fehler! Ich habe sie absichtlich übereinander gelegt, damit ich eine clip-path anwenden kann, um einen Teil von jedem auszuschneiden und das Endergebnis zu erzielen.

Wie machen wir das? Wir können die untere linke Ecke des zweiten Bildes (img:nth-child(2)) mit der CSS clip-path Eigenschaft abschneiden.
clip-path: polygon(0 0, 100% 0, 100% 100%, calc(50% + var(--g) / 4) 100%, 0 calc(50% - var(--g) / 4))
Und die obere rechte Ecke des dritten.
clip-path: polygon(0 0, calc(50% - var(--g) / 4) 0, 100% calc(50% + var(--g) / 4), 100% 100%, 0 100%);
Ich weiß, ich weiß. Das sind viele Zahlen und dergleichen. Ich habe einen Artikel, der die Technik detailliert beschreibt.
Das war's, wir haben unser erstes Raster aus Bildern! Ich habe einen graustufigen filter auf dem <img>-Selektor hinzugefügt, um diesen schönen kleinen Hover-Effekt zu erzielen.
Die geteilte Bildenthüllung
Versuchen wir etwas anderes. Wir können das Gelernte über das Abschneiden von Bildecken mit einem schönen Effekt kombinieren, um das vollständige Bild beim Hovern anzuzeigen.
Die Rasterkonfiguration hierfür ist weniger intensiv als bei der letzten, da wir nur zwei überlappende Bilder benötigen.
.gallery {
display: grid;
}
.gallery > img {
grid-area: 1 / 1;
width: 350px; /* the size */
aspect-ratio: 1; /* equal height */
}
Zwei gleich große Bilder sind übereinander gestapelt (dank grid-area: 1 / 1).
Der Hover-Effekt beruht auf der Animation von clip-path. Wir werden den Code des ersten Bildes zerlegen, um zu sehen, wie es funktioniert, und dann dasselbe in das zweite Bild mit aktualisierten Werten einfügen. Beachten Sie jedoch, dass wir drei verschiedene Zustände haben.
- Wenn keine Bilder gehovert werden, wird die Hälfte jedes Bildes enthüllt.
- Wenn wir über das erste Bild hovern, wird es vollständiger enthüllt, behält aber eine kleine Ecke.
- Wenn wir über das zweite Bild hovern, ist vom ersten nur noch ein kleiner Dreieck zu sehen.

In jedem Fall haben wir eine dreieckige Form. Das bedeutet, wir benötigen ein dreipunktiges Polygon für den clip-path Wert.
Was? Der zweite Zustand ist kein Dreieck, sondern eher ein Quadrat mit einer abgeschnittenen Ecke.
Das stimmt, aber wenn wir genau hinsehen, können wir ein „verstecktes“ Dreieck erkennen. Fügen wir den Bildern einen box-shadow hinzu.
Aha! Haben Sie es bemerkt?

Welche Magie ist das? Es ist eine wenig bekannte Tatsache, dass clip-path Werte außerhalb des Bereichs 0%-100% akzeptiert, was uns ermöglicht, „überlaufende“ Formen zu erstellen. (Ja, das habe ich gerade erfunden. Gerne geschehen.) Auf diese Weise müssen wir nur mit drei Punkten arbeiten, anstatt mit den fünf, die es für dieselbe Form aus den sichtbaren Teilen benötigen würde. Optimiertes CSS also!
Dies ist der Code, nachdem wir die Polygonwerte in die clip-path Eigenschaft eingefügt haben.
.gallery > img:first-child {
clip-path: polygon(0 0, calc(100% + var(--_p)) 0 , 0 calc(100% + var(--_p)))
}
.gallery > img:last-child {
clip-path: polygon(100% 100%, 100% calc(0% - var(--_p)), calc(0% - var(--_p)) 100%)
}
Beachten Sie die Variable --_p. Ich verwende sie, um den Code ein wenig zu optimieren, wenn wir den Hover-Übergang hinzufügen. Anstatt den gesamten clip-path zu aktualisieren, aktualisieren wir nur diese Variable, um die Bewegung zu erhalten. Hier ist ein Video, um zu sehen, wie sich die Punkte zwischen den Zuständen bewegen sollten.
Wir können eine transition auf den <img>-Selektor legen und dann die --_p Variable bei den Zuständen aktualisieren, um den endgültigen Effekt zu erzielen.
.gallery {
--g: 8px; /* the gap */
}
.gallery > img {
/* etc. */
--_p: calc(-1 * var(--g));
transition: .4s .1s;
}
.gallery:hover > img:last-child,
.gallery:hover > img:first-child:hover{
--_p: calc(50% - var(--g));
}
.gallery:hover > img:first-child,
.gallery:hover > img:first-child:hover + img {
--_p: calc(-50% - var(--g));
}
Wenn wir den Abstand (definiert als --g im Code) zwischen den Bildern nicht berücksichtigen, sind die drei Werte von --_p 0%, 50% und -50%. Jeder davon definiert einen der zuvor erklärten Zustände.
Die Tortenbildenthüllung
Erhöhen wir den Schwierigkeitsgrad gegenüber dem letzten und versuchen wir denselben Trick, aber mit vier Bildern statt zwei.
Cool, oder? Jedes Bild ist ein Viertel eines Kreises, und beim Hovern gibt es eine Animation, die ein Bild in einen vollen Kreis verwandelt, der die restlichen Bilder abdeckt. Der Effekt mag unmöglich erscheinen, da es keine Möglichkeit gibt, Punkte zu drehen und sie zu vollen Kreisen zu transformieren. Tatsächlich drehen wir überhaupt keine Punkte. Es ist eine Illusion!
Für dieses Beispiel konzentriere ich mich nur auf die clip-path Animation, da die Rasterkonfiguration die gleiche wie im vorherigen Beispiel ist: vier gleich große Bilder, die übereinander gestapelt sind.
Und ein Video ist eine langweilige und lange Erklärung wert.
Die clip-path besteht aus sieben Punkten, von denen drei fest positioniert sind und die anderen sich wie im Video gezeigt bewegen. Der Effekt wirkt bei langsamer Wiedergabe weniger cool, aber wir können sehen, wie die clip-path sich zwischen Formen verwandelt.
Der Effekt ist etwas besser, wenn wir border-radius hinzufügen und ihn schneller machen.
Und wenn wir ihn noch schneller machen, wie im Originalbeispiel, erhalten wir die perfekte Illusion, dass sich ein Viertelkreis in einen Vollkreis verwandelt. Hier ist der Polygonwert für unsere clip-path auf dem ersten Bild in der Sequenz.
.gallery > img:nth-child(1) {
clip-path: polygon(50% 50%, calc(50% * var(--_i, 0)) calc(120% * var(--_i, 0)), 0 calc(100% * var(--_i, 0)),0 0, 100% 0, 100% calc(100% * var(--_i, 0)), calc(100% - 50% * var(--_i, 0)) calc(120% * var(--_i, 0)));
}
.gallery > img:hover {
--_i: 1;
}
Wie üblich verwende ich eine Variable, um den Code zu optimieren. Die Variable wechselt zwischen 0 und 1, um das Polygon zu aktualisieren.
Dasselbe gilt für die anderen Bilder, aber mit einer anderen clip-path-Konfiguration. Ich weiß, dass die Werte schwer zu entschlüsseln sein mögen, aber Sie können jederzeit Online-Tools wie Clippy verwenden, um die Werte zu visualisieren.
Das Bildermosaik
Sie kennen Mosaike, richtig? Das ist ein Kunststil, bei dem dekorative Designs aus kleineren einzelnen Stücken wie bunten Steinen erstellt werden. Es kann aber auch ein zusammengesetztes Bild aus anderen kleineren Bildern sein.
Und, Sie haben es erraten: Wir können so etwas in CSS machen!
Stellen wir uns zuerst vor, wie die Dinge aussehen würden, wenn clip-path nicht im Spiel wäre und wir nur fünf überlappende Bilder hätten.
Ich schummele in diesem Video ein wenig, da ich den Code inspiziere, um den Bereich jedes Bildes zu identifizieren, aber das ist es, was Sie im Kopf behalten müssen. Versuchen Sie für jedes Bild, den fehlenden Teil zu ergänzen, um das vollständige Rechteck zu sehen, und damit können wir die Position und Größe jedes einzelnen bestimmen.
Wir müssen herausfinden, wie viele Spalten und Zeilen wir für das Raster benötigen.
- Wir haben zwei große Bilder nebeneinander, die jeweils die halbe Rasterbreite und die volle Rasterhöhe ausfüllen. Das bedeutet, wir brauchen wahrscheinlich zwei Spalten (eine für beide Bilder) und eine Zeile (für die volle Höhe des Rasters).
- Wir haben das Bild in der Mitte, das die beiden anderen Bilder überlappt. Das bedeutet, wir brauchen eigentlich vier Spalten statt zwei, obwohl wir immer noch nur die eine Zeile benötigen.
- Die letzten beiden Bilder füllen jeweils die halbe Rasterbreite aus, genau wie die ersten beiden Bilder. Aber sie sind nur halb so hoch wie das Raster. Wir können die bereits vorhandenen Spalten verwenden, aber wir benötigen zwei Zeilen statt einer, um diese Bilder mit halber Rasterhöhe zu berücksichtigen.

Ich möchte nicht, dass Sie denken, dass die Art und Weise, wie ich dies aufgeteilt habe, die *einzige* Möglichkeit ist, es zu tun. Dies ist lediglich, wie ich es verstanden habe. Ich bin sicher, es gibt andere Konfigurationen, um dasselbe Layout zu erzielen!
Nehmen wir diese Informationen und definieren unser Raster, dann platzieren wir die Bilder darauf.
.gallery {
display: grid;
grid: repeat(2, 1fr) / repeat(4, 1fr);
aspect-ratio: 2;
}
.gallery img:nth-child(1) {
grid-area: 1 / 1 / span 2 / span 2;
}
.gallery img:nth-child(2) {
grid-area: 1 / 2 / span 2 / span 2;
}
.gallery img:nth-child(3) {
grid-area: span 2 / span 2 / -1 / -1;
}
.gallery img:nth-child(4) {
grid-area: 2 / 1 / span 1 / span 2;
}
.gallery img:nth-child(5) {
grid-area: span 1 / span 2 / -1 / -1;
}
Ich denke, Sie haben das Prinzip verstanden, da wir nun ein paar Beispiele mit demselben Ansatz gesehen haben. Wir definieren ein Raster und platzieren die Bilder explizit darauf, indem wir grid-area verwenden, damit sich die Bilder überlappen.
Okay, aber das
aspect-ratioist diesmal anders.
Das stimmt! Wenn wir zur Begründung zurückkehren, haben wir die ersten beiden quadratischen Bilder nebeneinander, die gleich groß sind. Das bedeutet, dass die Breite des Rasters gleich dem Doppelten seiner Höhe sein muss. Daher aspect-ratio: 2.
Jetzt ist es Zeit für die clip-path Werte. Wir haben vier Dreiecke und eine Raute.

Auch hier verwende ich Clippy für all diese mathematischen Dinge. Aber ehrlich gesagt, ich kann viele einfache Formen von Hand schreiben, da ich mehrere Jahre lang eng mit clip-path gearbeitet habe, und ich bin sicher, Sie können das mit Übung auch!
Das komplexe Bildermosaik
Erhöhen wir den Schwierigkeitsgrad und versuchen wir ein weiteres Mosaik, diesmal mit weniger Symmetrie und komplexeren Formen.
Keine Sorge, Sie werden sehen, dass es das gleiche Konzept wie das gerade erstellte ist! Stellen wir uns wieder jedes Bild als Rechteck vor und definieren dann das Raster anhand dessen, was wir sehen.
Wir beginnen mit zwei Bildern.

Sie sind beide Quadrate. Das erste Bild ist halb so groß wie das zweite. Das erste Bild nimmt weniger als die Hälfte der Rasterbreite ein, während das zweite Bild mehr als die Hälfte einnimmt, was uns insgesamt zwei Spalten mit unterschiedlicher Größe ergibt (die erste ist halb so groß wie die zweite). Das erste Bild ist halb so hoch, also gehen wir automatisch davon aus, dass wir auch zwei Zeilen benötigen.
Fügen wir ein weiteres Bild zum Layout hinzu.

Dieses macht die Dinge etwas komplizierter! Wir müssen einige Linien zeichnen, um zu identifizieren, wie die Rasterkonfiguration aktualisiert werden soll.

Wir wechseln von einem 2×2-Raster zu vier Spalten und drei Zeilen. Ziemlich asymmetrisch, oder? Bevor wir versuchen, die vollständige Größe zu ermitteln, sehen wir, ob dasselbe Layout bestehen bleibt, wenn wir die anderen Bilder hinzufügen.

Es sieht so aus, als ob wir immer noch mehr Zeilen und Spalten benötigen, damit alles seinen Platz findet. Basierend auf den Linien auf diesem Bild werden wir insgesamt fünf Spalten und vier Zeilen haben.
Die Logik ist einfach, auch wenn das Layout komplex ist, oder? Wir fügen die Bilder einzeln hinzu, um die richtige Konfiguration zu finden, die alles passt. Jetzt müssen wir die Größe jeder Spalte und Zeile bestimmen.
Wenn wir sagen, dass die kleinste Zeile/Spalte gleich einem Bruchteil des Rasters ist (1fr), erhalten wir
grid-template-columns: 1fr 1fr 2fr 3fr 5fr;
…für die Spalten, und
grid-template-rows: 3fr 1fr 2fr 2fr;
…für die Zeilen. Wir können dies mit der grid Kurzschreibweise wieder konsolidieren.
grid: 3fr 1fr 2fr 2fr / 1fr 1fr 2fr 3fr 5fr;
Sie kennen den Ablauf! Platzieren Sie die Bilder im Raster und wenden Sie eine clip-path darauf an.
.gallery img:nth-child(1) {
grid-area: 1 / 1 /span 2 / span 3;
clip-path: polygon(0 0, 100% 0, 0 100%);
}
.gallery img:nth-child(2) {
grid-area: 1/2/span 3/span 3;
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.gallery img:nth-child(3) {
grid-area: 1 / span 2 / -1 / -1;
clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.gallery img:nth-child(4) {
grid-area: span 3 / 1 / -1 / span 3;
clip-path: polygon(25% 0, 100% 60%, 50% 100%, 0 100%, 0 20%);
}
.gallery img:nth-child(5) {
grid-area: span 3/span 3/-1/-1;
clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
Wir können hier aufhören und unser Code ist in Ordnung, aber wir werden noch ein wenig tun, um die clip-path Werte zu optimieren. Da wir keine Abstände zwischen unseren Bildern haben, können wir die Tatsache nutzen, dass sich unsere Bilder überlappen, um sie schlanker zu machen. Hier ist ein Video, um die Idee zu veranschaulichen.
Wie Sie sehen können, benötigt das Bild in der Mitte (das mit der Kamera) keine clip-path, da die anderen Bilder es überlappen und uns die Form ohne zusätzliche Arbeit geben! Und beachten Sie, dass wir dasselbe überlappende Dreipunkt-clip-path Konzept, das wir zuvor auf dem Bild unten links verwendet haben, nutzen können, um den Code auch dort kleiner zu halten.
Am Ende haben wir ein komplex aussehendes Raster von Bildern mit nur vier clip-path Deklarationen – alle davon sind dreipunktige Polygone!
Zusammenfassung
Wow, oder? Ich weiß nicht, wie es Ihnen geht, aber mir wird nie langweilig zu sehen, was CSS heutzutage leisten kann. Es ist noch nicht lange her, da hätte all das eine wortreiche Hackerei und definitiv etwas JavaScript erfordert.
In dieser Serie haben wir viele, viele verschiedene Arten von Bilderrastern erforscht, von einfachen Dingen bis hin zu den komplexen Mosaiken, die wir heute erstellt haben. Und wir haben viel praktische Erfahrung mit CSS-Clipping gesammelt – etwas, das Sie definitiv für andere Projekte verwenden können!
Aber bevor wir enden, habe ich etwas Hausaufgaben für Sie…


Hier sind zwei Mosaike, die ich Sie bitten möchte, mit dem hier behandelten Material zu erstellen. Eines ist eher „einfach“ und das andere ist etwas knifflig. Es wäre wirklich großartig, Ihre Arbeit in den Kommentaren zu sehen, also verlinken Sie sie! Ich bin neugierig zu sehen, ob Ihr Ansatz anders ist, als wie ich vorgehen würde!
Vielen Dank für die enorme Arbeit, die Sie in dieser Serie geleistet haben. Sehr inspirierend. Ich habe nach Möglichkeiten gesucht, Formen für Worteffekte zu alphabetisieren; Ihre Artikel haben mir wunderbare Einblicke gegeben…
Liebe diese Blogbeiträge so sehr!
Hallo danke… Die Tricks sind so gut und hilfreich.