Verwendung von Container-Scroll-State-Abfragen

Container-Scroll-State-Abfragen sind eine Art von Container-Abfrage. Anstatt Styles selektiv auf nachfolgende Elemente basierend auf der Größe des Containers anzuwenden, ermöglichen es Scroll-State-Abfragen, Styles basierend auf dem Scroll-Zustand des Containers anzuwenden. Dies kann beinhalten, ob der Container teilweise gescrollt ist, an einen Vorfahren, der als Scroll-Snap-Container definiert ist, eingerastet ist, oder über position: sticky positioniert ist und an einer Grenze eines Vorfahren-Containers, der als Scroll-Container definiert ist, haftet.

Dieser Artikel erklärt, wie man Container-Scroll-State-Abfragen verwendet, indem er ein Beispiel für jeden Typ durchläuft. Es wird vorausgesetzt, dass Sie die Grundlagen von Container-Abfragen kennen. Wenn Sie neu in Bezug auf 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 ab, ob ein Container in die gegebene Richtung durch benutzerinitiiertes Scrollen (z. B. durch Ziehen des Scrollbalkens oder eine Trackpad-Geste) gescrollt werden kann. Mit anderen Worten, gibt es überlaufenden Inhalt in der gegebenen Richtung, der gescrollt werden kann? Dies ist nützlich, um Styling in Bezug auf die Scroll-Position eines Scroll-Containers anzuwenden. Zum Beispiel könnten Sie einen Hinweis anzeigen, der Personen ermutigt, nach unten zu scrollen und mehr Inhalt zu sehen, wenn der Scrollbalken oben ist, und diesen Hinweis verbergen, wenn der Benutzer tatsächlich mit dem Scrollen begonnen hat.
  • snapped: Fragt ab, ob ein Container an einen Scroll-Snap Container-Vorfahren entlang einer gegebenen Achse eingerastet ist oder wird. Dies ist nützlich, um Styles anzuwenden, wenn ein Element an einen Scroll-Snap-Container eingerastet ist. Beispielsweise könnten Sie ein eingerastetes Element auf eine bestimmte Weise hervorheben oder einige seiner zuvor verborgenen Inhalte enthüllen.
  • stuck: Fragt ab, ob ein Container mit einem position Wert von sticky an eine Kante seines Scroll-Container-Vorfahren haftet. Dies ist nützlich, um position: sticky Elemente anders zu stylen, wenn sie haften — zum Beispiel könnten Sie ihnen ein anderes Farbschema oder Layout geben.

Überblick über die Syntax

Um ein Container-Element als eine Scroll-State-Abfrage für Container festzulegen, 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 es mit einer spezifischen Container-Abfrage ansprechen können:

css
.container {
  container-type: scroll-state;
  container-name: my-container;
}

Sie können dann einen @container Block erstellen, der die Abfrage spezifiziert, die Regeln, die auf die Kinder des Containers angewendet werden, wenn der Test erfolgreich ist, und optional, den container-name der Container(s), die Sie abfragen möchten. Wenn Sie keinen container-name angeben, wird die Container-Abfrage auf alle Scroll-State-Query-Container auf der Seite angewendet.

Hier fragen wir nur Container mit dem Namen my-container ab, um zu bestimmen, ob der Container in Richtung seiner oberen Kante gescrollt werden kann:

css
@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: value), testen, ob ein Container in der angegebenen Richtung durch benutzerinitiiertes Scrollen gescrollt werden kann. Ist dies nicht der Fall, gibt die Abfrage false zurück.

Der value gibt die Richtung an, in die Sie die Verfügbarkeit des Scrollens 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 erfolgreich ist, werden die Regeln im @container Block auf Nachkommen des passenden Scroll-Containers angewendet.

Schauen wir uns ein Beispiel an, in dem wir einen Scroll-Container voller Inhalte haben und einen praktischen kleinen Link, um bei Bedarf zum Anfang zurückzuscrollen. Wir werden eine scrollable Abfrage verwenden, um den Link nur dann anzuzeigen, wenn der Benutzer begonnen hat, durch den Inhalt nach unten zu scrollen.

HTML

Im HTML haben wir ein <article> Element, das genügend Inhalt enthält, um das Dokument zum Scrollen zu bringen, vorangestellt von einem Back-to-Top-Link:

html
<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 Großteil des HTML der Kürze halber versteckt.

CSS

