Die Suche nach einem Fixed-Background-Effekt mit Inline Bildern

Avatar of Alex Lazar
Alex Lazar am

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

Vor ein paar Tagen habe ich an einem Kundenprojekt gearbeitet und wollte einen bestimmten Effekt auf einem <img> erzielen. Hintergrundbilder können den gewünschten Effekt ziemlich einfach mit background-attachment: fixed; erzielen. Damit bleibt ein Hintergrundbild an seinem Platz – auch wenn die Seite gescrollt wird. Es wird nicht sehr oft verwendet, daher kann der Effekt ungewöhnlich und auffällig wirken, besonders wenn er sparsam eingesetzt wird.

Inhaltsverzeichnis

Es hat einige Zeit gedauert, bis ich herausgefunden habe, wie man denselben Effekt nur mit einem Inline-Bild anstelle eines CSS-Hintergrundbilds erzielt. Dies ist ein Video des Effekts in Aktion

Der genaue Code für die obige Demo ist in diesem Git-Repo verfügbar. Beachten Sie nur, dass es sich um ein Next.js-Projekt handelt. Wir werden uns gleich einem CodePen-Beispiel mit rohem HTML zuwenden.

Warum <img> anstelle von background-image verwenden?

Es gibt eine Reihe von Gründen, warum ich das für mein Projekt wollte

  • Es ist einfacher, Lazy Loading zu verwenden (z. B. <img loading="lazy"… >).
  • Es bietet bessere SEO (ganz zu schweigen von Barrierefreiheit), dank des alt-Textes.
  • Es ist möglich, srcset/sizes zu verwenden, um die Ladeleistung zu verbessern.
  • Es ist möglich, das <picture>-Tag zu verwenden, um die beste Bildgröße und das beste Format für den Browser des Benutzers auszuwählen.
  • Es ermöglicht Benutzern, das Bild herunterzuladen und zu speichern (ohne auf DevTools zurückgreifen zu müssen).

Insgesamt ist es besser, das Bild-Tag zu verwenden, wo immer es möglich ist, insbesondere wenn das Bild als Inhalt und nicht als Dekoration betrachtet werden kann. Daher landete ich bei einer Technik, die CSS clip-path verwendet. Wir werden uns dem gleich widmen, direkt nachdem wir uns die background-image-Methode angesehen haben, um beide Ansätze schön nebeneinander zu vergleichen.

1. CSS background-image verwenden

Dies ist der „originäre“ Weg, um einen festen Scroll-Effekt zu erzielen. Hier ist das CSS

.hero-section {
  background-image: url("nice_bg_image.jpg");
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center; 
  background-attachment: fixed;
}

Aber wie wir gerade gesehen haben, ist dieser Ansatz für einige Situationen nicht ideal, da er auf der CSS-Eigenschaft background-image zum Aufrufen und Laden des Bildes beruht. Das bedeutet, dass das Bild technisch gesehen nicht als Inhalt betrachtet wird – und daher von Screenreadern nicht erkannt wird. Wenn wir mit einem Bild arbeiten, das Teil des Inhalts ist, sollten wir es zugänglich machen, damit es wie Inhalt und nicht wie Dekoration konsumiert wird.

Ansonsten funktioniert diese Technik gut, aber nur, *wenn das Bild die gesamte Breite des Viewports einnimmt und/oder zentriert ist*. Wenn Sie ein Bild auf der rechten oder linken Seite der Seite haben, wie im Beispiel, werden Sie auf eine ganze Reihe von Positionierungsproblemen stoßen, da background-position relativ zur Mitte des Viewports ist.

Die Korrektur erfordert einige Media Queries, um sicherzustellen, dass es auf allen Geräten richtig positioniert ist.

2. Den clip-path-Trick bei einem Inline-Bild verwenden

Jemand auf StackOverflow teilte diesen clip-path-Trick, und er erledigt die Arbeit gut. Sie können auch weiterhin das <img>-Tag verwenden, was, wie wir oben besprochen haben, in einigen Fällen vorteilhaft sein kann, insbesondere wenn ein Bild Teil des Inhalts und nicht reine Dekoration ist.

Hier ist der Trick

.image-container {
  position: relative;
  height: 200px;
  clip-path: inset(0);
}

.image {
  object-fit: cover;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

Schauen Sie es sich in Aktion an

Bevor wir nun losstürzen und diesen Snippet überall anbringen, hat er seine eigenen Nachteile. Zum Beispiel ist der Code meiner Meinung nach *etwas lang* für einen so einfachen Effekt. Aber noch wichtiger ist die Tatsache, dass die Arbeit mit clip-path auch einige Implikationen hat. Zum einen kann ich nicht einfach ein border-radius: 10px; wie im vorherigen Beispiel einfügen, um die Ecken des Bildes abzurunden. Das funktioniert nicht – es erfordert, abgerundete Ecken aus dem Clipping-Pfad selbst zu erstellen.

Ein weiteres Beispiel: Ich weiß nicht, wie ich das Bild *innerhalb* des clip-path positionieren soll. Wiederum mag das eine Frage des guten Wissens über clip-path sein und es dort zeichnen, wo Sie es brauchen, oder das Bild im Voraus zuschneiden, wie es nötig ist.

Gibt es etwas Besseres?

Persönlich habe ich auf die Verwendung des Fixed-Scrolling-Effekts bei Inline-Bildern verzichtet und bin wieder auf die Verwendung eines CSS-Hintergrundbilds zurückgekehrt – was, wie ich weiß, etwas einschränkend ist.

Haben Sie jemals versucht, dies zu bewerkstelligen, insbesondere mit einem Inline-Bild, und es gut hinbekommen? Ich würde es gerne erfahren!