Wie man ein reines CSS-Karussell erstellt

Avatar of Robin Rendle
Robin Rendle am

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

Wir haben in einer aktuellen Ausgabe des Newsletters eine Möglichkeit erwähnt, ein reines CSS-Karussell zu erstellen, und ich dachte, eine detailliertere Ausarbeitung wäre interessant und würde einige meiner Gedanken zur Erstellung eines solchen einfangen.

Also, das werden wir heute machen.

Hier gibt es keinerlei JavaScript! Keine jQuery-Plugins. Keine Tricksereien. Nur ein paar neue CSS-Eigenschaften, mit denen ich experimentiert habe, sowie etwas grundlegendes HTML.

Okay, zu Beginn müssen wir uns auf die Auszeichnung konzentrieren. Das Design umfasst eine linke Navigation, die aus Bildern besteht, und eine große Bildergalerie auf der rechten Seite, mit der wir jedes Bild einzeln durchscrollen können. Wir benötigen auch einen Wrapper, der uns hilft, das Layout zu organisieren.

<div class="wrapper">
  <nav class="lil-nav"></nav>
  <div class="gallery"></div>
</div>

Als Nächstes können wir Bilder hinzufügen! Für dieses kleine Beispiel habe ich unsere Liste von Websites mit hochwertigen Bildern, die Sie kostenlos verwenden können, durchgesehen und mich für Unsplash entschieden.

Nachdem ich die Bilder mit dem CodePen Asset Manager gespeichert hatte, begann ich, die URLs zum nav Element hinzuzufügen.

<nav class="lil-nav">
  <a href="#image-1">
    <img class="lil-nav__img" src="..." alt="Yosemite" />
  </a>
  <a href="#image-2">
    <img class="lil-nav__img" src="..." alt="Basketball hoop" />
  </a>
  <!-- more images go here --> 
</nav>

Sehen Sie, dass der href zu jedem dieser Links auf eine ID zeigt? Das liegt daran, dass wir, wenn wir uns die Demo noch einmal ansehen, ein Bild anklicken können und dann möchten, dass es zur größeren Version dieses Bildes in der Galerie auf der rechten Seite springt.

Also, jetzt können wir auch diese Bilder zur großen Galerie hinzufügen...

<div class="gallery">
  <img class="gallery__img" id="image-1" src="..." alt="Yosemite" />
  <img class="gallery__img" id="image-2" src="..." alt="Basketball hoop" />
  <!-- more images go here --> 
</div>

Schön. Als Nächstes kommt der lustige Teil: dieses Ding zu stylen. Wir können ein Grid-Layout für das übergeordnete .wrapper verwenden und einige intelligente Standardwerte für das img Element festlegen.

img {
  display: block;
  max-width: 100%;
}

.wrapper {
  display: grid;
  grid-template-columns: 1fr 5fr;
  grid-gap: 20px;
}

Bisher haben wir unser Layout sortiert und unsere Links eingerichtet. Als Nächstes kümmern wir uns um den Überlauf, der außerhalb unseres Wrappers austreten könnte, und stellen sicher, dass die Navigation und die Galerie scrollbar sind.

.wrapper {
  display: grid;
  grid-template-columns: 1fr 5fr;
  grid-gap: 10px;
  overflow: hidden;
  height: 100vh; 
}

.gallery {
  overflow: scroll;
}

.lil-nav {
  overflow-y: scroll;
  overflow-x: hidden;
}

Wir können jetzt jedes Bild in der Galerie durchscrollen, aber wenn dies eine Produktionswebsite wäre, würden wir wahrscheinlich sicherstellen wollen, dass die Leute leichter an diesem Karussell vorbeiscrollen können. Trent Walton schrieb vor einigen Jahren über genau dieses Problem, und ich denke, es ist immer gut, das im Auge zu behalten.

Als Nächstes konzentrieren wir uns auf das Karussell-Snap jedes Bildes in der Galerie. Dazu müssen wir die Eigenschaften scroll-snap-type und scroll-snap-align wie folgt verwenden.

.gallery {
  overflow: scroll;
  scroll-snap-type: x mandatory;
}

.gallery__img {
  scroll-snap-align: start;
  margin-bottom: 10px;
}

Versuchen Sie nun erneut, die Galerie auf der rechten Seite durchzuscrollen.

Wenn Sie mehr über diese Eigenschaften erfahren möchten, empfehle ich Ihnen dieses Stück über praktisches CSS-Scroll-Snapping, das sich mit den Details dieser Eigenschaften befasst.

Wir haben ein ziemlich brauchbares Karussell! Von hier aus müssen wir nur noch das Design aufräumen, da das Galeriebild nicht die volle Höhe des Bildschirms hat. Dazu können wir object-fit verwenden und jedem Bild eine min-height mit der vh Einheit geben, genau wie hier.