Der .back-to-top Link erhält einen position Wert von fixed, platziert in der unteren rechten Ecke des Viewports, und wird mit einem translate Wert von 80px 0 aus dem Viewport verschoben. Ein transition Wert animiert das translate und die background-color, wenn sich einer der Werte ändert.

css
.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-Abfrage-Container mit einem container-type Wert von scroll-state bezeichnet wird. Der container-name ist nicht unbedingt erforderlich, aber nützlich in Fällen, in denen der Code zu einer Codebasis mit mehreren Scroll-State-Abfrage-Controllern hinzugefügt wird, die mit verschiedenen Abfragen gezielt werden.

css
html {
  container-type: scroll-state;
  container-name: scroller;
}

Als nächstes definieren wir einen @container Block, der den Container-Namen setzt, der mit dieser Abfrage gezielt wird, und die Abfrage selbst — scrollable: top. Diese Abfrage wendet die innerhalb des Blocks enthaltenen Regeln nur an, wenn das <html> Element in Richtung seiner oberen Kante gescrollt werden kann — mit anderen Worten, wenn der Container vorher nach unten gescrollt wurde. Ist das der Fall, wird translate: 0 0 auf den .back-to-top Link angewendet, wodurch er wieder auf dem Bildschirm angezeigt wird.

css
@container scroller scroll-state(scrollable: top) {
  .back-to-top {
    translate: 0 0;
  }
}

Wir haben den Rest des Beispiel-CSS der Kürze halber versteckt.

Ergebnis

Versuchen Sie, das Dokument nach unten zu scrollen, und beachten Sie, wie der "back-to-top" Link als Ergebnis erscheint, indem er sanft von der rechten Seite des Viewports aufgrund der transition animiert wird. Wenn Sie wieder nach oben scrollen, indem Sie den Link aktivieren oder manuell scrollen, wird der "back-to-top" Link vom Bildschirm weg bewegt.

Verwendung von snapped Abfragen

Relevant nur, wenn Scroll-Snapping implementiert ist, testen Scroll-State snapped Abfragen (geschrieben als scroll-state(snapped: value)), ob ein Container an einen Scroll-Snap-Container Vorfahren entlang der angegebenen Achse eingerastet ist oder wird. Ist dies nicht der Fall, gibt die Abfrage false zurück.

Der value gibt in diesem Fall die Richtung an, in der Sie die Fähigkeit des Elements zum Einrasten 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 Inline-Richtung einrastet.
  • y: Testet, ob der Container an seinen Scroll-Snap-Container-Vorfahren in beide Richtungen einrastet.

Um einen Container mit einer nicht-none snapped Scroll-State-Abfrage zu bewerten, muss es ein Container mit einem Scroll-Snap-Container-Vorfahren sein, das heißt, der Vorfahren hat einen scroll-snap-type Wert, der nicht none ist. Die Container-Abfrage scroll-state(snapped: none) entspricht Scroll-State-Controllern, die keinen Scroll-Container-Vorfahren haben.

Die Bewertung erfolgt, wenn das scrollsnapchanging Ereignis am Scroll-Snap-Container ausgelöst wird.

Wenn der Test erfolgreich ist, werden die Regeln im @container Block auf Nachkommen des passenden Scroll-Snap-Zielcontainers angewendet.

In diesem Beispiel schauen wir uns einen Scroll-Snap-Container mit Kindern an, die vertikal daran einrasten, und verwenden eine snapped Abfrage, um die Kinder nur dann zu stylen, wenn sie eingerastet sind oder dabei sind, eingerastet zu werden.

HTML

Das HTML besteht aus einem <main> Element, das ein Scroll-Snap-Container sein wird. Im Inneren sind 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 ermöglichen, die Nachkommen eines Containers zu stylen, nicht den Container selbst.

html
<main>
  <section>
    <div class="wrapper">
      <h2>Section 1</h2>
    </div>
  </section>

  ...
</main>

Wir haben den Großteil des HTML der Kürze halber versteckt.

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, an den Snap-Ziele entlang der y-Achse einrasten; mandatory bedeutet, dass ein Snap-Ziel immer eingerastet wird.

css
main {
  overflow: scroll;
  scroll-snap-type: y mandatory;
  height: 450px;
  width: 250px;
  border: 3px solid black;
}

Die <section> Elemente sind durch Setzen eines nicht-none scroll-snap-align Wertes als Snap-Ziele definiert. Der Wert center bedeutet, dass sie in der Mitte der Container einrasten werden.

