Sapă mai adânc în interogările stilului containerului PlatoBlockchain Data Intelligence. Căutare verticală. Ai.

Săpătură mai profundă în interogările privind stilul containerului

Am scris câteva gânduri timpurii despre interogările de stil de container putin in urma. Este încă devreme. Sunt deja definite în Specificație de nivel 1 pentru modulul de izolare CSS (în prezent în starea de redactare a redactorului), dar încă mai au loc câteva discuții restante.

Ideea de bază este că putem defini un container și apoi să aplicăm stiluri condiționat descendenților săi pe baza stilului său calculat.

@container ?  {
  /* conditional styles */
}

Cel mai bun exemplu pe care l-am văzut până acum este eliminarea caracterelor cursive din ceva de genul , , și atunci când sunt utilizate într-un context în care conținutul este deja scris în cursive:

em, i, q {
  font-style: italic; /* default UA behavior */
}

/* When the container's font-style is italic, remove italics from these elements. */
@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

Asta e ideea generală. Dar dacă nu știai, Miriam Suzanne, care este editor al spec., păstrează un set continuu și complet de note personale privind interogările de stil de container care este disponibil publicului. A fost actualizat zilele trecute și am petrecut ceva timp acolo încercând să-mi înțeleg aspectele mai nuanțate ale interogărilor de stil. Sunt lucruri neoficiale, dar m-am gândit să notez câteva lucruri care mi-au remarcat. Cine ştie? Poate că sunt lucruri pe care le putem aștepta în cele din urmă cu nerăbdare!

Fiecare element este un container de stil

Nici măcar nu trebuie să atribuim în mod explicit un container-name or container-type pentru a defini un container de stil deoarece totul este implicit un container de stil.

Deci, vedeți exemplul de mai sus care elimină caracterele cursive? Observați că nu identifică un container. Se trece direct la interogare folosind style() funcţie. Deci, ce container este interogat? Va fi părinte direct al elementelor primind stilurile aplicate. Și dacă nu asta, atunci este următorul container relativ apropiat care are prioritate.

Îmi place asta. Este foarte CSS-y ca interogarea să caute o potrivire, apoi să continue să apară până când găsește o condiție de potrivire.

Mi-a fost greu pentru micul meu creier să înțeleagă de ce putem scăpa cu un container implicit bazat pe stiluri, dar nu atât de mult atunci când avem de-a face cu interogări dimensionale, cum ar fi size și inline-size. Miriam explică frumos:

Interogările dimensionale necesită css izolare privind dimensiunea, aspectul și stilul containerului pentru a preveni buclele de layout. Limitarea este un lucru invaziv de aplicat pe scară largă, așa că a fost important ca autorii să aibă un control atent asupra elementelor care sunt (sau nu sunt) containere de dimensiune.

Interogările bazate pe stil nu au aceeași limitare. Nu există deja nicio modalitate în CSS ca stilurile descendente să aibă un impact asupra stilurilor calculate ale unui strămoș. Deci nu este necesară izolarea și nu există efecte secundare invazive sau neașteptate în stabilirea unui element ca container de interogări de stil.

(sublinierea mea)

Totul se rezumă la consecințe - dintre care nu există niciuna, în măsura în care totul este un container de interogare de stil imediat scos din cutie.

  • Dacă se găsește un container: condițiile sunt rezolvate față de acel container.
  • Dacă mai multe containere se potrivesc: cel mai apropiat container relativ are prioritate.
  • Dacă nu se găsesc potriviri: unknown întors.

E la fel spiritul „iertător” ca și restul CSS.

Un container poate suporta atât interogări dimensionale, cât și de stil

Să presupunem că vrem să definim o interogare de stil fără un explicit container-name:

@container style(font-style: italic) {
  em {
    font-style: normal;
  }
}

Acest lucru funcționează pentru că toate elementele sunt containere de stil, indiferent de container-type. Acesta este ceea ce ne permite să interogăm implicit stiluri și să ne bazăm pe cea mai apropiată potrivire. Și acest lucru este în regulă, deoarece, din nou, nu există efecte secundare adverse la stabilirea recipientelor de stil.

Trebuie să folosim un explicit container-type pentru interogări dimensionale, dar nu atât pentru interogări de stil, deoarece fiecare element este o interogare de stil. Asta înseamnă, de asemenea, că acest container este atât un stil și interogare dimensională:

.card-container {
  container: card / inline-size; /* implictly a style query container as well */
}

Excluderea unui container de la interogare

Poate că nu vrem ca un container să participe la procesul de potrivire. Acolo ar putea fi posibil să setați container-type: none pe un element.

.some-element {
  container-type: none;
}

Containerele de interogări în stil explicit oferă mai mult control asupra a ceea ce este interogat

Dacă, să zicem, ar fi să scriem o interogare de stil pentru padding , nu există o modalitate fiabilă de a determina cel mai potrivit container, indiferent dacă lucrăm cu un container denumit în mod explicit sau cu cel mai apropiat părinte direct. Asta este pentru ca padding nu este o proprietate moștenită.

Deci, în aceste cazuri, ar trebui să folosim container-name pentru a informa în mod explicit browserul din ce containere pot extrage. Putem chiar da unui container mai multe nume explicite pentru a-l face să corespundă mai multor condiții:

