Adaptives Foto-Layout mit Flexbox

Avatar of Tim Van Damme
Tim Van Damme am

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

Schauen wir uns eine super leichtgewichtige Methode an, um einen horizontalen Masonry-Effekt für eine Reihe von Fotos beliebiger Größe zu erstellen. Wirf beliebige Fotos hinein, und sie reihen sich Kante an Kante ohne Lücken auf.

Die Lösung ist nicht nur leichtgewichtig, sondern auch ziemlich einfach. Wir verwenden eine unsortierte Liste von Bildern und nur 17 Zeilen CSS, wobei die Schwergewichte flexbox und object-fit sind.

Warum?

Ich habe zwei Hobbys: mein Leben mit Fotos zu dokumentieren und interessante Wege zu finden, CSS-Eigenschaften zu kombinieren, sowohl alte als auch neue.

Vor ein paar Wochen habe ich an XOXO teilgenommen und eine Menge Fotos gemacht, die ich auf eine schöne kleine Auswahl von 39 reduziert habe. Da ich meine Inhalte besitzen möchte, habe ich mich in den letzten Jahren damit beschäftigt, einen einfachen Fotoblog zu erstellen, aber ich konnte nie das Layout perfektionieren, das ich mir vorgestellt hatte: ein einfaches Masonry-Layout, bei dem Fotos Zeilen füllen, während sie ihr Seitenverhältnis beibehalten (denken Sie an Photos.app auf iOS, Google Fotos, Flickr...).

Ich habe recherchiert, ob es leichte, nicht-JavaScript-Optionen gibt, konnte aber nichts finden, das meinen Bedürfnissen entsprach. Angesichts einiger Flugverspätungen begann ich, mit Code herumzuspielen und beschränkte mich darauf, die Dinge so einfach wie möglich zu halten (denn das ist meine Definition von Spaß).

Grundlegender Markup

Da ich im Grunde eine Liste von Bildern erstelle, habe ich mich für eine unsortierte Liste entschieden

<ul>
  <li>
    <img>
  </li>
  <!-- ... -->
  <li>
    <img>
  </li>
</ul>

Hoch lebe Flexbox

Dann kamen eine Reihe von Erleuchtungsmomenten

  • Flexbox ist großartig, um Zeilen zu füllen, indem die Zellbreite basierend auf dem Zellinhalt bestimmt wird.
  • Das bedeutete, dass die Bilder (Quer- oder Hochformat) alle die gleiche Höhe haben mussten.
  • Ich könnte object-fit: cover; verwenden, um sicherzustellen, dass die Bilder die Zellen ausfüllen.

Theoretisch klang das nach einem soliden Plan, und es brachte mir ein Ergebnis, mit dem ich zu etwa 90% zufrieden war.

ul {
  display: flex;
  flex-wrap: wrap;
}

li {
  height: 40vh;
  flex-grow: 1;
}

img {
  max-height: 100%;
  min-width: 100%;
  object-fit: cover;
  vertical-align: bottom;
}

Hinweis: 40vh schien der beste erste Ansatz für Desktop-Browser zu sein, da es zwei volle Reihen von Fotos in angemessener Größe anzeigte und auf weitere unten hinwies. Dies ermöglichte auch mehr Fotos pro Zeile, was die Seitenverhältnisse dramatisch verbessert.

Dehnungsfähigkeit der letzten Zeile

Das einzige Problem, auf das ich gestoßen bin, ist, dass Flexbox *wirklich* alle Zeilen füllen möchte, und es hat einige seltsame Dinge mit den Seitenverhältnissen der Fotos in der letzten Zeile gemacht. Das ist wahrscheinlich mein am wenigsten geliebter Teil dieses Layouts, aber ich musste am Ende der Liste ein leeres <li> Element hinzufügen.

<ul>
  <li>
    <img>
  </li>
  <!-- ... -->
  <li>
    <img>
  </li>
  <li></li>
</ul>

Kombiniert mit diesem Stück CSS

li:last-child {
  flex-grow: 10;
}

Hinweis: Es gibt keine Wissenschaft hinter der Verwendung von „10“. Bei all meinen Tests lieferte dies die besten Ergebnisse.

Demo

Siehe den Pen
Adaptive Photo Layout
von Tim Van Damme (@maxvoltar)
auf CodePen.

Viewport-Optimierung

Bei der Arbeit in verschiedenen Viewport-Orientierungen sind einige Überlegungen zu beachten.

Porträt

Wenn Ihr Viewport höher als breit ist, schränkt dieser Ansatz die Anzahl der Fotos pro Zeile ein, was ihre Seitenverhältnisse beeinträchtigt. Um dies zu lösen, können Sie die Fotozeilen mit dieser einfachen Media Query weniger hoch machen

@media (max-aspect-ratio: 1/1) {
  li {
    height: 30vh;
  }
}

Kurze Bildschirme

Um bei kleinen Geräten im Querformat zu helfen, erhöht die Erhöhung der Höhe von Fotos, um sie so groß wie möglich zu sehen

@media (max-height: 480px) {
  li {
    height: 80vh;
  }
}

Kleinere Bildschirme + Porträt

Die meisten Handys sind nicht breit genug, damit Flexbox richtig funktioniert, ohne die Fotos zu miniaturisieren. Daher habe ich hier darauf verzichtet, mehrere Fotos pro Zeile zu fitting. Dennoch lohnt es sich, hier eine maximale Höhe festzulegen, damit Sie zumindest einen Hinweis auf das nächste Foto in der Liste haben.

@media (max-aspect-ratio: 1/1) and (max-width: 480px) {
  ul {
    flex-direction: row;
  }

  li {
    height: auto;
    width: 100%;
  }

  img {
    width: 100%;
    max-height: 75vh;
    min-width: 0;
  }
}

Da haben wir es!

Dieser Ansatz respektiert die Seitenverhältnisse von Fotos nicht vollständig (aber er kommt nah heran) und führt *gelegentlich* zu einigen seltsamen Ergebnissen, aber ich liebe die Einfachheit und Flexibilität davon absolut. Möchten Sie, dass Ihre Galerie horizontal statt vertikal scrollt? Ein paar Anpassungen ermöglichen Ihnen dies. Gibt es 1.000 Fotos in der Galerie oder nur eines? Alles sieht gut aus. Unsicher bei Seitenverhältnissen? Flexbox ist Ihr bester Freund. Werfen Sie noch einmal einen Blick auf die Demo, wenn Sie es noch nicht getan haben, und lassen Sie mich wissen, was Sie denken!

Bonus

Abhängig von der Größe dieser Fotos kann eine Seite wie diese schnell mehrere Megabyte groß werden. Auf dem Blog, an dem ich arbeite, habe ich loading="lazy" hinzugefügt, um dabei zu helfen. Mit diesem Attribut auf den Bildern werden nur Fotos geladen, wenn Sie beim Scrollen näher an sie herankommen. Es wird derzeit nur in Chrome unterstützt, aber Sie könnten eine eigene, besser unterstützte Technik entwickeln.