Verwendung von Container-Scroll-Zustandsabfragen

Container-Scroll-Zustandsabfragen sind eine Art von Container-Abfragen. Anstatt Stile abhängig von der Größe des Containers selektiv auf Nachbarelemente anzuwenden, ermöglichen Scroll-Zustandsabfragen die selektive Anwendung von Stilen auf Nachbarelemente basierend auf dem Scroll-Zustand des Containers. Dies kann beinhalten, ob der Container teilweise gescrollt, an einen Scroll Snap Container Vorfahren angeheftet oder über position: sticky positioniert und an eine Grenze eines Scroll Containers Vorfahren angeheftet ist.

Dieser Artikel erklärt, wie Container-Scroll-Zustandsabfragen verwendet werden, und führt durch ein Beispiel für jeden Typ. Es wird vorausgesetzt, dass Sie die Grundlagen von Container-Abfragen kennen. Wenn Sie neu bei Container-Abfragen sind, lesen Sie CSS-Container-Abfragen, bevor Sie fortfahren.

Arten von Container-Scroll-Zustandsabfragen

Es gibt drei @container Deskriptoren, die Sie in einer scroll-state() Abfrage verwenden können:

  • scrollable: Abfragt, ob ein Container in die gegebene Richtung durch benutzerinitiierte Scroll-Aktionen scrollbar ist (zum Beispiel durch Ziehen des Scrollbalkens oder eine Trackpad-Geste). Mit anderen Worten: Gibt es überlaufenden Inhalt in der gegebenen Richtung, zu dem gescrollt werden kann? Dies ist nützlich, um Stile im Zusammenhang mit der Scrollposition eines Scroll-Containers zu applizieren. Zum Beispiel könnten Sie einen Hinweis anzeigen, der Benutzer dazu ermutigt, nach unten zu scrollen und mehr Inhalte zu sehen, wenn der Scrollbalken oben ist, und ihn ausblenden, wenn der Benutzer tatsächlich begonnen hat zu scrollen.
  • snapped: Abfragt, ob ein Container an einen Scroll Snap Container-Vorfahren entlang einer gegebenen Achse geheftet ist oder sein wird. Dies ist nützlich für das Anwenden von Stilen, wenn ein Element an einen Scroll-Snap-Container geheftet ist. Beispielsweise könnten Sie ein geheftetes Element in irgendeiner Weise hervorheben oder einige seiner zuvor versteckten Inhalte sichtbar machen.
  • stuck: Abfragt, ob ein Container mit einem position Wert von sticky an einer Kante seines Scroll-Containers-Vorfahren feststeckt. Dies ist nützlich für das Styling von position: sticky Elementen, wenn sie feststecken – z. B. könnten Sie ihnen ein anderes Farbschema oder Layout geben.

Überblick über die Syntax

Um ein Containerelement als Scroll-Zustandsabfragecontainer zu etablieren, setzen Sie die Eigenschaft container-type mit dem Wert scroll-state darauf. Sie können ihm optional auch einen container-name geben, sodass Sie ihn 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, die Sie abfragen möchten. Wenn Sie keinen container-name angeben, wird die Container-Abfrage auf alle Scroll-Zustandsabfragecontainer 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-Zustandsabfragen von anderen Container-Abfragen zu trennen, werden die Scroll-Zustands-Deskriptoren und -Werte in Klammern gesetzt, vorangestellt durch scroll-state (scroll-state( ... )). Diese Konstrukte sehen wie Funktionen aus, sind es jedoch nicht.

Verwendung von scrollable Abfragen

Scroll-Zustands-scrollable Abfragen, geschrieben als scroll-state(scrollable: value), testen, ob ein Container-Vorfahre in die gegebene Richtung durch benutzerinitiierte Scrollaktionen gescrollt werden kann. Wenn nicht, gibt die Abfrage false zurück.

Der value gibt an, in welcher Richtung Sie die Scrollverfügbarkeit 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 Nachfahren des passenden Scroll-Containers angewendet.

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

HTML

Im HTML haben wir ein <article>-Element mit genug Inhalt, um das Dokument zum Scrollen zu bringen, vorausgehend von einem Zurück-zur-Spitze-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 das meiste HTML der Kürze halber verborgen.