.card {
  container-name: card layout theme;
}

Oh si container-name acceptă orice număr de opționale și reutilizabile nume pentru un container! Aceasta este și mai multă flexibilitate atunci când vine vorba de a ajuta browserul să facă o alegere atunci când caută potriviri.

.theme {
  container-name: theme;
}
.grid {
  container-name: layout;
}
.card {
  container-name: card layout theme;
}

Mă întreb dacă acest lucru ar putea fi considerat și o „rezervă” în cazul în care un container este trecut peste.

Interogările de stil pot fi combinate

or și and operatorii ne permit să combinăm diversele pentru a menține lucrurile USCATE:

@container bubble style(--arrow-position: start start) or style(--arrow-position: end start) {
  .bubble::after {
    border-block-end-color: inherit;
    inset-block-end: 100%;
  }
}

/* is the same as... */
@container bubble style(--arrow-position: start start) {
  /* etc. */
}
@container bubble style(--arrow-position: end start) {
  /* etc. */
}

Comutarea stilurilor

Există o mică suprapunere între interogările stil container și se lucrează pentru definirea a toggle() funcţie. De exemplu, putem trece prin două font-style valori, să zicem italic și normal:

em, i, q {
  font-style: italic;
}

@container style(font-style: italic) {
  em, i, q {
    font-style: normal;
  }
}

Misto. Dar propunerea pentru CSS Toggles sugerează că toggle() funcția ar fi o abordare mai simplă:

em, i, q {
  font-style: toggle(italic, normal);
}

Dar orice dincolo de acest tip de caz de utilizare binar este unde toggle() este mai puțin potrivit. Interogările de stil, totuși, sunt bune. Miriam identifică trei cazuri în care interogările de stil sunt mai potrivite decât a toggle():

/* When font-style is italic, apply background color. */
/* Toggles can only handle one property at a time. */
@container style(font-style: italic) {
  em, i, q {
    background: lightpink;
  }
}

/* When font-style is italic and --color-mode equals light */
/* Toggles can only evaluate one condition at a time */
@container style((font-style: italic) and (--color-mode: light)) {
  em, i, q {
    background: lightpink;
  }
}

/* Apply the same query condition to multiple properties */
/* Toggles have to set each one individually as separate toggles */
@container style(font-style: italic) {
  em, i, q {
    /* clipped gradient text */
    background: var(--feature-gradient);
    background-clip: text;
    box-decoration-break: clone;
    color: transparent;
    text-shadow: none;
  }
}

Interogările de stil rezolvă „Hack-ul de comutare a proprietății personalizate”

Observați că interogările de stil sunt o soluție formală pentru „Truc de comutare a proprietății personalizate CSS”. Acolo, setăm o proprietate personalizată goală (--foo: ;) și utilizați metoda de rezervă separată prin virgulă pentru a „activa și dezactiva” proprietățile atunci când proprietatea personalizată este setată la o valoare reală.

button {
  --is-raised: ; /* off by default */
  
  border: 1px solid var(--is-raised, rgb(0 0 0 / 0.1));
  box-shadow: var(
    --is-raised,
    0 1px hsl(0 0% 100% / 0.8) inset,
    0 0.1em 0.1em -0.1em rgb(0 0 0 / 0.2)
  );
  text-shadow: var(--is-raised, 0 -1px 1px rgb(0 0 0 / 0.3));
}

button:active {
  box-shadow: var(--is-raised, 0 1px 0.2em black inset);
}

#foo {
  --is-raised: initial; /* turned on, all fallbacks take effect. */
}

Este super tare, de asemenea, multă muncă pe care interogările de stil de containere o fac triviale.

Interogări de stil și conținut CSS generat

Pentru conținutul generat produs de content proprietatea ::before și ::after pseudo-elemente, containerul de potrivire este elementul pe care este generat conținutul.

.bubble {
  --arrow-position: end end;
  container: bubble;
  border: medium solid green;
  position: relative;
}

.bubble::after {
  content: "";
  border: 1em solid transparent;
  position: absolute;
}

@container bubble style(--arrow-position: end end) {
  .bubble::after {
    border-block-start-color: inherit;
    inset-block-start: 100%;
    inset-inline-end: 1em;
  }
}

Interogări de stil și componente web

Putem defini o componentă web ca un container și o putem interoga după stil. În primul rând, avem a componentei:


  
… …

Apoi folosim :host pseudo-element ca container pentru a seta a container-name, A container-type, și câteva atribute de nivel înalt ale acestuia:

:host {
  container: media-host / inline-size;
  --media-location: before;
  --media-style: square;
  --theme: light;
}

Elementele din interiorul poate interoga parametrii element:

@container media-host style(--media-style: round) {
  [part='img'] {
    border-radius: 100%;
  }
}

Ce urmeaza?

Din nou, toate lucrurile pe care le-am notat aici se bazează pe notele lui Miriam, iar acele note nu sunt un substitut pentru specificațiile oficiale. Dar ele sunt un indiciu a ceea ce se discută și unde ar putea ajunge lucrurile în viitor. Apreciez că Miriam a legat o mână de discuții remarcabile care au loc încă, pe care le putem urmări pentru a rămâne la curent cu lucrurile:

Timestamp-ul:

Mai mult de la CSS Trucuri