Zoomen von Bildern in einem Rasterlayout PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.

Zoomen von Bildern in einem Rasterlayout

Dank CSS Grid ist es einfach, ein Raster aus Bildern zu erstellen. Aber das Gitter dazu bringen, ausgefallene Dinge zu tun nachdem die Bilder platziert wurden, kann schwierig zu lösen sein.

Angenommen, Sie möchten den Bildern, in denen sie wachsen, einen ausgefallenen Hover-Effekt hinzufügen und über die Zeilen und Spalten hinauszoomen, in denen sie sich befinden? Wir können das schaffen!

Cool, oder? Wenn Sie den Code überprüfen, finden Sie kein JavaScript, keine komplexen Selektoren oder sogar magische Zahlen. Und dies ist nur ein Beispiel unter vielen, die wir untersuchen werden!

Aufbau des Gitters

Der HTML-Code zum Erstellen des Rasters ist so einfach wie eine Liste von Bildern in einem Container. Mehr brauchen wir nicht.

<div class="gallery">
  <img>
  <img>
  <img>
  <!-- etc. -->
</div>

Für das CSS beginnen wir zunächst damit, das Raster wie folgt festzulegen:

.gallery {
  --s: 150px; /* controls the size */
  --g: 10px;  /* controls the gap */

  display: grid;
  gap: var(--g);
  width: calc(3*var(--s) + 2*var(--g)); /* 3 times the size plus 2 times the gap */
  aspect-ratio: 1;
  grid-template-columns: repeat(3, auto);
}

Kurz gesagt, wir haben zwei Variablen, eine, die die Größe der Bilder steuert, und eine, die die Größe der Lücke zwischen den Bildern festlegt. aspect-ratio hilft, die Dinge im Verhältnis zu halten.

Sie fragen sich vielleicht, warum wir nur drei Spalten, aber keine Zeilen definieren. Nein, ich habe die Zeilen nicht vergessen – wir müssen sie nur nicht explizit setzen. CSS Grid kann Elemente automatisch platzieren implizite Zeilen und Spalten, was bedeutet, dass wir so viele Zeilen wie nötig für eine beliebige Anzahl von Bildern erhalten, die wir darauf werfen. Wir können die Zeilen stattdessen explizit definieren, aber wir müssen hinzufügen grid-auto-flow: column um sicherzustellen, dass der Browser die benötigten Spalten für uns erstellt.

Hier ist ein Beispiel, um beide Fälle zu veranschaulichen. Der Unterschied besteht darin, dass man in a einfließt row Richtung und die andere in a column Richtung.

Zur kasse diesen anderen Artikel, den ich geschrieben habe Weitere Informationen zu den impliziten Rastern und dem Algorithmus für die automatische Platzierung finden Sie hier.

Jetzt, da wir unser Raster haben, ist es an der Zeit, die Bilder zu stylen:

.gallery > img {
  width: 0;
  height: 0;
  min-height: 100%;
  min-width: 100%;
  object-fit: cover;
}

Der Hover-Effekt, den wir erstellen, basiert auf diesem CSS. Es kommt Ihnen wahrscheinlich seltsam vor, dass wir Bilder erstellen, die weder Breite noch Höhe haben, aber eine Mindestbreite und -höhe von 100 % haben. Aber Sie werden sehen, dass es ein ziemlich guter Trick für das ist, was wir erreichen wollen.

Was ich hier mache, ist dem Browser mitzuteilen, dass die Bilder haben müssen 0 Breite und Höhe müssen aber auch gleich einer Mindesthöhe sein 100%… aber 100% von was? Bei Verwendung von Prozentsätzen ist der Wert relativ zu etwas anderem. In diesem Fall wird unser Bild in a platziert Gitterzelle und wir müssen diese Größe kennen, um zu wissen, was es ist 100% ist relativ zu.