CSS

Der .back-to-top Link erhält einen position Wert von fixed, wird unten rechts in der Ansicht platzieren und mit einem translate Wert von 80px 0 aus der Ansicht verschoben. Ein transition Wert wird die translate und background-color animieren, 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, als Scroll-Zustandsabfragecontainer mit einem container-type-Wert von scroll-state gekennzeichnet. Der container-name ist nicht unbedingt erforderlich, aber nützlich in Fällen, in denen der Code zu einer Codebasis hinzugefügt wird, die mehrere gezielte Scroll-Zustandsabfragecontainer mit unterschiedlichen Abfragen enthält.

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

Als nächstes definieren wir einen @container Block, der den Containernamen festlegt, der durch diese Abfrage angesprochen wird, sowie die Abfrage selbst — scrollable: top. Diese Abfrage wendet die Regeln im Block nur dann an, wenn das <html> Element an seiner oberen Kante gescrollt werden kann — mit anderen Worten, wenn der Container zuvor nach unten gescrollt wurde. Ist dies der Fall, wird translate: 0 0 auf den .back-to-top-Link angewendet, welcher ihn wieder auf den Bildschirm zurückbringt.

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

Wir haben den restlichen Beispiel-CSS der Kürze halber verborgen.

Ergebnis

Versuchen Sie, das Dokument nach unten zu scrollen, und bemerken Sie, wie der "Zurück-zur-Spitze"-Link als Ergebnis erscheint und sanft von der rechten Seite der Ansicht animiert wird, bedingt durch den transition. Wenn Sie zurück zum Anfang scrollen, indem Sie den Link aktivieren oder manuell scrollen, wird der "Zurück-zur-Spitze"-Link aus dem Bildschirm heraus animiert.

Verwendung von snapped Abfragen

Nur relevant, wenn Scroll-Snap implementiert ist, testen Scroll-Zustands-snapped Abfragen (geschrieben als scroll-state(snapped: value)) ob ein Container ist oder wird, an einen Scroll-Snap-Container Vorfahr entlang der gegebenen Achse geheftet. Gibt false zurück, wenn nicht.

Der value gibt in diesem Fall die Richtung an, in der Sie die Fähigkeit des Elements zum Snap testen, zum Beispiel:

  • x: Testet, ob der Container horizontal zu seinem Scroll-Snap-Container-Vorfahren snappt.
  • inline: Testet, ob der Container in Inline-Richtung zu seinem Scroll-Snap-Container-Vorfahren snappt.
  • y: Testet, ob der Container in beide Richtungen zu seinem Scroll-Snap-Container-Vorfahren snappt.

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

Die Evaluation erfolgt, wenn das scrollsnapchanging Ereignis auf dem Scroll-Snap-Container ausgelöst wird.

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

In diesem Beispiel werden wir uns einen Scroll-Snap-Container mit Kindern ansehen, die vertikal zu ihm snap und eine snapped-Abfrage verwenden, um die Kinder nur dann zu stylen, wenn sie gesnapped oder kurz davor sind, gesnapped zu werden.

HTML

Das HTML besteht aus einem <main>-Element, das ein Scroll-Snap-Container wird. Darin sind mehrere <section>-Elemente enthalten, 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 Styling von Nachfahren eines Containers ermöglichen, nicht des Containers selbst.

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

  ...
</main>

Wir haben das meiste HTML der Kürze halber verborgen.

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 gesnapped werden; mandatory bedeutet, dass ein Snap-Ziel immer gesnapped wird.

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

Die <section> Elemente werden als Snap-Ziele durch Setzen eines nicht-none scroll-snap-align Werts bezeichnet. Der center Wert bedeutet, dass sie an ihr Zentrumspunkt an den Container gesnapped werden.

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

  scroll-snap-align: center;
}

Wir möchten die <section> Elemente abfragbar machen. Genauer gesagt möchten wir testen, ob die <section> Elemente zu ihrem Container snappen, daher kennzeichnen wir sie als Scroll-Zustandsabfragecontainer, indem wir ihnen einen container-type Wert von scroll-state geben. Wir geben ihnen auch einen container-name, welcher nicht unbedingt erforderlich ist, aber nützlich sein wird, wenn unser Code später komplexer wird und wir mehrere gezielte Scroll-Zustandsabfragecontainer mit unterschiedlichen Abfragen haben.

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

