Vielleicht mein absoluter Lieblings-CSS-Trick aller Zeiten! Dieser nutzt vier überlagerte Hintergrund-Gradienten, die Schatten am oberen und unteren Rand von Containern enthüllen, wenn diese gescrollt werden. Das signalisiert dem Nutzer, dass er in diese Richtung scrollen kann. Es ist einfach gute UX, und das heute mehr denn je, da Benutzeroberflächen ohne sichtbare Scrollbalken seit der Erfindung des Tricks im Jahr 2012 immer häufiger geworden sind.
Die Idee von Scroll-Schatten ergibt absolut Sinn. Wenn ein Container nach unten gescrollt wird, sieht man oben einen Schatten, der verdeutlicht, dass man wieder hochscrollen kann. Und wenn es möglich ist, weiter nach unten zu scrollen, gibt es auch dort einen Schatten – es sei denn, man ist bereits ganz unten angekommen.
Dies könnte tatsächlich mein Lieblings-CSS-Trick überhaupt sein. Die Idee stammt ursprünglich von Roman Komarov, aber Lea Verou entwickelte die raffinierte CSS-Spielerei dazu und machte sie populär.
Scroll-Schatten bieten eine so angenehme UX, dass man sich fast fragt, warum sie keine native Browser-Funktion sind oder zumindest einfacher mit CSS umzusetzen. Man könnte sie als Affordanz bezeichnen: ein offensichtlicher visueller Hinweis, der ohne Lernaufwand zeigt, ob Scrollen möglich oder abgeschlossen ist.
Hier ist ein funktionierendes Beispiel
So sieht es aus: Wenn man nach unten scrollen kann, erscheint dort ein Schatten, der darauf hinweist. Wenn man in beide Richtungen scrollen kann, gibt es Schatten oben und unten. Kann man nur nach oben scrollen, ist der Schatten nur oben sichtbar.



