Ähnlich wie Containerabfragen, aber für steckengebliebene, eingefrorene und überlaufende Abfragen.
Veröffentlicht: 15. Januar 2025
In Chrome 133 werden Containerabfragen um Scrollstatus-Containerabfragen erweitert. Der vom Browser verwaltete Status für die anpinnende Positionierung, Scroll-Snap-Punkte und scrollbare Elemente kann jetzt über CSS abgefragt und angepasst werden.
Übersicht
Vor Abfragen zum Scrollstatus mussten Sie JavaScript verwenden, um herauszufinden, ob ein Element feststeckt, angedockt oder scrollbar ist. Jetzt gibt es eine leistungsstärkere Methode im Standards-Track, um diese Informationen zu erhalten und entsprechend anzupassen. Außerdem gibt es eine neue Möglichkeit, Animationen auszulösen. So können Sie jetzt auch scrollen-ausgelöste Animationen über CSS erstellen.
Hier finden Sie eine Übersicht über die Statusabfragen, die ab Chrome 133 verfügbar sind:
- Festhängender Zustand:
- Der Triggerstil ändert sich, wenn ein Element an einer Kante angedockt ist.
- Angedockter Zustand:
- Stiländerungen auslösen, wenn ein Element an einer Achse angedockt ist.
- Scrollbarer Zustand:
- Triggerstil ändert sich, wenn ein Element überläuft.
Die gute Nachricht ist, dass alles, was Sie über Containerabfragen gelernt haben, auch für Abfragen zum Scrollstatus hilfreich ist.
Außerdem gibt es noch viel zu entdecken zwischen scrollbasierten Animationen und Scroll-Status-Containerabfragen. Wir müssen mit dem Timing und dem Kontext experimentieren, um herauszufinden, ob eine scrollbasierte Animation oder eine scrollgetriggerte Scroll-Status-Animation am besten geeignet ist. Das folgende Video und die Demo veranschaulichen das Problem: eine von Sticky-Elementen ausgelöste Animation im Vergleich zu einer scrollgesteuerten Animation.
Erste Abfrage zum Scrollstatus
Im ersten Schritt definieren Sie den Container mit einem neuen Wert für das container-type
-Attribut. Wie bei einer Containerabfrage geben Sie dem Element, das Sie abfragen möchten, die container-type
und optional eine container-name
. Bei Abfragen zum Scrollstatus geben Sie das Element an, das angedockt, hängengeblieben oder übergelaufen ist container-type: scroll-state
.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
}
Im zweiten Schritt wählen Sie das untergeordnete Element dieses Containers aus, das auf den Status reagieren soll. Bei Containerabfragen kann dies nicht dasselbe Element sein, das die container-type
enthält.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
Der dritte Schritt besteht darin, es auszuprobieren. Im folgenden CSS-Beispiel wird der Hintergrund rot, wenn das .stuck-top
-Element bei 0
oben bleibt. Mit einigen zusätzlichen Zeilen im CSS, die wir bereits geschrieben hätten, und einem zusätzlichen enthaltenden Element, das den Browserstatus als Proxy verwendet, sind unsere Komponenten viel intelligenter in Bezug auf ihre Umgebung.
Progressive Verbesserung
Mit dem Attribut- und Nesting-Befehl @supports
können Sie mit nur wenigen zusätzlichen Codezeilen progressive Verbesserungen oder die bedingte Verwendung von Funktionen hinzufügen:
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
@supports (container-type: scroll-state) {
> nav {
@container scroll-state(stuck: top) {
background: Highlight;
color: HighlightText;
}
}
}
}
Denke auch daran, @media (prefers-reduced-motion: no-preference) {}
um die Bewegung herum zu verwenden, wenn du Elemente auf der Seite mit Scrollstatusabfragen animierst.
Anwendungsfälle
Stockend
Vielleicht sollte dieser Abschnitt „Heikle Situationen“ heißen? Dies ist eine kleine Sammlung von Anwendungsfällen für den Sticky-Status sowie ein Bonusbereich mit Ideen, die umgesetzt werden müssen.
@container scroll-state(stuck: top) {}
@container scroll-state(stuck: bottom) {}
Schatten hinzufügen, wenn das Gerät feststeckt
Einer der häufigsten Anwendungsfälle für eine steckengebliebene Abfrage ist bei Navigationsleisten, bei denen box-shadow
hinzugefügt werden soll, wenn sie steckengeblieben sind, damit sie über den Inhalten schweben, die sie überlagern.
.stuck-top {
container-type: scroll-state;
position: sticky;
top: 0px;
> nav {
transition: box-shadow .3s ease;
@container scroll-state(stuck: top) {
box-shadow: var(--shadow-5);
}
}
}
Aktuell steckengebliebenen Header aktivieren
Ein weiteres häufiges Szenario für Haftnotizen in der Benutzeroberfläche ist das Hervorheben des aktuell hängenden Elements. In einer alphabetisch sortierten Liste kann das sehr hilfreich sein.
.sticky-slide {
dt {
container-type: scroll-state;
position: sticky;
inset-block-start: 0;
inset-inline: 0;
> header {
transition:
background .3s ease,
box-shadow .5s ease;
@container scroll-state(stuck: top) {
background: hsl(265 100% 27%);
box-shadow: 0 5px 5px #0003;
}
}
}
}
Hier sehen Sie eine weitere Variante, bei der die Überschriften seitlich neben den Listenelementen angezeigt werden. Es gibt viele Möglichkeiten!
Ideen-Overflow
Hier finden Sie eine Liste von Sticky-Demos, die Sie dazu inspirieren könnten, die Demo mit Abfragen zum Scrollstatus etwas aufzupeppen oder das JavaScript zu entfernen. Ich schlage vor, dass Sie einen Code erstellen, der Ihnen gefällt. So bleiben die Syntax und die Ideen besser in Erinnerung. 😏
- https://codepen.io/BlogFire/pen/PoGMjaX – Variante mit Haftnotizen
- https://codepen.io/mikegolus/pen/jOZzRzw – Schatten zu einer Tabelle hinzufügen, wenn sie herausragt
- https://codepen.io/MarcRay/pen/PomBeP – unter der Kopfzeile wird die Navigationsleiste beim Trigger angezeigt
- https://codepen.io/kevinpowell/pen/OqKJjK – Fußzeilennavigationsleiste, die sich enthüllt
- https://codepen.io/abhisekz-the-decoder/pen/eKaLRd – fixierte Kartenüberschriften
- https://codepen.io/tutsplus/pen/abojPjP – Schatten der Preisüberschrift beim Trigger
- https://codepen.io/kevinpowell/pen/KEjMEv – Titel der Seitenleiste für fixierte Abschnitte
Angedockt
Mit Abfrageaufträgen für den angepinnten Zustand können wir einen Teil der Verantwortung von JavaScript und Snap-Ereignissen auf CSS übertragen.
@container scroll-state(snapped: x) {}
@container scroll-state(snapped: y) {}
@container scroll-state(snapped: inline) {}
@container scroll-state(snapped: block) {}
Zur Erinnerung: Falls Sie den Abschnitt Erste Abfrage zum Scrollstatus übersprungen haben, ist das Element mit scroll-snap-align
der Container für eine Snap-Abfrage. Das Element, das sich anpassen kann, muss ein untergeordnetes Element dieses Elements sein. Für die Einrichtung sind also drei Elemente erforderlich:
a scroll container with `scroll-snap-type`
⤷ a snap target with both `scroll-snap-align` and `container-type: scroll-state`
⤷ a child of the snap target that can query the container for snap state
Angedocktes Element optisch hervorheben
Bei einem scrollbaren Element, das in der Mitte fixiert ist, wird das Element in der Mitte häufig hervorgehoben oder präsentiert. In diesem Beispiel für Erfahrungsberichte wird das Keyword not
verwendet, sodass alle nicht angepinnten Erfahrungsberichte eine geringe Deckkraft haben, während die angepinnten Erfahrungsberichte in ihrem natürlichen Präsentationsstatus bleiben.
.demo {
overflow: auto hidden;
scroll-snap-type: x mandatory;
> article {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
> * {
transition: opacity .5s ease;
@container not scroll-state(snapped: x) {
opacity: .25;
}
}
}
}
}
Untertitel für das angepinnte Element anzeigen
Das ist ein gutes Beispiel dafür, wie durch Abfragen des Scrollstatus eine scroll-ausgelöste Animation ermöglicht wird. Es ist auch ein gutes Beispiel dafür, wann die Vermeidung von überflüssigen Bewegungen im CSS sinnvoll ist.
.demo {
overflow-x: auto;
scroll-behavior-x: contain;
scroll-snap-type: x mandatory;
> .card {
container-type: scroll-state;
scroll-snap-align: center;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
figcaption {
transform: translateY(100%);
@container scroll-state(snapped: x) {
transform: translateY(0);
}
}
}
}
}
}
Folienelemente animieren
Es ist sehr üblich, Elemente einer Präsentation zu animieren, wenn Sie einen Vortrag halten. Früher war es ziemlich mühsam, einen IntersectionObserver dafür zu schreiben, der nur eine Klasse auf der Folie festlegte. Jetzt benötigen wir kein JavaScript mehr.
html {
scroll-snap-type: y mandatory;
}
section {
container-type: scroll-state;
scroll-snap-align: start;
scroll-snap-stop: always;
@supports (container-type: scroll-state) {
@media (prefers-reduced-motion: no-preference) {
> h1 {
transition: opacity .5s ease, transform .5s var(--ease-spring-3);
transition-delay: .5s;
opacity: 0;
transform: scale(1.25);
@container scroll-state(snapped: block) {
opacity: 1;
transform: scale(1);
}
}
}
}
}
Sie werden feststellen, dass sich alle an den CSS-Status angedockten Abfragen wie scrollsnapchanging
und nicht wie scrollsnapchange
verhalten. So erhalten Sie so früh wie möglich visuelles Feedback zum angedockten Element. Wenn das zu früh ist, sollten Sie das JavaScript-Ereignis verwenden.
Scrollbar
Die Abfrage für den scrollbaren Status ist sehr hilfreich, um visuelle Hinweise zu geben, wann ein scrollbarer Bereich tatsächlich gescrollt werden kann. Bis zu den Abfragen zum Scrollstatus war es schwierig, diese Informationen zu erhalten.
@container scroll-state(scrollable: top) {}
@container scroll-state(scrollable: right) {}
@container scroll-state(scrollable: bottom) {}
@container scroll-state(scrollable: left) {}
Scrollen mit Schatten anzeigen
Es gibt einen berühmten CSS-Trick von Lea Verou, bei dem mit background-attachment: local
ein ähnlicher Effekt erzielt wird, sowie eine Möglichkeit, dies mit einer Scroll-Animation zu tun. Jede Methode hat Vor- und Nachteile. Es liegt an uns, herauszufinden, wann und wo jede dieser Methoden am besten geeignet ist.
Im folgenden Beispiel wird ein einzelnes fixiertes Element verwendet, das den Scrollbereich überspannt. Die Deckkraft eines Farbverlaufs oben und eines unten wird mit @property
animiert, wenn die Abfrage für den kontextbezogenen Scrollstatus @container scroll-state(scrollable: top)
angewendet wird.
Beachten Sie auch, dass es sich um den ersten Container handelt, der sowohl ein size
- als auch ein scroll-state
-Container ist.
.scroll-container {
container-type: scroll-state size;
overflow: auto;
&::after {
content: " ";
background: var(--_shadow-top), var(--_shadow-bottom);
transition:
--_scroll-shadow-color-1-opacity .5s ease,
--_scroll-shadow-color-2-opacity .5s ease;
@container scroll-state(scrollable: top) {
--_scroll-shadow-color-1-opacity: var(--_shadow-color-opacity, 25%);
}
@container scroll-state(scrollable: bottom) {
--_scroll-shadow-color-2-opacity: var(--_shadow-color-opacity, 25%);
}
}
}
Prompt mit Pfeil
Manchmal kann ein Pfeil Nutzern helfen zu erkennen, dass ein Bereich scrollbar ist. Sie zeigen in der Regel in die Richtung, in die gescrollt werden kann, und verschwinden, sobald sie nicht mehr benötigt werden. Dazu können Sie den folgenden Code verwenden.
@container scroll-state((scrollable: top) or (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
}
@container scroll-state((scrollable: top) and (not (scrollable: bottom))) {
translate: 0 calc(100% + 10px);
rotate: .5turn;
}
Zurück zum Seitenanfang
Eine weitere beliebte Interaktion mit dem Scrollstatus ist die praktische Schaltfläche „Nach oben scrollen“. Mit dem folgenden Code wird die Schaltfläche „An den Anfang scrollen“ ausgeblendet, wenn nicht nach oben gescrollt werden kann.
Diese Lösung ist etwas unkonventionell, ermöglicht es aber, die Menge an CSS zu reduzieren. Die Schaltfläche sollte immer sichtbar sein. Sie müssen also festlegen, dass sie ausgeblendet wird, wenn nicht mehr nach oben gescrollt werden kann.
@container not scroll-state(scrollable: top) {
translate: 0 calc(100% + 10px);
}
Weiterführende Studien
Wenn Sie mehr dazu erfahren möchten, finden Sie hier einige Ressourcen, die von Spezifikationsdetails bis hin zu anderen interessanten Artikeln zu diesem Thema reichen:
- Was sollten wir sonst noch in Containern abfragen können? https://github.com/w3c/csswg-drafts/issues/5989
- Erläuterung zu scroll-state() – https://drafts.csswg.org/css-conditional-5/scroll_state_explainer.md
- CSS-Spezifikation für „scroll-state()“ – https://www.w3.org/TR/css-conditional-5/#scroll-state-container
- Layout-Snapshots in der HTML-Ereignisschleife
- Podcastfolge zu Statusabfragen: https://nerdy.dev/the-css-podcast-on-state-queries
- Weitere Artikel
- https://utilitybend.com/blog/is-the-sticky-thing-stuck-is-the-snappy-item-snapped-a-look-at-state-queries-in-css/
- https://ishadeed.com/article/css-state-queries/
- https://csscade.com/can-you-detect-overflow-with-css/
- https://css-tip.com/overflow-detection/ – Erkennung mit scrollgetriebener Animation, die nicht nur für Kinder erkennbar ist (mit dem Nachteil, dass es sich um eine Täuschung handelt)