Als nächstes definieren wir einen @container-Block, der den Containernamen festlegt, den wir mit dieser Abfrage ansprechen, und die Abfrage selbst — snapped: y. Diese Abfrage wendet die Regeln im Block nur dann an, wenn ein <section>-Element vertikal zu seinem Container snappen angesetzt ist. Wenn das der Fall ist, wenden wir einen neuen background und color auf das Kind <div> der <section>-Elemente an, um es hervorzuheben.

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

Ergebnis

Das gerenderte Ergebnis sehen Sie unten. Versuchen Sie, den Container nach oben und unten zu scrollen, und bemerken Sie, wie sich der Stil des <section> Elements ändert, wenn es zu seinem Container gesnapped wird.

Verwendung von stuck Abfragen

Scroll-Zustands-stuck Abfragen, geschrieben als scroll-state(stuck: value), testen, ob ein Container mit einem position Wert von sticky an einer Kante seines Scroll-Containers-Vorfahren feststeckt. Wenn nicht, gibt die Abfrage false zurück.

Der value gibt in diesem Fall die Kante des Scroll-Containers an, die getestet wird, beispielsweise:

  • top: Testet, ob der Container an der oberen Kante seines Scroll-Container-Vorfahren feststeckt.
  • block-end: Testet, ob der Container an der Block-End-Kante seines Scroll-Container-Vorfahren feststeckt.
  • none: Testet, ob der Container an keiner Kante seines Scroll-Container-Vorfahren feststeckt. Beachten Sie, dass none Abfragen auch dann übereinstimmen, wenn der Container position: sticky nicht gesetzt hat.

Wenn die Abfrage true zurückgibt, werden die Regeln innerhalb des @container-Blocks auf die Nachfahren des passenden position: sticky-Containers angewendet.

Schauen wir uns ein Beispiel an, in dem wir einen scrollenden Container mit überlaufenden Inhalten haben, in dem die Überschriften auf position: sticky gesetzt sind und an der oberen Kante des Containers festkleben, wenn sie auf diese Position scrollen. Wir werden eine stuck-Scroll-Zustandsabfrage verwenden, um die Überschriften anders zu stylen, wenn sie an der oberen Kante feststecken.

HTML

Im HTML haben wir ein <article> Element mit genug Inhalt, um das Dokument zum Scrollen zu bringen. Es ist mit mehreren <section> Elementen strukturiert, die jeweils ein <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 das meiste HTML der Kürze halber verborgen.

CSS

Jedes <header> hat einen position Wert von sticky und einen top Wert von 0, was sie an der oberen Kante des Scroll-Containers festkleben lässt. Um zu testen, ob die <header> Elemente an der oberen Kante des Containers festkleben, sind sie als Scroll-Zustandsabfragecontainer mit einem container-type Wert von scroll-state gekennzeichnet. Der container-name ist nicht zwingend erforderlich, aber nützlich, wenn dieser Code zu einer Codebasis mit mehreren gezielten Scroll-Zustandsabfragecontainern mit unterschiedlichen Abfragen hinzugefügt wird.

css
header {
  background: white;
  position: sticky;
  top: 0;
  container-type: scroll-state;
  container-name: sticky-heading;
}

Wir geben den <h2> und <p> Elementen innerhalb der <header> Elemente auch ein grundlegendes Styling und einen transition Wert, sodass sie sanft animieren, 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 Containernamen festlegt, den wir mit dieser Abfrage ansprechen, und die Abfrage selbst — stuck: top. Diese Abfrage wendet die Regeln im Block nur dann an, wenn ein <header> Element an der oberen Kante seines Scroll-Containers feststeckt. In diesem Fall werden ein anderer background und ein box-shadow auf das enthaltene <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 restlichen CSS der Kürze halber verborgen.

Ergebnis

Versuchen Sie, das Dokument nach unten und oben zu scrollen, und bemerken Sie, wie die <h2> und <p> Elemente zu einem neuen Farbschema übergehen, wenn sie an der oberen Kante ihres Containers feststecken.

Siehe auch