.gallery__img {
  scroll-snap-align: start;
  margin-bottom: 10px;
  min-height: 100vh;
  object-fit: cover;
}

Jetzt sind die großen Galeriebilder immer bildschirmfüllend und skalieren, um die Breite und Höhe auszufüllen. Machen wir weiter und kümmern uns um den Stil der kleinen Navigationsbilder.

.lil-nav {
  overflow-y: scroll;
  overflow-x: hidden;
}

.lil-nav a {
  height: 200px;
  display: flex;
  margin-bottom: 10px;
}

.lil-nav__img {
  object-fit: cover;
}

Zuerst habe ich diese kleine Navigation auch wie ein Karussell agieren lassen, aber das fühlte sich wirklich komisch an. Ich behalte vorerst das Standardverhalten scroll bei. In der obigen Demo versuchen Sie jedoch, ein Bild anzuklicken. Haben Sie bemerkt, wie es sofort zu diesem Bild im Karussell springt? Es wäre schön, wenn wir diesen Übergang etwas animieren könnten – und das können wir!

.gallery {
  overflow: scroll;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
}

Diese scroll-behavior CSS-Eigenschaft ist dafür super praktisch, und so wird das Ganze nun animiert, wenn Sie eines der Navigationspunkte anklicken.

Schön, oder? Eine weitere Kleinigkeit, die wir hier tun könnten, ist, einen Filter auf die Navigationspunkte anzuwenden, um sie schwarz-weiß zu machen und sie dann beim Hovern zu animieren.

.lil-nav__img {
  object-fit: cover;
  filter: saturate(0);
  transition: 0.3s ease all;
}

.lil-nav__img:hover {
  transform: scale(1.05);
  filter: saturate(1);
}

Ich bin sicher, wir könnten hier noch viel mehr tun, aber ich denke, das funktioniert ganz gut!

Wir könnten sogar ein kleines bisschen JavaScript hinzufügen, um anzuzeigen, welches Bild aktiv ist, aber ich glaube, die Leute wissen das allein schon vom Betrachten der Galerie.

Das ist alles! Wir haben jetzt ein Karussell, das für progressive Verbesserung ziemlich gut ist, und es bedeutet, dass wir keine JavaScript-Bibliothek laden oder mehr Code schreiben müssen, als wir wirklich brauchen.

Lassen Sie uns jedoch noch einen Schritt weiter gehen und diesen Kerl responsiv machen. Was wir tun wollen, ist, die Reihenfolge unseres Grids umzukehren, indem wir alle unsere aktuellen Stile in eine Media Query verschieben, die nur bei größeren Bildschirmen aktiviert wird.

Sie möchten diese Demo vielleicht in einem neuen Tab öffnen und die Größe des Browsers verkleinern/vergrößern, um die Änderungen zu sehen.

Wenn Sie diese Demo auf einem Mobilgerät laden, sollten Sie sehen, wie das Layout zwischen den beiden Modi wechselt. Dies geschieht durch eine einzige Media Query auf dem .wrapper Element. Beachten Sie, dass wir Sass verwenden.

$large: 1200px;

.wrapper {
  overflow: hidden;
  height: 100vh;
  display: grid;
  grid-template-rows: 2fr 1fr;
  grid-gap: 10px;

  @media screen and (min-width: $large) {
    grid-template-columns: 1fr 5fr;
    grid-template-rows: auto;
  }
}

Fügen wir auch eine für die Navigation hinzu. Aber dieses Mal müssen wir der Navigation sagen, dass sie in der zweiten Zeile beginnt, damit sie zum unteren Bildschirmrand verschoben wird.

.lil-nav {
  overflow-x: scroll;
  overflow-y: hidden;
  display: flex;
  grid-row-start: 2;

  @media screen and (min-width: $large) {
    overflow-y: scroll;
    overflow-x: hidden;
    display: block;
    grid-row-start: auto;
  }
}

Bei der Galerie müssen wir für größere Bildschirme den scroll-type umkehren und auch die overflow Eigenschaft umkehren.

.gallery {
  overflow-x: scroll;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  display: flex;

  @media screen and (min-width: $large) {
    display: block;
    overflow-y: scroll;
    overflow-x: hidden;
    scroll-snap-type: y mandatory;
  }
}

Das sind die meisten Änderungen, die wir vornehmen mussten, und sie gefallen mir ziemlich gut! Wenn wir dies produktionsreif machen wollten, würden wir uns um die Barrierefreiheit kümmern (z.B. wir möchten nicht, dass Screenreader alle Bilder sowohl in der Nav als auch in der Galerie vorlesen). Dann gibt es die Leistung – wir könnten Lazy Loading in Betracht ziehen, damit die Bilder nur dann gerendert werden, wenn sie benötigt werden.

Auf jeden Fall ist das ein guter Anfang!