:has()

Avatar of Mojtaba Seyedi
Mojtaba Seyedi am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Die CSS-Pseudo-Klasse :has() wählt Elemente aus, die andere Elemente enthalten, die mit dem in den Argumenten übergebenen Selektor übereinstimmen. Sie wird oft als „Elternselektor“ bezeichnet, da sie ein Elternelement basierend auf den darin enthaltenen Kindelementen auswählen und Stile auf das Elternelement anwenden kann.

/* Select the .card element when it 
   contains a <figure> immediately
   followed by a paragraph. */
.card:has(figure + p) {
  flex-direction: row;
}

Dieses Beispiel wählt ein Element mit der Klasse .card aus, wenn es ein <figure>-Element enthält, dem unmittelbar ein <p>-Element folgt.

<article class="card">
  <figure></figure>
  <p></p>
</article>

Dies ist unglaublich nützlich, um Stile für Komponenten zu schreiben, die bestimmte Elemente enthalten oder auch nicht enthalten können, wie z. B. ein Kartenraster, bei dem ein Kartenelement immer einen Absatz hat, aber möglicherweise kein dazugehöriges Bild.

Bild oder kein Bild? Das ist die Frage.

Auf diese Weise können Sie in Situationen, in denen Sie nicht immer wissen, was das Markup enthält, dennoch Stile schreiben, die diesen Bedingungen entsprechen.

:has() ist in der Speifikation für Selektoren Level 4 definiert, wo es als „relationaler Pseudo-Selektor“ beschrieben wird, da es Selektoren basierend auf der Beziehung eines Elements zu anderen Elementen abgleichen kann.

Grundlegende Verwendung

Das folgende HTML enthält zwei <button> -Elemente. Eines davon hat ein SVG-Symbol.

<!-- Plain button -->
<button>Add</button>

<!-- Button with SVG icon -->
<button>
  <svg></svg>
  Add
</button>

Nehmen wir nun an, Sie möchten nur den <button> mit einem <svg> -Element darin formatieren.

:has() ist perfekt dafür geeignet.

button:has(svg) {
  /* Styles */
}

Der :has() -Selektor gibt uns die Möglichkeit, zwischen einem Button, der einen <svg>-Nachfahren hat, und einem, der keinen hat, zu unterscheiden.

Syntax

:has( <unforgiving-relative-selector-list> )

Eine unansehnliche Selektorliste bezieht sich auf die Argumente, die den Argumenten des :has()-Selektors übergeben werden, welche eine durch Kommas getrennte Liste von Elementen ist, die gemeinsam basierend auf ihrer Beziehung zum Elternelement ausgewertet werden.

article:has(ol, ul) {
  /* Matches an <article> that contains either
     an ordered or unordered list. */
}

Wir werden die „unansehnliche“ Natur der Argumentliste im Detail aufschlüsseln.

Spezifität

Einer der interessanteren Aspekte von :has() ist, dass seine Spezifität durch das spezifischste Element in seiner Argumentliste bestimmt wird. Nehmen wir die folgenden Stilregeln an:

article:has(.some-class, #id, img) {
  background: #000;
}

article .some-class {
  background: #fff;
}

Wir haben zwei Regeln, die beide ein <article>-Element auswählen, um seinen Hintergrund zu ändern. Welchen Hintergrund bekommt dieses HTML?

<article class="some-class">
  <div class="some-class"></div>
</article>