Der Browser wird zunächst ignorieren min-height: 100% um die Größe der Gitterzellen zu berechnen, aber es wird die verwenden height: 0 in seiner Berechnung. Das bedeutet, dass unsere Bilder nicht zur Größe der Gitterzellen beitragen … weil sie technisch gesehen keine physische Größe haben. Dies führt zu drei gleichen Spalten und Zeilen, die auf der Größe des Rasters basieren (das wir auf der definiert haben .gallery's Breite und aspect-ratio). Die Höhe jeder Gitterzelle ist nichts anderes als die Variable --s wir definiert (dasselbe gilt für die Breite).

Zoomen von Bildern in einem Rasterlayout

Jetzt, da wir die Abmessungen der Zellen unseres Rasters haben, wird der Browser sie verwenden min-height: 100% (und min-width: 100%), wodurch die Bilder gezwungen werden, den Raum jeder Gitterzelle vollständig auszufüllen. Das Ganze mag etwas verwirrend aussehen, aber die Hauptidee ist sicherzustellen, dass das Raster die Größe der Bilder definiert und nicht umgekehrt. Ich möchte nicht, dass das Bild die Größe des Rasters definiert, und Sie werden verstehen, warum, nachdem Sie den Hover-Effekt hinzugefügt haben.

Erstellen des Hover-Effekts

Was wir tun müssen, ist den Maßstab der Bilder zu erhöhen, wenn sie mit der Maus bewegt werden. Wir können das tun, indem wir ein Bild anpassen width und height on :hover:

.gallery {
  --f: 1.5; /* controls the scale factor */
}

.gallery img:hover{
  width:  calc(var(--s) * var(--f));
  height: calc(var(--s) * var(--f));
}

Ich habe eine neue benutzerdefinierte Variable hinzugefügt, --f, zur Mischung als Skalierungsfaktor, um die Größe beim Schweben zu steuern. Beachten Sie, wie ich die Größenvariable multipliziere, --s, um damit die neue Bildgröße zu berechnen.

Aber Sie sagten, dass die Bildgröße 0 sein muss. Was ist los? Ich bin verloren…

Was ich gesagt habe, ist immer noch wahr, aber ich mache eine Ausnahme für das schwebende Bild. Ich sage dem Browser, dass nur ein Bild eine Größe haben wird, die nicht gleich Null ist – also wird es zur Dimension des Rasters beitragen – während alle anderen gleich bleiben 0.

Zoomen von Bildern in einem Rasterlayout PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.
Zoomen von Bildern in einem Rasterlayout

Die linke Seite zeigt das Gitter in seinem natürlichen Zustand ohne schwebende Bilder, was die rechte Seite zeigt. Alle Rasterzellen auf der linken Seite sind gleich groß, da alle Bilder keine physikalischen Abmessungen haben.

Auf der rechten Seite wird das zweite Bild in der ersten Zeile verschoben, wodurch es Abmessungen erhält, die sich auf die Größe der Rasterzelle auswirken. Der Browser vergrößert diese spezifische Gitterzelle beim Hovern, was zur Gesamtgröße beiträgt. Und da die Größe des gesamten Rasters festgelegt ist (weil wir eine feste width auf die .gallery), werden die anderen Gitterzellen logischerweise kleiner werden, um die zu halten .gallery's Gesamtgröße im Takt.

Das ist unser Zoom-Effekt in Aktion! Indem wir die Größe nur eines Bildes erhöhen, beeinflussen wir die gesamte Rasterkonfiguration, und wir sagten zuvor, dass das Raster die Größe der Bilder definiert, sodass sich jedes Bild innerhalb seiner Rasterzelle erstreckt, um den gesamten Raum auszufüllen.

Dazu fügen wir einen Hauch von hinzu transition Und verwenden object-fit um Bildverzerrungen zu vermeiden und die Illusion ist perfekt!

Ich weiß, dass die Logik hinter dem Trick nicht leicht zu verstehen ist. Machen Sie sich keine Sorgen, wenn Sie es nicht vollständig verstehen. Das Wichtigste ist, die Struktur des verwendeten Codes zu verstehen und ihn zu ändern, um mehr Variationen zu erhalten. Das werden wir als nächstes tun!

Weitere Bilder hinzufügen

Wir haben ein 3×3-Raster erstellt, um den Haupttrick zu erklären, aber Sie haben wahrscheinlich erraten, dass wir hier nicht aufhören müssen. Wir können die Anzahl der Spalten und Zeilen variabel machen und so viele Bilder hinzufügen, wie wir wollen.

.gallery {
  --n: 3; /* number of rows*/
  --m: 4; /* number of columns */
  --s: 150px; /* control the size */
  --g: 10px;  /* control the gap */
  --f: 1.5;   /* control the scale factor */

  display: grid;
  gap: var(--g);
  width:  calc(var(--m)*var(--s) + (var(--m) - 1)*var(--g));
  height: calc(var(--n)*var(--s) + (var(--n) - 1)*var(--g));
  grid-template-columns: repeat(var(--m),auto);
}

Wir haben zwei neue Variablen für die Anzahl der Zeilen und Spalten. Dann definieren wir einfach die Breite und Höhe unseres Gitters damit. Das gleiche für grid-template-columns die verwendet die --m Variable. Und genau wie zuvor müssen wir die Zeilen nicht explizit definieren, da die automatische Platzierungsfunktion des CSS-Grids die Arbeit für uns erledigt, egal wie viele Bildelemente wir verwenden.

Warum nicht unterschiedliche Werte für Breite und Höhe? Wir können das schaffen:

.gallery {
  --n: 3; /* number of rows*/
  --m: 4; /* number of columns */
  --h: 120px; /* control the height */
  --w: 150px; /* control the width */
  --g: 10px;  /* control the gap */
  --f: 1.5;   /* control the scale factor */

  display: grid;
  gap: var(--g);
  width:  calc(var(--m)*var(--w) + (var(--m) - 1)*var(--g));
  height: calc(var(--n)*var(--h) + (var(--n) - 1)*var(--g));
  grid-template-columns: repeat(var(--m),auto);
}

.gallery img:hover{
  width:  calc(var(--w)*var(--f));
  height: calc(var(--h)*var(--f));
}

Wir ersetzen --s mit zwei Variablen, eine für die Breite, --w, und noch eins für die Höhe, --h. Dann passen wir alles andere entsprechend an.

Also haben wir mit einem Raster mit fester Größe und Anzahl von Elementen begonnen, aber dann haben wir einen neuen Satz von Variablen erstellt, um jede gewünschte Konfiguration zu erhalten. Alles, was wir tun müssen, ist, so viele Bilder hinzuzufügen, wie wir wollen, und die CSS-Variablen entsprechend anzupassen. Die Kombinationen sind grenzenlos!

Was ist mit einer Vollbildversion? Ja, das ist auch möglich. Wir müssen nur wissen, welche Werte wir unseren Variablen zuweisen müssen. Wenn wir wollen N Reihen von Bildern und wir möchten, dass unser Raster im Vollbildmodus angezeigt wird, müssen wir zuerst nach einer Höhe von lösen 100vh:

var(--n) * var(--h) + (var(--n) - 1) * var(--g) = 100vh

Gleiche Logik für die Breite, aber mit vw statt vh:

var(--m) * var(--w) + (var(--m) - 1) * var(--g) = 100vw

Wir rechnen nach:

--w: (100vw - (var(--m) - 1) * var(--g)) / var(--m)
--h: (100vh - (var(--n) - 1) * var(--g)) / var(--n)

Erledigt!

Es ist genau das gleiche HTML, aber mit einigen aktualisierten Variablen, die die Größe und das Verhalten des Rasters ändern.

Beachten Sie, dass ich die zuvor festgelegte Formel weggelassen habe .gallery's width und height und ersetzte sie durch 100vw und 100vh, beziehungsweise. Die Formel wird uns das gleiche Ergebnis liefern, aber da wir wissen, welchen Wert wir wollen, können wir all diese zusätzliche Komplexität aufgeben.

Wir können auch die vereinfachen --h und --w durch Entfernen der Lücke aus der Gleichung zugunsten von:

--h: calc(100vh / var(--n)); /* Viewport height divided by number of rows */
--w: calc(100vw / var(--m)); /* Viewport width divided by number of columns */

Dadurch wächst das schwebende Bild etwas mehr als im vorherigen Beispiel, aber das ist keine große Sache, da wir die Skalierung mit steuern können --f Variable, die wir als Multiplikator verwenden.

Und da die Variablen an einer Stelle verwendet werden, können wir den Code noch vereinfachen, indem wir sie ganz entfernen:

Es ist wichtig zu beachten, dass diese Optimierung nur für das Vollbildbeispiel gilt und nicht für die Beispiele, die wir behandelt haben. Dieses Beispiel ist ein besonderer Fall, in dem wir den Code leichter machen können, indem wir einen Teil der komplexen Berechnungsarbeit entfernen, die wir in den anderen Beispielen benötigt haben.

Wir haben eigentlich alles, was wir brauchen, um das beliebte Muster der expandierenden Paneele zu erstellen:

Lassen Sie uns noch tiefer graben

Haben Sie bemerkt, dass unser Skalierungsfaktor kleiner sein kann als 1? Wir können die Größe des schwebenden Bildes kleiner als definieren --h or --w aber das Bild wird beim Hover größer.

Die anfängliche Rasterzellengröße ist gleich --w und --h, warum machen also kleinere Werte die Gitterzelle? größer? Sollte die Zelle nicht bekommen kleinere, oder zumindest seine ursprüngliche Größe beibehalten? Und was ist die endgültige Größe der Gitterzelle?

Wir müssen genauer untersuchen, wie der CSS-Grid-Algorithmus die Größe der Gitterzellen berechnet. Und dazu gehört, den Standardwert von CSS Grid zu verstehen Ausrichtung strecken.

Hier ist ein Beispiel, um die Logik zu verstehen.

Auf der linken Seite der Demo habe ich eine zweispaltige mit definiert auto Breite. Wir erhalten das intuitive Ergebnis: zwei gleiche Spalten (und zwei gleiche Gitterzellen). Aber das Raster, das ich auf der rechten Seite der Demo eingerichtet habe, wo ich die Ausrichtung mit aktualisiere place-content: start, scheint nichts zu haben.

DevTools zeigt uns, was in beiden Fällen wirklich passiert:

Zoomen von Bildern in einem Rasterlayout PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.
Zoomen von Bildern in einem Rasterlayout

Im zweiten Grid haben wir zwei Spalten, aber ihre Breite ist gleich Null, also erhalten wir zwei Grid-Zellen, die in der oberen linken Ecke des Grid-Containers eingeklappt sind. Das ist nicht ein Fehler, sondern das logische Ergebnis der Ausrichtung des Gitters. Wenn wir die Größe einer Spalte (oder Zeile) mit auto, es bedeutet, dass sein Inhalt seine Größe bestimmt – aber wir haben eine leere div ohne Inhalt, dem Platz zu machen wäre.

Aber seit stretch die Standardausrichtung ist und wir genügend Platz in unserem Raster haben, wird der Browser beide Rasterzellen gleichmäßig strecken, um den gesamten Bereich abzudecken. So endet das Gitter auf der linken Seite mit zwei gleichen Spalten.

Aus die spezifikation:

Beachten Sie, dass bestimmte Werte von justify-content und align-content kann dazu führen, dass die Spuren voneinander beabstandet sind (space-around, space-between, space-evenly) oder in der Größe geändert werden (stretch).

Beachten Sie das „in der Größe zu ändern“, das hier der Schlüssel ist. Im letzten Beispiel habe ich verwendet place-content was die Abkürzung für ist justify-content und align-content

Und das ist irgendwo darin vergraben der Grid-Sizing-Algorithmus Spezifikationen:

Dieser Schritt erweitert Spuren, die eine haben Auto Max-Track-Sizing-Funktion durch Dividieren aller verbleibenden positiven, definitiv Freiraum gleichermaßen unter ihnen. Wenn der freie Speicherplatz ist unbestimmt, Aber die Gitterbehälter hat eine bestimmte Mindestbreite/Höhe, verwenden Sie stattdessen diese Größe, um den freien Speicherplatz für diesen Schritt zu berechnen.

„Gleich“ erklärt, warum wir am Ende gleiche Gitterzellen haben, aber es gilt für „den freien Raum“, der sehr wichtig ist.

Nehmen wir das vorherige Beispiel und fügen Inhalt zu einem der hinzu divs:

Wir haben ein Quadrat hinzugefügt 50px Bild. Hier ist eine Illustration, wie jedes Raster in unserem Beispiel auf dieses Bild reagiert:

Zoomen von Bildern in einem Rasterlayout PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.
Zoomen von Bildern in einem Rasterlayout

Im ersten Fall sehen wir, dass die erste Zelle (in Rot) größer ist als die zweite (in Blau). Im zweiten Fall ändert sich die Größe der ersten Zelle, um sie an die physische Größe des Bildes anzupassen, während die zweite Zelle ohne Abmessungen bleibt. Der freie Speicherplatz wird gleichmäßig aufgeteilt, aber die erste Zelle enthält mehr Inhalt, wodurch sie größer wird.

Dies ist die Mathematik, um unseren freien Speicherplatz herauszufinden:

(grid width) - (gap) - (image width) = (free space)
200px - 5px - 50px = 145px 

Geteilt durch zwei – die Anzahl der Spalten – erhalten wir eine Breite von 72.5px für jede Spalte. Aber wir fügen die Größe des Bildes hinzu, 50px, zur ersten Spalte, die uns mit einer Spalte bei verlässt 122.5px und die zweite gleich 72.5px.

Die gleiche Logik gilt für unser Bildraster. Alle Bilder haben eine Größe gleich 0 (kein Inhalt), während das schwebende Bild zur Größe beiträgt – auch wenn es nur so ist 1px — macht seine Gitterzelle größer als die anderen. Aus diesem Grund kann der Skalierungsfaktor jeden Wert größer als annehmen 0 sogar Dezimalstellen dazwischen 0 und 1.

Um die endgültige Breite der Gitterzellen zu erhalten, führen wir die gleiche Berechnung durch, um Folgendes zu erhalten:

(container width) - (sum of all gaps) - (hovered image width) = (free space)

Die Containerbreite wird definiert durch:

var(--m)*var(--w) + (var(--m) - 1)*var(--g)

…und alle Lücken sind gleich:

(var(--m) - 1)*var(--g)

…und für das schwebende Bild haben wir:

var(--w)*var(--f)

All das können wir mit unseren Variablen berechnen:

var(--m)*var(--w) - var(--w)*var(--f) = var(--w)*(var(--m) - var(--f))

Die Anzahl der Spalten wird durch definiert --m , also teilen wir diesen freien Speicherplatz gleichmäßig auf, um Folgendes zu erhalten:

var(--w)*(var(--m) - var(--f))/var(--m)

… was uns die Größe der nicht bewegten Bilder gibt. Für schwebende Bilder haben wir Folgendes:

var(--w)*(var(--m) - var(--f))/var(--m) + var(--w)*var(--f)
var(--w)*((var(--m) - var(--f))/var(--m) + var(--f))

Wenn wir die endgültige Größe des schwebenden Bildes steuern möchten, verwenden wir die obige Formel, um genau die gewünschte Größe zu erhalten. Wenn wir zum Beispiel möchten, dass das Bild doppelt so groß wird:

(var(--m) - var(--f))/var(--m) + var(--f) = 2

Also, der Wert unseres Skalenmultiplikators, --f, muss gleich sein:

var(--m)/(var(--m) - 1)

Für drei Spalten haben wir 3/2 = 1.5 und das ist der Skalierungsfaktor, den ich in der ersten Demo dieses Artikels verwendet habe, weil ich das Bild beim Hover doppelt so groß machen wollte!

Die gleiche Logik gilt für die Höhenberechnung, und falls wir beide unabhängig voneinander steuern möchten, müssen wir zwei Skalierungsfaktoren berücksichtigen, um sicherzustellen, dass wir beim Schweben eine bestimmte Breite und Höhe haben.

.gallery {
  /* same as before */
   --fw: 1.5; /* controls the scale factor for the width */
   --fh: 1.2; /* controls the scale factor for the height */

  /* same as before */
}

.gallery img:hover{
  width:  calc(var(--w)*var(--fw));
  height: calc(var(--h)*var(--fh));
}

Jetzt kennen Sie alle Geheimnisse, um jede Art von Bildraster mit einem coolen Hover-Effekt zu erstellen und gleichzeitig die Kontrolle über die gewünschte Größe zu haben, indem Sie die gerade behandelte Mathematik verwenden.

Wrapping up

In meinem letzte Artikelhaben wir ein komplex aussehendes Raster mit ein paar CSS-Zeilen erstellt, das die impliziten Raster- und Autoplatzierungsfunktionen von CSS Grid nutzt. In diesem Artikel haben wir uns auf einige CSS-Rastergrößen-Tricks verlassen, um ein ausgefallenes Raster von Bildern zu erstellen, die beim Hover zoomen und das Raster entsprechend anpassen. All dies mit einem vereinfachten Code, der mithilfe von CSS-Variablen einfach angepasst werden kann!

Im nächsten Artikel spielen wir mit Formen! Wir werden CSS-Raster mit Maske und Clip-Pfad kombinieren, um ein ausgefallenes Bildraster zu erhalten.

Zeitstempel:

Mehr von CSS-Tricks