Verwendung von Container-Scroll-State-Abfragen
Container-Scroll-State-Abfragen sind eine Art von Container-Abfragen. Anstatt Stile basierend auf der Größe des Containers selektiv auf Nachfahrenelemente anzuwenden, ermöglichen es Scroll-State-Abfragen, Stile basierend auf dem Scrollzustand des Containers selektiv auf Nachfahrenelemente anzuwenden. Dies kann beinhalten, ob der Container teilweise gescrollt wird, an einen Scroll-Snap-Container Vorfahren eingerastet ist oder über position: sticky positioniert und an eine Begrenzung eines Scroll-Containers Vorfahren angedockt ist.
Dieser Artikel erklärt, wie Sie Container-Scroll-State-Abfragen verwenden, indem er ein Beispiel für jeden Typ durchgeht. Es wird davon ausgegangen, dass Sie die Grundlagen von Container-Abfragen kennen. Wenn Sie neu in Container-Abfragen sind, lesen Sie CSS Container-Abfragen, bevor Sie fortfahren.
Arten von Container-Scroll-State-Abfragen
Es gibt drei @container Deskriptoren, die Sie in einer scroll-state() Abfrage verwenden können:
scrollable: Fragt, ob ein Container in die angegebene Richtung durch benutzerinitiiertes Scrollen gescrollt werden kann (zum Beispiel durch Ziehen des Scrollbalkens oder mit einer Trackpad-Geste). Mit anderen Worten, gibt es überfließenden Inhalt in der angegebenen Richtung, zu dem gescrollt werden kann? Dies ist nützlich, um Stile zu anzuwenden, die sich auf die Scrollposition eines Scroll-Containers beziehen. Zum Beispiel könnten Sie einen Hinweis anzeigen, der die Leute ermutigt, nach unten zu scrollen, um mehr Inhalt zu sehen, wenn der Scrollbalken oben ist, und ihn ausblenden, wenn der Benutzer tatsächlich mit dem Scrollen begonnen hat.scrolled: Fragt, ob ein Container zuletzt in die angegebene Richtung gescrollt wurde. Dies ermöglicht es Ihnen, Stile basierend auf der Scrollrichtung des Benutzers selektiv anzuwenden, zum Beispiel eine obere Menüleiste, die nur angezeigt wird, wenn der Benutzer nach oben scrollt.snapped: Fragt, ob ein Container an einen Scroll-Snap Container Vorfahren entlang einer angegebenen Achse eingerastet wird. Dies ist nützlich, um Stile anzuwenden, wenn ein Element an einen Scroll-Snap-Container eingerastet ist. Zum Beispiel möchten Sie das eingerastete Element auf irgendeine Weise hervorheben oder einen zuvor versteckten Inhalt enthüllen.stuck: Fragt, ob ein Container mit einempositionWert vonstickyan einer Kante seines Scroll-Container Vorfahren klebt. Dies ist nützlich, umposition: stickyElemente unterschiedlich zu gestalten, wenn sie kleben — zum Beispiel könnten Sie ihnen ein anderes Farbschema oder Layout geben.
Übersicht über die Syntax
Um ein Containerelement als Scroll-State-Abfragecontainer zu etablieren, setzen Sie die container-type Eigenschaft darauf mit einem Wert von scroll-state. Sie können ihm optional auch einen container-name geben, sodass Sie ihn mit einer spezifischen Container-Abfrage anvisieren können:
.container {
container-type: scroll-state;
container-name: my-container;
}
Sie können dann einen @container Block erstellen, der die Abfrage, die Regeln, die auf Kinder des Containers angewendet werden, wenn der Test besteht, und optional den container-name der Container, die Sie abfragen möchten, angibt. Wenn Sie keinen container-name angeben, wird die Container-Abfrage für alle Scroll-State-Abfragecontainer auf der Seite angewendet.
Hier fragen wir nur Container mit dem Namen my-container ab, um festzustellen, ob der Container in Richtung seiner oberen Kante gescrollt werden kann:
@container my-container scroll-state(scrollable: top) {
/* CSS rules go here */
}
Hinweis:
Um Scroll-State-Abfragen von anderen Container-Abfragen zu trennen, werden die Scroll-State-Deskriptoren und Werte in Klammern gesetzt, vorangestellt von scroll-state (scroll-state( ... )). Diese Konstrukte sehen aus wie Funktionen, sind es aber nicht.
Verwendung von scrollable Abfragen
Scroll-State scrollable Abfragen, geschrieben als scroll-state(scrollable: <keyword>), testen, ob ein Container-Vorfahren in der angegebenen Richtung durch benutzerinitiiertes Scrollen gescrollt werden kann. Wenn nicht, gibt die Abfrage false zurück.
Der Schlüsselwortwert gibt die Richtung an, für die Sie die Verfügbarkeit des Scrolling testen, zum Beispiel:
top: Testet, ob der Container in Richtung seiner oberen Kante gescrollt werden kann.inline-end: Testet, ob der Container in Richtung seiner inline-end Kante gescrollt werden kann.y: Testet, ob der Container in eine oder beide Richtungen entlang seiner y-Achse gescrollt werden kann.
Wenn der Test besteht, werden die Regeln innerhalb des @container Blocks auf Nachfahren des passenden Scroll-Containers angewendet.
Schauen wir uns ein Beispiel an, in dem wir einen Scroll-Container voller Inhalt haben und einen praktischen kleinen Link, um bei Bedarf wieder nach oben zu scrollen. Wir verwenden eine scrollable Abfrage, um den Link nur anzuzeigen, wenn der Benutzer begonnen hat, den Inhalt herunterzuscrollen.
HTML
Im HTML haben wir ein <article> Element, das genug Inhalt enthält, um das Dokument zu scrollen, vorangestellt von einem Zurück-zum-Anfang-Link:
<a class="back-to-top" href="#" aria-label="Top of page">↑</a>
<article>
<h1>Reader with container query-controlled "back-to-top" link</h1>
<section>
<header>
<h2>This first section is interesting</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</header>
...
</section>
...
</article>
Wir haben den größten Teil des HTML zur Kürze ausgeblendet.
CSS
Dem .back-to-top Link wird ein position Wert von fixed zugewiesen, er wird in der unteren rechten Ecke des Viewports platziert und mittels eines translate Werts von 80px 0 aus dem Viewport verschoben. Ein transition Wert animiert das translate und die background-color, wenn sich einer der Werte ändert.
.back-to-top {
width: 64px;
height: 64px;
color: white;
text-align: center;
position: fixed;
bottom: 10px;
right: 10px;
translate: 80px 0;
transition:
0.4s translate,
0.2s background-color;
}
Der Scroll-Container in diesem Beispiel ist das <html> Element selbst, das als Scroll-State-Abfragecontainer mit einem container-type Wert von scroll-state gekennzeichnet ist. Der container-name ist nicht unbedingt notwendig, aber nützlich in Fällen, in denen der Code in einen Codebestand mit mehreren Scroll-State-Abfragecontainern, die mit unterschiedlichen Abfragen angesprochen werden, eingefügt wird.
html {
container-type: scroll-state;
container-name: scroller;
}
Als nächstes definieren wir einen @container Block, der den Container-Namen festlegt, der von dieser Abfrage anvisiert wird, und die Abfrage selbst — scrollable: top. Diese Abfrage wendet die Regeln innerhalb des Blocks nur dann an, wenn das <html> Element in Richtung seiner oberen Kante gescrollt werden kann — mit anderen Worten, wenn der Container zuvor nach unten gescrollt wurde. Ist das der Fall, wird translate: 0 0 auf den .back-to-top Link angewendet, der ihn zurück auf den Bildschirm verschiebt.
@container scroller scroll-state(scrollable: top) {
.back-to-top {
translate: 0 0;
}
}
Wir haben den Rest des Beispiel-CSS zur Kürze ausgeblendet.
Ergebnis
Versuchen Sie, das Dokument herunterzuscrollen, und beachten Sie, wie der "Zurück-zum-Anfang" Link erscheint und aufgrund des transition sanft von der rechten Seite des Viewports animiert wird. Wenn Sie durch Aktivieren des Links oder manuelles Scrollen wieder nach oben scrollen, wird der "Zurück-zum-Anfang" Link wieder aus dem Bildschirm verschoben.
Verwendung von scrolled Abfragen
Scroll-State scrolled Abfragen, geschrieben als scroll-state(scrolled: <keyword>), testen, ob ein Container-Vorfahren zuletzt in die angegebene Richtung gescrollt wurde. Wenn nicht, gibt die Abfrage false zurück.
Der Schlüsselwortwert gibt die Richtung an, die Sie testen. Zum Beispiel:
block-start: Testet, ob der Container zuletzt in Richtung seiner block-start Kante gescrollt wurde.right: Testet, ob der Container zuletzt in Richtung seiner rechten Kante gescrollt wurde.y: Testet, ob der Container zuletzt nach oben oder unten entlang der y-Achse gescrollt wurde.none: Testet, ob der Container kein Scroll-Container ist oder seit dem Rendern nicht in irgendeine Richtung gescrollt wurde.
Wenn der Test true zurückgibt, werden die Regeln innerhalb des @container Blocks auf die Nachfahren des passenden Scroll-Containers angewendet.
Schauen wir uns ein Beispiel eines Scroll-Containers mit einer scrolled Abfrage an, die obere und untere Inhalts-"Leisten" nur dann anzeigt, wenn der Benutzer nach oben oder unten scrollt.
HTML
In unserem HTML haben wir ein <article> Element mit genügend Inhalt, um das Dokument zu scrollen, vorangestellt von zwei <div> Elementen, die unsere oberen und unteren "Leisten" darstellen:
<div class="bar" id="top-bar">You're currently scrolling towards the top.</div>
<div class="bar" id="bottom-bar">
You're currently scrolling towards the bottom.
</div>
<article>
<h1>Document with scrolled container query</h1>
<section>
<header>
<h2>This first section is interesting</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</header>
...
</section>
...
</article>
Wir haben den größten Teil des HTML zur Kürze ausgeblendet.
CSS
Den "Leisten" wird ein grundlegendes Styling zugewiesen. Am bedeutendsten wird ihnen ein position Wert von fixed zugewiesen, den wir mithilfe von left und right Werten von beiden Seiten versetzen.
.bar {
border-radius: 10px;
border: 1px solid #000;
background-color: #0009;
padding: 10px;
color: white;
text-shadow: 1px 1px 1px black;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 5px;
right: 5px;
}
Als nächstes setzen wir negative top und bottom Längenwerte auf die oberen und unteren Leisten, damit sie standardmäßig oberhalb und unterhalb des Viewports verborgen sind. Wir fügen ein transition hinzu, damit sie sanft animiert eingeblendet werden, wenn sich ihre translate Werte ändern.
#top-bar {
top: -50px;
transition: 0.6s translate;
}
#bottom-bar {
bottom: -50px;
transition: 0.6s translate;
}
Der Scroll-Container in diesem Beispiel ist das <html> Element selbst, das als Scroll-State-Abfragecontainer mit einem container-type Wert von scroll-state gekennzeichnet ist. Der container-name ist nicht unbedingt notwendig, aber es ist nützlich, wenn ein Codebestand mehrere Scroll-State-Abfragecontainer hat, die mit unterschiedlichen Abfragen angesprochen werden.
html {
container-type: scroll-state;
container-name: scroller;
}
Als nächstes definieren wir zwei @container Blöcke, die beide den scroller Container-Namen anvisieren. Der erste Block definiert eine Abfrage scrolled: block-end und der zweite definiert eine Abfrage scrolled: block-start. Diese Abfragen wenden die Regeln in ihrem Block nur an, wenn das <html> Element zuletzt in Richtung seiner block-end-Kante oder block-start-Kante gescrollt wurde. Mit anderen Worten, wenn der Container nach unten oder oben gescrollt wird. Wenn eine der Bedingungen wahr wird, hat die im Block referenzierte Leiste einen translate Wert, der sie auf den Bildschirm verschiebt. Die im @condition referenzierte Leiste, die nicht mehr wahr ist, wird aus dem Bildschirm heraus verschoben.
@container scroller scroll-state(scrolled: block-start) {
#top-bar {
translate: 0 55px;
}
}
@container scroller scroll-state(scrolled: block-end) {
#bottom-bar {
translate: 0 -55px;
}
}
Wir haben den Rest des Beispiel-CSS zur Kürze ausgeblendet.
Ergebnis
Versuchen Sie, das Dokument nach oben und unten zu scrollen, und beachten Sie, wie die verschiedenen Leisten als Ergebnis erscheinen und sanft auf- und abgleiten.
Verwendung von snapped Abfragen
Nur relevant, wenn Scroll-Snapping implementiert ist, testen Scroll-State snapped Abfragen, geschrieben als scroll-state(snapped: <keyword>), ob ein Container entlang der angegebenen Achse an einen Scroll-Snap-Container Vorfahren eingerastet werden soll. Wenn nicht, gibt die Abfrage false zurück.
Der Schlüsselwortwert gibt in diesem Fall die Richtung an, in der Sie die Fähigkeit des Elements, einzurasten, testen, zum Beispiel:
x: Testet, ob der Container horizontal an seinen Scroll-Snap-Container-Vorfahren einrastet.inline: Testet, ob der Container an seinen Scroll-Snap-Container-Vorfahren in der Inline-Richtung einrastet.y: Testet, ob der Container in beide Richtungen an seinen Scroll-Snap-Container-Vorfahren einrastet.
Um einen Container mit einer nicht-none snapped Scroll-State-Abfrage zu bewerten, muss es sich um einen Container mit einem Scroll-Snap-Container-Vorfahren handeln, das heißt, der Vorfahre hat einen scroll-snap-type Wert ungleich none. Die Container-Abfrage scroll-state(snapped: none) passt auf Scroll-State-Container, die keinen Scroll-Container-Vorfahren haben.
Die Bewertung erfolgt, wenn das scrollsnapchanging Ereignis am Scroll-Snap-Container ausgelöst wird.
Wenn der Test besteht, werden die Regeln innerhalb des @container Blocks auf Nachfahren des passenden Scroll-Snap-Zielcontainers angewendet.
In diesem Beispiel betrachten wir einen Scroll-Snap-Container mit Kindern, die vertikal an ihn einrasten, und verwenden eine snapped Abfrage, um die Kinder nur dann zu stylen, wenn sie eingerastet oder im Begriff sind, eingerastet zu werden.
HTML
Das HTML besteht aus einem <main> Element, das ein Scroll-Snap-Container sein wird. Darin befinden sich mehrere <section> Elemente, die Snap-Ziele sein werden. Jedes <section> enthält einen Wrapper <div> und eine <h2> Überschrift. Die Wrapper sind enthalten, um ein Stilziel zu schaffen, da Container-Abfragen das Stylen von Nachfahren eines Containers ermöglichen, nicht des Containers selbst.
<main>
<section>
<div class="wrapper">
<h2>Section 1</h2>
</div>
</section>
...
</main>
Wir haben den größten Teil des HTML zur Kürze ausgeblendet.
CSS
Wir setzen einen overflow Wert von scroll und eine feste height auf das <main> Element, um es in einen vertikalen Scroll-Container zu verwandeln. Wir setzen auch einen scroll-snap-type Wert von y mandatory, um <main> in einen Scroll-Snap-Container zu verwandeln, zu dem Snap-Ziele entlang der y-Achse einrasten werden; mandatory bedeutet, dass ein Snap-Ziel immer eingerastet wird.
main {
overflow: scroll;
scroll-snap-type: y mandatory;
height: 450px;
width: 250px;
border: 3px solid black;
}
Die <section> Elemente werden durch Setzen eines scroll-snap-align Werts ungleich none als Snap-Ziele bezeichnet. Der center Wert bedeutet, dass sie an ihrem Mittelpunkt an den Container einrasten.
section {
font-family: "Helvetica", "Arial", sans-serif;
width: 150px;
height: 150px;
margin: 50px auto;
scroll-snap-align: center;
}
Wir möchten die <section> Elemente abfragbar machen. Insbesondere möchten wir testen, ob die <section> Elemente gerade dabei sind, an ihren Container einzurasten, also kennzeichnen wir sie als Scroll-State-Abfragecontainer, indem wir einen container-type Wert von scroll-state darauf setzen. Wir geben ihnen auch einen container-name, was nicht unbedingt notwendig ist, aber nützlich wird, wenn unser Code später komplexer wird und wir mehrere Scroll-State-Abfragecontainer haben, die wir mit unterschiedlichen Abfragen anvisieren möchten.
section {
container-type: scroll-state;
container-name: snap-container;
}
Als nächstes definieren wir einen @container Block, der den Container-Namen festlegt, den wir mit dieser Abfrage anvisieren, und die Abfrage selbst — snapped: y. Diese Abfrage wendet die Regeln innerhalb des Blocks nur an, wenn ein <section> Element vertikal an seinen Container einrastet. Wenn das der Fall ist, wenden wir einen neuen background und color auf die .wrapper <div> an, um es hervorzuheben.
@container snap-container scroll-state(snapped: y) {
.wrapper {
background: purple;
color: white;
}
}
Ergebnis
Das gerenderte Ergebnis ist unten gezeigt. Versuchen Sie, den Container nach oben und unten zu scrollen, und beachten Sie, wie sich der Stil des <section> ändert, wenn es an seinen Container eingerastet wird.
Verwendung von stuck Abfragen
Scroll-State stuck Abfragen, geschrieben als scroll-state(stuck: <keyword>), testen, ob ein Container mit einem position Wert von sticky an einer Kante seines Scroll-Container Vorfahren klebt. Wenn nicht, gibt die Abfrage false zurück.
Der Schlüsselwortwert in diesem Fall gibt die Kante des Scroll-Containers an, die Sie testen, zum Beispiel:
top: Testet, ob der Container an der oberen Kante seines Scroll-Container Vorfahren klebt.block-end: Testet, ob der Container an der block-end Kante seines Scroll-Container Vorfahren klebt.none: Testet, ob der Container an keiner Kante seines Scroll-Container Vorfahren klebt. Beachten Sie, dassnoneAbfragen auch zutreffen, wenn der Container nichtposition: stickygesetzt hat.
Wenn die Abfrage true zurückgibt, werden die Regeln im @container Block auf die Nachfahren des passenden position: sticky Containers angewendet.
Schauen wir uns ein Beispiel an, bei dem wir einen Scroll-Container mit überlaufendem Inhalt haben, in dem die Überschriften auf position: sticky gesetzt sind und an der oberen Kante des Containers haften, wenn sie dorthin gescrollt werden. Wir verwenden eine stuck Scroll-State-Abfrage, um die Überschriften anders zu stylen, wenn sie an der oberen Kante haften.
HTML
Im HTML haben wir ein <article> Element mit genug Inhalt, um das Dokument zu scrollen. Es ist strukturiert mit mehreren <section> Elementen, die jeweils eine <header> mit verschachteltem Inhalt enthalten:
<article>
<h1>Sticky reader with scroll-state container query</h1>
<section>
<header>
<h2>This first section is interesting</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</header>
...
</section>
<section>
<header>
<h2>This one, not so much</h2>
<p>Confecta res esset.</p>
</header>
...
</section>
...
</article>
Wir haben den größten Teil des HTML zur Kürze ausgeblendet.
CSS
Jedes <header> hat einen position Wert von sticky und einen top Wert von 0, was sie an die obere Kante des Scroll-Containers anheftet. Um zu testen, ob die <header> Elemente an der oberen Kante des Containers haften, werden sie als Scroll-State-Abfragecontainer mit einem container-type Wert von scroll-state gekennzeichnet. Der container-name ist nicht unbedingt notwendig, aber nützlich, wenn dieser Code in einen Codebestand mit mehreren Scroll-State-Abfragecontainern eingefügt wird, die mit unterschiedlichen Abfragen anvisiert werden.
header {
background: white;
position: sticky;
top: 0;
container-type: scroll-state;
container-name: sticky-heading;
}
Wir geben auch den <h2> und <p> Elementen innerhalb der <header> Elemente ein grundlegendes Styling und einen transition Wert, damit sie sanft animieren, wenn sich ihre background Werte ändern.
h2,
header p {
margin: 0;
transition: 0.4s background;
}
h2 {
padding: 20px 5px;
margin-bottom: 10px;
}
header p {
font-style: italic;
padding: 10px 5px;
}
Als nächstes definieren wir einen @container Block, der den Container-Namen festlegt, den wir mit dieser Abfrage anvisieren, und die Abfrage selbst — stuck: top. Diese Abfrage wendet die Regeln innerhalb des Blocks nur an, wenn ein <header> Element an der oberen Kante seines Scroll-Containers klebt. Wenn das der Fall ist, wird ein anderer background und ein box-shadow auf die enthaltenen <h2> und <p> angewendet.
@container sticky-heading scroll-state(stuck: top) {
h2,
p {
background: #cccccc;
box-shadow: 0 5px 2px #00000077;
}
}
Wir haben den Rest des CSS zur Kürze ausgeblendet.
Ergebnis
Versuchen Sie, das Dokument nach unten und oben zu scrollen, und beachten Sie, wie die <h2> und <p> Elemente in ein neues Farbschema übergehen, wenn sie an der oberen Kante ihres Containers kleben.