Sie denken vielleicht, es bekommt einen weißen (#fff) Hintergrund, weil er später in der Kaskade kommt. Da die Argumentliste für :has() jedoch andere Selektoren enthält, müssen wir den spezifischsten in der Liste betrachten, um die tatsächliche Spezifität der ersten Regel zu bestimmen. Das wäre in diesem Fall #id.

Lassen Sie uns sie vergleichen.

  • article .some-class generiert eine Punktzahl von (0,1,1).
  • article:has(.some-class, #id, img) generiert eine Punktzahl von (1,0,1).

Die erste Regel gewinnt! Das Element erhält einen schwarzen (#000) Hintergrund.

Quiz!

Welche Farbe gewinnt Ihrer Meinung nach im folgenden Beispiel?

article:has(h1, .title) a { 
  color: red; 
}

article h1 a {
  color: green;
}
Zeigen Sie mir die Antwort!
/* Specificity: (0,1,2) */
article:has(h1, .title) a {
  color: red; /* 🏆 Winner! */
}

/* Specificity: (0,0,3) */
article h1 a {
  color: green;
}

:has() ist ein „unansehnlicher“ Selektor.

Der erste Entwurf der Spezifikationen führte :has() als „nachgiebigen Selektor“ ein.

:has( <forgiving-relative-selector-list> )

Die Idee war, dass eine Liste einen ungültigen Selektor enthalten und ihn ignorieren könnte.

/* Example: Do not use! */
article:has(h2, ul, ::-scoobydoo) { }

::-scoobydoo ist ein komplett erfundener ungültiger Pseudo-Element-Selektor, der nicht existiert. Wenn :has() „nachgiebig“ wäre, würde dieser fehlerhafte Selektor einfach ignoriert werden, während der Rest der Argumente normal geparst wird.

Später, aufgrund eines Konflikts mit dem Verhalten von jQuery, entschieden die Spezifikationsautoren, :has() als nicht-nachgiebigen Selektor zu definieren. Infolgedessen sind :is() und :where() die einzigen nachgiebigen relationalen Selektoren der Gruppe.

Das bedeutet, dass :has() sich viel mehr wie ein zusammengesetzter Selektor verhält. Laut CSS-Spezifikationen ist das allgemeine Verhalten eines zusammengesetzten Selektors aus historischen Gründen, dass wenn ein Selektor in der Liste ungültig ist, die gesamte Selektorliste ungültig ist, was dazu führt, dass der gesamte Regelblock verworfen wird.

/* This doesn't do anything because `::-scoobydoo`
   is an invalid selector */
a, a::-scoobydoo {
  color: green;
}

Dasselbe gilt für :has(). Jeder ungültige Selektor in seiner Argumentliste macht alles andere in der Liste ungültig. Also, das Beispiel, das wir uns zuvor angesehen haben,

/* Example: Do not use! */
article:has(h2, ul, ::-scoobydoo) { }

… wird gar nichts bewirken. Alle drei Selektoren in der Argumentliste sind aufgrund des ungültigen ::scoobydoo-Selektors ungültig. Es ist eine Alles-oder-Nichts-Sache.

Aber es gibt eine Art Umgehungslösung dafür. Denken Sie daran, :is() und :where() sind nachgiebig, auch wenn :has() es nicht ist. Das bedeutet, wir können einen dieser Selektoren in :has() verschachteln, um ein nachgiebigeres Verhalten zu erzielen.

p:has(:where(a, a::scoobydoo)) {
  color: green;
}

Wenn Sie also jemals möchten, dass :has() als „nachgiebiger“ Selektor fungiert, versuchen Sie, :is() oder :where() darin zu verschachteln.

Die Argumentliste akzeptiert komplexe Selektoren.

Ein komplexer Selektor enthält einen oder mehrere zusammengesetzte Selektoren (z. B. a.fancy-link) und Kombinatoren (z. B. >+~). Die Argumentliste für :has() akzeptiert diese komplexen Selektoren und kann verwendet werden, um Beziehungen zwischen mehreren Elementen zu identifizieren.

<relative-selector> = <combinator>? <complex-selector>

Hier ist ein Beispiel für einen relationalen Selektor, der einen komplexen Selektor mit dem Kindselektor (>) enthält. Er wählt Elemente mit der Klasse .icon aus, die direkte Kinder von Links mit der Klasse .fancy-link sind und sich im :focus-Zustand befinden.

a.fancy-link:focus > .icon {
  /* Styles */
}

So etwas kann direkt in die :has()-Argumentliste eingefügt werden.

p:has(a.fancy-link:focus > .icon) {
  /* Styles */
}

Aber anstatt .icon-Elemente auszuwählen, die direkte Kinder von .fancy-class-Links sind, die sich im :focus-Zustand befinden, formatieren wir Absätze, die fokussierte .fancy-links mit direkten Kindern haben, die die Klasse .icon besitzen.

Puh, versuchen Sie mal, das dreimal schnell zu sagen! Vielleicht hilft es, ein Markup-Beispiel zu sehen, das passt.

Es unterstützt im Allgemeinen keine Pseudo-Selektoren.

Ich sage, dass :has() andere Pseudo-Elemente in seinen Argumenten „im Allgemeinen“ nicht unterstützt, weil genau das in der Spezifikation steht.

Hinweis: Pseudo-Elemente sind im Allgemeinen von :has() ausgeschlossen, da viele von ihnen bedingt existieren, basierend auf der Formatierung ihrer Vorfahren. Das Zulassen, dass diese von :has() abgefragt werden, würde Zyklen einführen.

Es gibt tatsächlich ein paar „has-allowed Pseudo-Elemente“, die in der :has()-Argumentliste zulässig sind. Die Spezifikation bietet das folgende Beispiel, das zeigt, wie :not() neben :has() verwendet wird.

/* Matches any <section> element that contains 
   anything that’s not a heading element. */
section:has(:not(h1, h2, h3, h4, h5, h6))

Jhey Tompkins bietet ein weiteres Beispiel, das zeigt, wie :has() verwendet werden kann, um Formulare basierend auf verschiedenen Eingabezuständen wie :valid, :invalid und :placeholder-shown zu formatieren.

label {
  color: var(--color);
}
input {
  border: 4px solid var(--color);
}

.form-group:has(:invalid) {
  --color: var(--invalid);
}

.form-group:has(:focus) {
  --color: var(--focus);
}

.form-group:has(:valid) {
  --color: var(--valid);
}

.form-group:has(:placeholder-shown) {
  --color: var(--blur);
}

Es kann sich nicht selbst verschachteln, aber es unterstützt Verketten.

Entschuldigung, es gibt kein Verschachteln von :has() innerhalb von :has(), wie z.B.:

/* Nesting is a no-go */
.header-group:has(.subtitle:has(h2)) {
  /* Invalid! */
}

Das würde eine Endlosschleife erzeugen, bei der die Spezifität innerhalb einer anderen Auswertung ausgewertet wird. Es erlaubt Ihnen jedoch, Argumente zu verketten.

h2,
.subtitle {
  margin-block-end: 1.5rem;
}

/* Reduce spacing on header because the subtitle will handle it */
.header-group:has(h2):has(.subtitle) h2 {
  margin-block-end: 0.2rem;
}

Verketten funktioniert wie die logische UND-Operation, bei der beide Bedingungen übereinstimmen müssen, damit die Stilregel wirksam wird. Angenommen, Sie haben eine Liste von .news-articles und die darin enthaltenen Artikel sind kategorisiert. Vielleicht möchten Sie bestimmte Stile auf die Liste anwenden, aber nur, wenn sie Artikel mit .breaking-news und Artikel mit .featured-news enthält, sie aber unverändert lassen, wenn nur einer oder keiner der Artikel diesen Klassen entspricht.

Nun, Sie können zwei :has()-Deklarationen für diese bedingte Formatierung verketten.

.news-list:has(.featured-news):has(.breaking-news) { 
  /* Styles */ 
}

Dieses Beispiel ist spezifisch für den Container .news-list. Wenn wir ein beliebiges übergeordnetes Element abgleichen wollten, das sowohl .featured-news als auch .breaking-news als Artikelklassen :has(), könnten wir .news-list ganz weglassen.

:has(.featured-news):has(.breaking-news) { 
  /* Styles */ 
}

Es ist mehr als ein „Eltern“-Selektor.

Jhey Thompkins nennt ihn den „Familien“-Selektor, was vielleicht eine passendere Beschreibung ist, insbesondere im Hinblick auf das letzte Beispiel, das wir betrachtet haben. Betrachten wir es noch einmal.

.header-group:has(h2):has(.subtitle) h2 {
  margin-block-end: 0.2rem;
}

Wir wählen nicht nur ein Element mit der Klasse .header-group aus, das ein <h2>-Element enthält. Das sind die Eltern-auswählenden Kräfte, die normalerweise :has() zugeschrieben werden. Was wir auswählen, ist ein Element

  • mit einer .subtitle-Klasse
  • das ein Kind von .header-group ist
  • und ein <h2>-Element darin enthält.

Ist <h2> das direkte Kind von .header-group? Nein, es ist eher ein Enkel.

Kombinieren von :has() mit anderen relationalen Pseudo-Selektoren.

Sie können :has() mit anderen funktionalen Pseudo-Klassen-Selektoren wie :where():not() und :is() kombinieren.

Kombination von :has() und :is().

Zum Beispiel können Sie prüfen, ob eine der HTML-Überschriften mindestens ein <a>-Element als Nachfahren hat.

:is(h1, h2, h3, h4, h5, h6):has(a) {
  color: blue;
}

/* is equivalent to: */
h1:has(a),
h2:has(a),
h3:has(a),
h4:has(a),
h5:has(a),
h6:has(a) {
  color: blue;
}

Sie können auch :is() als Argument an :has() übergeben. Stellen Sie sich vor, wir ändern das letzte Beispiel so, dass jede Überschriftenebene, die ein <a>-Kindelement oder ein beliebiges Kindelement mit der Klasse .link enthält, ausgewählt wird.

:is(h1, h2, h3, h4, h5, h6):has(:is(a, .link)) {
  color: blue;
}

Kombination von :has() und :not().

Wir können :has() auch mit dem :not() -Selektor verwenden! Sagen wir, Sie möchten einem .card-Element einen Rand hinzufügen, wenn es keine <img>-Element-Nachfahren enthält. Klar doch.

.card:not(:has(img)) {
  border: 1px solid var(--my-amazing-color);
}

Dies prüft, ob die Karte :has() irgendein Bild hat und sagt dann:

Hey, wenn du keine Bilder findest, bitte sehr, mit einem Sahnehäubchen darauf, wende diese Stile an.

Willst du es verrückter machen? Wählen wir jedes .post-Element für Bilder aus, denen alt-Text fehlt.

.post:has(img:not([alt])) {
  /* Styles */
}

Sehen Sie, was wir hier gemacht haben? Dieses Mal ist :not() in :has(). Das bedeutet:

Hey, wenn du Beiträge findest, die ein Bild ohne Alternativtext enthalten, wende bitte diese Stile an, vielen Dank.

Dies könnte verwendet werden, um Bilder zu debuggen, denen das alt-Attribut fehlt.

Hier ist ein weiteres Beispiel, das ich aus Eric Meyers Video übernommen habe. Nehmen wir an, Sie möchten jede <div> auswählen, die nichts außer <img>-Elementen enthält.

div:not(:has(:not(img))) {
  /* Styles */
}

Was wir hier sagen, ist:

Wenn du eine <div> findest und darin nichts als ein oder mehrere Bilder sind, mach deine Magie!

Hier kommt es auf die Reihenfolge an.

Beachten Sie, wie die Änderung der Reihenfolge unserer Selektoren beeinflusst, was sie auswählen. Wir haben über die unerbittliche Natur der :has()-Argumentliste gesprochen, aber sie ist in den Beispielen, die wir betrachtet haben, die :has() mit anderen relationalen Pseudo-Selektoren kombinieren, noch unerbittlicher.

Werfen wir einen Blick auf ein Beispiel.

article:not(:has(img)) {
  /* Styles */
}

Dies gleicht jedes <article>-Element ab, das keine Bilder enthält. Drehen wir nun die Dinge um, sodass :has() vor :not() kommt.

article:has(:not(img)) {
  /* Styles */
}

Jetzt gleichen wir jedes <article> -Element ab, das irgendetwas enthält, solange keine Bilder darin sind. Der Artikel muss einen Nachfahren haben, um übereinzustimmen, und dieser Nachfahre kann alles außer einem Bild sein.

Anwendungsfälle

Brotkrümel-Trennzeichen

Brotkrümel sind eine praktische Möglichkeit zu zeigen, auf welcher Seite sich ein Benutzer gerade befindet und wo diese Seite im Seitenbaum liegt. Wenn Sie sich beispielsweise auf einer Über-uns-Seite befinden, können Sie eine Liste anzeigen, die einen Eintrag mit einem Link zur Startseite und einen Eintrag enthält, der lediglich die aktuelle Seite angibt.

<ol class="breadcrumb">
  <li class="breadcrumb-item"><a href="/">Home</a></li>
  <li class="breadcrumb-item current">About</li>
</ol>

Das ist cool. Aber was, wenn wir das als horizontale Liste anzeigen und die Listenpunkte ausblenden möchten? Mit CSS ganz einfach.

ol {
  display: flex;
  list-style: none;
}

Achtung! Das Setzen von list-style: none verhindert, dass Safari das Element als Liste identifiziert.

OK, aber jetzt bleiben uns zwei Listenelemente, die sich überschneiden. Wir könnten einen gap zwischen ihnen einfügen, da wir Flexbox verwenden.

ol {
  display: flex;
  gap: .5rem;
  list-style: none;
}

Das hilft sicherlich. Aber wir können eine stärkere Unterscheidung zwischen den beiden Elementen treffen, indem wir einen Trennstrich zwischen sie setzen. Keine große Sache.

.breadcrumb-item::after {
  content: "/";
}

Aber warten Sie! Wir brauchen keinen Trennstrich nach dem .current-Element, da es immer das letzte in der Liste ist und nichts danach folgt. Hier kommt :has() ins Spiel. Wir können jedes Kind mit der Klasse .current mit dem nachfolgenden Kindselektor (~) suchen, um es aufzuspüren.

.breadcrumb-item:has(~ .current)::after {
  content: "/";
}

Da haben wir es!

JavaScript-freie Formularvalidierung

Wie wir bereits gelernt haben, akzeptiert :has() keine Pseudo-Elemente, aber es erlaubt uns, Pseudo-Klassen zu verwenden. Wir können dies als leichte Form der Validierung verwenden, die wir normalerweise mit JavaScript angehen würden.

Nehmen wir an, wir haben ein Newsletter-Anmeldeformular, das nach einer E-Mail fragt.

<form>  
  <label for="email-input">Add your pretty email:</label>
  <input id="email-input" type="email" required>
</form>

E-Mail ist ein erforderliches Feld in diesem Formular. Sonst gibt es nichts zu übermitteln! Vielleicht können wir dem Eingabefeld einen roten Rand geben, wenn der Benutzer eine ungültige E-Mail-Adresse eingibt.

form:has(input:invalid) {
  border: 1px solid red;
}

Probieren Sie es aus. Versuchen Sie, eine ungültige E-Mail-Adresse einzugeben und dann zum Passwortfeld zu tabulieren oder zu klicken.

Formatieren von erledigten Elementen in einer Aufgabenliste

Haben Sie versucht, das Label einer Checkbox zu formatieren, wenn die Eingabe aktiviert ist? Sie wissen schon, wie eine To-Do-Listen-App, bei der Sie Elemente in der Liste erledigen, indem Sie ein Kästchen ankreuzen.

Die Struktur Ihres HTML könnte so aussehen:

<form>
  <input id="example-checkbox" type="checkbox">
  <label for="example-checkbox">We need to target this when input is checked</label>
</form>

Obwohl es für die Barrierefreiheit besser ist, das Label vor dem Eingabeelement zu platzieren oder es darum zu wickeln, müssen Sie das Label nach dem Eingabeelement platzieren, um das Label basierend auf dem check-Attribut des Eingabeelements auswählen zu können.

Mit einem nachfolgenden Geschwisterselektor (+) können Sie das Label wie folgt formatieren:

/* When the input is checked, 
  style the label */
input:checked + label {
  color: green;
}

Ändern wir das Markup und erstellen ein implizites Label, indem wir die Eingabe darin verschachteln.

<form>  
  <label>
    <input type="checkbox">
    We need to target this when input is checked
  </label>
</form>

Früher gab es keine Möglichkeit, dieses Label auszuwählen, wenn die Eingabe aktiviert war. Aber jetzt, wo wir den :has() -Selektor haben, haben wir diese Möglichkeit.

/* If a label has a checked input,
  style that label */
label:has(input:checked) {
  color: green;
}

Gehen wir nun zurück zum idealen Markup, bei dem das Label vor der Eingabe steht.

<form> 
  <label for="example-checkbox">We need to target this when input is checked</label>
  <input id="example-checkbox" type="checkbox">
</form>

Sie können :has() immer noch als vorherigen Selektor verwenden, um das explizite Label auszuwählen und zu formatieren, während Sie zugänglicheres Markup beibehalten.

/* If a label has a checked input 
   that is it's next sibling, style 
   the label */
label:has(+ input:checked) {
  color: green;
}
Intelligenter „In den Warenkorb“-Button

Was passiert, wenn wir :has() auf das Stammelement einer Seite oder den Body anwenden?

:root:has( /* Any condition */ ) {
  /* Styles */
}

Das :root ist die höchste Ebene eines Dokuments, die alles darunter steuert, richtig? Wenn etwas weit unten im DOM-Baum passiert, können Sie es erkennen und einen anderen Zweig des DOMs entsprechend formatieren.

Nehmen wir an, Sie betreiben einen E-Commerce-Shop und möchten den „In den Warenkorb“-Button formatieren, wenn ein Produkt in den Warenkorb gelegt wird. Das ist ziemlich üblich, oder? Seiten wie Amazon tun das ständig, um dem Benutzer mitzuteilen, dass ein Artikel erfolgreich in ihrem Warenkorb ist.

Stellen Sie sich vor, das ist die Struktur unseres HTML. Der „In den Warenkorb“-Button befindet sich im <header>-Element und das Produkt befindet sich in einem <main>-Element.

Ein Diagramm, das identifiziert, wo sich die Produkt- und Button-Elemente im DOM-Baum befinden.

Ein stark vereinfachtes Beispiel des Markups könnte so aussehen.

<body>
  <header>
    <button class="cart-button">Add to cart</button>
  </header>
  <main> 
    <ul>
      <li class="p-item">Product</li>
      <li class="p-item is-selected">Product</li>
      <li class="p-item">Product</li>
    </ul>
  </main>
</body>

In CSS können wir prüfen, ob der <body> :has() irgendeinen Nachfahren mit den Klassen .p-item und .is-selected enthält. Sobald diese Bedingung erfüllt ist, kann der .cart-button ausgewählt werden.

body:has(.p-item.is-selected) .cart-button {
  background-color: green;
}
Farbthemen ändern

Dunkler Modus, heller Modus, Hochkontrastmodus. Den Benutzern die Wahl zu geben, das Farbschema einer Website anzupassen, kann eine schöne UX-Verbesserung sein.

Nehmen wir an, irgendwo tief im Dokument gibt es ein <select>-Menü, mit dem Benutzer ein Farbschema auswählen können.

<select>
  <option value="light">Light</option>
  <option value="dark">Dark</option>
  <option value="high-contrast">High-contrast</option>
</select>

Wir können :has() auf dem <body> -Element verwenden und das ausgewählte <option> des <select> -Menüs prüfen. Auf diese Weise können wir, wenn ein <option> einen bestimmten Wert enthält, CSS-Custom Properties mit verschiedenen Farb-Werten aktualisieren, um das aktuelle Farbschema zu ändern.

body:has(option[value="dark"]:checked) {
  --primary-color: #e43;
  --surface-color: #1b1b1b;
  --text-color: #eee;
}

Auch hier geschieht etwas (ein Benutzer wählt <option> aus) irgendwo im DOM-Baum, und wir beobachten Änderungen auf der höchsten Ebene des Baums (dem <body> ) und aktualisieren die Stile (über benutzerdefinierte Eigenschaften) entsprechend.

Ein Element basierend auf der Anzahl der Kinder formatieren

Hier ist ein cleverer Trick, der von Bramus Van Damme stammt. :has() kann Stile basierend auf der Anzahl der Kinder in einem übergeordneten Container anwenden.

Stellen Sie sich ein zweispaltiges Layout vor. Wenn die Anzahl der Elemente im Raster ungerade ist – 3, 5, 7, 9 usw. –, dann bleiben Sie mit einem leeren Feld im Raster nach dem letzten Element zurück.

Anpassung eines zweispaltigen Layouts mit einer ungeraden Anzahl von Kindern, wobei das erste Kind die erste Zeile überspannt.

Es wäre besser, wenn das erste Element im Raster die beiden Spalten in der ersten Zeile einnehmen könnte, um dies zu verhindern. Und dafür müssten Sie prüfen, ob das :last-child-Element im Raster auch ein ungerades Kind ist.

/* If the last item in a grid is an odd-numbered child */
.grid-item:last-child:nth-child(odd) {
  /* Styles */
}

Dies kann in die :has()-Argumentliste eingefügt werden, sodass wir das :first-child des Rasters formatieren können, damit es die gesamte erste Zeile des Rasters einnimmt, wenn das :last-child eine ungerade Zahl ist.

.grid:has(> .grid-item:last-child:nth-child(odd)) .grid-item:first-child {
  grid-column: 1 / -1;
}

Browser-Unterstützung

Diese Browser-Supportdaten stammen von Caniuse, das weitere Details enthält. Eine Zahl zeigt an, dass der Browser die Funktion ab dieser Version unterstützt.

Desktop

ChromeFirefoxIEEdgeSafari
105121Nein10515.4

Mobil / Tablet

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712715.4

Auf Unterstützung testen

Die @supports-Regel unterstützt :has(), was bedeutet, dass wir prüfen können, ob ein Browser sie unterstützt, und Stile bedingt basierend auf dem Ergebnis anwenden können.

@supports(figure(:has(figcaption))) {
  /* Supported! */
}

Weitere Informationen