css
section {
  font-family: Arial, Helvetica, sans-serif;
  width: 150px;
  height: 150px;
  margin: 50px auto;

  scroll-snap-align: center;
}

Wir wollen die Möglichkeit, die <section> Elemente zu abfragen. Genauer gesagt, wollen wir testen, ob die <section> Elemente an ihren Container einrasten, daher bezeichnen wir sie als Scroll-State-Abfrage-Container, indem wir einen container-type Wert von scroll-state auf sie setzen. Wir geben ihnen auch einen container-name, der nicht unbedingt notwendig ist, aber nützlich ist, wenn unser Code später komplexer wird und wir mehrere Scroll-State-Abfrage-Container haben, die wir mit verschiedenen Abfragen ansprechen wollen.

css
section {
  container-type: scroll-state;
  container-name: snap-container;
}

Als nächstes definieren wir einen @container Block, das den Container-Namen festlegt, den wir mit dieser Abfrage abfragen, und die Abfrage selbst — snapped: y. Diese Abfrage wendet die Regeln nur dann an, wenn ein <section> Element vertikal an seinen Container einrastet. Ist dies der Fall, wenden wir einen neuen background und color auf das .wrapper <div> Kind des <section> Elements an, um es hervorzuheben.

css
@container snap-container scroll-state(snapped: y) {
  .wrapper {
    background: purple;
    color: white;
  }
}

Ergebnis

Das gerenderte Ergebnis wird unten gezeigt. Versuchen Sie den Container nach oben und unten zu scrollen und beachten Sie, wie sich der <section> Stil ändert, wenn er an seinen Container einrastet.

Verwendung von stuck Abfragen

Scroll-State stuck Abfragen, geschrieben als scroll-state(stuck: value), testen, ob ein Container mit einem position Wert von sticky an einer Kante seines Scroll-Container-Vorfahren haftet. Ist dies nicht der Fall, gibt die Abfrage false zurück.

Der value in diesem Fall zeigt die Scroll-Container-Kante an, die Sie testen möchten, zum Beispiel:

  • top: Testet, ob der Container an der oberen Kante seines Scroll-Container-Vorfahren haftet.
  • block-end: Testet, ob der Container an der Blockend-Kante seines Scroll-Container-Vorfahren haftet.
  • none: Testet, ob der Container an keiner Kante seines Scroll-Container-Vorfahren haftet. Beachten Sie, dass none Abfragen auch dann zutreffen, wenn der Container nicht position: sticky eingestellt hat.

Wenn die Abfrage true zurückgibt, werden die Regeln im @container Block auf Nachkommen 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 diese Position erreichen. Wir werden eine stuck Scroll-State-Abfrage verwenden, um die Überschriften anders zu stylen, wenn sie an der oberen Kante haften.

HTML

Im HTML haben wir ein <article> Element, das genügend Inhalt enthält, um das Dokument zum Scrollen zu bringen. Es ist in mehreren <section> Elementen strukturiert, die jeweils einen <header> mit verschachtelten Inhalten enthalten:

html
<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 Großteil des HTML der Kürze halber versteckt.

CSS

Jeder <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 obersten Kante des Containers haften, sind sie als Scroll-State-Abfrage-Container mit einem container-type Wert von scroll-state gekennzeichnet. Der container-name ist nicht unbedingt erforderlich, kann aber nützlich sein, wenn dieser Code zu einer Codebasis mit mehreren Scroll-State-Abfrage-Controllern hinzugefügt wird, die mit unterschiedlichen Abfragen gezielt werden.

css
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, sodass sie sanft animiert werden, wenn sich ihre background Werte ändern.

css
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 ansprechen, und die Abfrage selbst — stuck: top. Diese Abfrage wendet die enthaltenen Regeln nur an, wenn ein <header> Element an der oberen Kante seines Scroll-Containers haftet. Wenn das der Fall ist, wird ein anderer background und ein box-shadow auf die enthaltenen <h2> und <p> angewendet.

css
@container sticky-heading scroll-state(stuck: top) {
  h2,
  p {
    background: #ccc;
    box-shadow: 0 5px 2px #0007;
  }
}

Wir haben den Rest des CSS der Kürze halber versteckt.

Ergebnis

Versuchen Sie, das Dokument nach unten und oben zu scrollen und beachten Sie, wie die <h2> und <p> Elemente in ein neues Farbschema wechseln, wenn sie an die obere Kante ihres Containers haften.

Siehe auch