Es ist ein wenig knifflig zu verstehen, wie es funktioniert, unter anderem weil es background-attachment: local; nutzt – eine Eigenschaft, die man, gelinde gesagt, eher selten verwendet. Hier ein Erklärungsversuch:
- Hier sind zwei Arten von Schatten am Werk:
- Reguläre Schatten
- Abdeck-Schatten (Cover shadows)
- Alle Schatten werden mit Hintergrund-Gradienten erzeugt. Zum Beispiel ein nicht wiederholender
radial-gradient, der so dimensioniert und oben in der Mitte des Elements platziert ist, dass er wie ein Schatten aussieht. - Die Abdeck-Schatten werden durch die Stapelreihenfolge (Stacking Order) von mehreren Hintergründen über den regulären Schatten platziert und sind in der Lage, diese vollständig zu verdecken.
- Die regulären Schatten verwenden den Standardwert von
background-attachment, nämlichscroll. Das kennen Sie wahrscheinlich, da Hintergründe normalerweise so funktionieren, ohne dass man groß darüber nachdenkt: Die Hintergründe sind einfach da, im sichtbaren Bereich des Elements positioniert, und bewegen sich nicht mit, wenn der Inhalt des Elements gescrollt wird. - Die Überlauf-Schatten verwenden das ungewöhnliche
background-attachment: local;, welches sie an den oberen und unteren Rand des Elements setzt, wobei die gesamte Scroll-Höhe des Elements berücksichtigt wird. Sie bewegen sich mit der Scroll-Position des Elements mit.
Stellen Sie sich folgendes Szenario vor: Das Element hat einen vertikalen Überlauf und ist aktuell ganz nach oben gescrollt. Sowohl der obere Schatten als auch seine Abdeckung befinden sich oben am Element. Die Abdeckung liegt obenauf und verbirgt den Schatten so, als wäre er gar nicht da. Scrollen Sie ein wenig nach unten, bleibt die Abdeckung am allerersten Anfang des Elements haften (der nun durch den Überlauf verborgen ist), sodass man die Abdeckung nicht mehr sieht und der Schatten zum Vorschein kommt. Am unteren Ende konnten Sie den Schatten die ganze Zeit sehen, weil die Abdeckung am untersten Ende des Elements haftet und der Schatten am unteren Rand des sichtbaren Bereichs fixiert ist. Scrollen Sie ganz nach unten, überlagert die Abdeckung den unteren Schatten und verbirgt ihn. Das klingt kompliziert, aber es funktioniert einwandfrei!
Das Schöne daran ist, dass man nur ein paar Zeilen Code auf ein einzelnes Element anwenden muss, um das Ergebnis zu erzielen.
.scroll-shadows {
max-height: 200px;
overflow: auto;
background:
/* Shadow Cover TOP */
linear-gradient(
white 30%,
rgba(255, 255, 255, 0)
) center top,
/* Shadow Cover BOTTOM */
linear-gradient(
rgba(255, 255, 255, 0),
white 70%
) center bottom,
/* Shadow TOP */
radial-gradient(
farthest-side at 50% 0,
rgba(0, 0, 0, 0.2),
rgba(0, 0, 0, 0)
) center top,
/* Shadow BOTTOM */
radial-gradient(
farthest-side at 50% 100%,
rgba(0, 0, 0, 0.2),
rgba(0, 0, 0, 0)
) center bottom;
background-repeat: no-repeat;
background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
background-attachment: local, local, scroll, scroll;
}
Es muss übrigens nicht nur auf weißen Hintergründen funktionieren, aber es muss eine flache Farbe (Flat Color) sein.
Hier ist eine Version, bei der die Farben in CSS-Variablen (Custom Properties) ausgelagert sind
Dies kann weit mehr als nur eine nette UI/UX-Spielerei sein; es kann entscheidend sein, um anzuzeigen, dass ein Container mehr Inhalt hat, wenn dieser keinen Scrollbalken oder andere UI-Elemente besitzt. Denken Sie an den Artikel Perfectly Cropped von Tyler Hall, in dem er beschreibt, wie verwirrt seine Familienmitglieder über das Share-Panel in iOS 13 waren. Es ist in diesem Screenshot absolut nicht offensichtlich, dass man hier nach unten scrollen kann.
Andere Tricks
Vielleicht könnte der Schatten größer oder stärker sein, je nachdem, wie viel noch zu scrollen ist?
Hakim El Hattab twitterte einmal ein Beispiel dazu, das dies hervorragend demonstrierte.
Beachten Sie hier die Schatten entlang der linken Seitenleiste:



Beachten Sie, dass diese Demo ein wenig JavaScript verwendet. Natürlich reizt mich die reine CSS-Version mehr, besonders hier, da sie so einfach auf ein einzelnes Element anzuwenden ist. Aber es gibt viele Ansätze mit JavaScript, wie zum Beispiel:
- Dieses Beispiel, das die Schatten je nach Bedarf einfügt und ein- bzw. ausblendet.
- Dieses Beispiel mit React Hooks.
- Dieses Beispiel, das die Intersection Observer API nutzt.
Trotz meiner Vorliebe für die reine CSS-Lösung gibt es einen weiteren Grund, warum man stattdessen zu einer JavaScript-basierten Lösung greifen sollte: iOS Safari. Seit der Veröffentlichung von iOS 13 im Juni 2019 funktioniert diese Technik in der dortigen Safari-Version (und allen folgenden) nicht mehr. Ich bin mir ehrlich gesagt nicht zu 100 % sicher, warum. Es wirkt wie ein Bug. Es ging zur gleichen Zeit kaputt, als auch die cleveren reinen CSS-Parallax-Techniken in iOS Safari scheiterten. Es könnte damit zusammenhängen, wie der Browser bestimmte gerenderte Ebenen von Websites „cached“. Es wäre wirklich schön, wenn Apple das beheben würde.