Jeg skrev opp noen tidlige tanker om beholderstilsøk en liten stund tilbake. Det er fortsatt tidlig. De er allerede definert i CSS Containment Module Level 1 spesifikasjon (for øyeblikket i Redaktørutkast-status), men det er fortsatt et par utestående diskusjoner som finner sted.
Den grunnleggende ideen er at vi kan definere en beholder og deretter bruke stiler betinget på dens etterkommere basert på dens beregnede stil.
@container ? {
/* conditional styles */
}
Det beste eksemplet jeg har sett så langt er å fjerne kursiv fra noe sånt som ,
og
når de brukes i en kontekst der innholdet allerede er kursivt:
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;
}
}
Det er den generelle ideen. Men hvis du ikke visste det, holder Miriam Suzanne, som er redaktør av spesifikasjonen, et pågående og grundig sett med personlige notater om forespørsler i containerstil som er offentlig tilgjengelig. Den ble oppdatert her om dagen, og jeg brukte litt tid der inne på å prøve å vikle hodet rundt mer nyanserte aspekter ved stilsøk. Det er uoffisielle greier, men jeg tenkte jeg skulle skrive ned noen ting som skilte seg ut for meg. Hvem vet? Kanskje det er ting vi kan se frem til etter hvert!
Hvert element er en stilbeholder
Vi trenger ikke engang eksplisitt tildele en container-name
or container-type
å definere en stilbeholder fordi alt er en stilbeholder som standard.
Så du ser det eksemplet ovenfor som fjerner kursiv? Legg merke til at den ikke identifiserer en beholder. Den hopper rett til spørringen ved å bruke style()
funksjon. Så hvilken beholder spørres etter? Det kommer til å bli direkte foreldre til elementene motta de anvendte stilene. Og hvis ikke det, så er det det neste nærmeste relative beholder som har forrang.
Jeg liker det. Det er veldig CSS-y for spørringen å søke opp etter et samsvar, og deretter fortsette å boble opp til det finner en samsvarende betingelse.
Det var vanskelig for min lille hjerne å forstå hvorfor vi kan komme unna med en implisitt beholder basert på stiler, men ikke så mye når vi har å gjøre med dimensjonale søk, som size
og inline-size
. Miriam forklarer det fint:
Dimensjonale søk krever css Begrensning på størrelsen, oppsettet og stilen til beholderen for å forhindre utformingsløkker. Inneslutning er en invasiv ting å bruke bredt, så det var viktig at forfattere hadde nøye kontroll over hvilke elementer som er (eller ikke er) størrelsesbeholdere.
Stilbaserte søk har ikke samme begrensning. Det er allerede ingen måte i CSS for etterkommerstiler å ha innvirkning på de beregnede stilene til en stamfar. Så ingen inneslutning er nødvendig, og det er ingen invasive eller uventede bivirkninger ved å etablere et element som en stil spørringsbeholder.
(Vekt min)
Alt kommer ned til konsekvenser - som det ikke er noen av så langt som at alt er en stilspørringsbeholder rett ut av esken.
- Hvis en beholder blir funnet: forholdene er løst mot den beholderen.
- Hvis flere beholdere samsvarer: den nærmeste relative beholderen har forrang.
- Hvis ingen treff blir funnet:
unknown
returnert.
Det er det samme "tilgivende" ånd som resten av CSS.
En beholder kan støtte både dimensjons- og stilspørringer
La oss si at vi vil definere en stilspørring uten en eksplisitt container-name
:
@container style(font-style: italic) {
em {
font-style: normal;
}
}
Dette fungerer fordi alle elementer er stilbeholdere, uansett container-type
. Det er det som lar oss implisitt spørre etter stiler og stole på den nærmeste matchen. Og dette er helt greit siden, igjen, det er ingen negative bivirkninger når du etablerer stilbeholdere.
Vi må bruke en eksplisitt container-type
for dimensjonale spørringer, men ikke så mye for stilspørringer siden hvert element er en stilspørring. Det betyr også at denne beholderen er både en stil og dimensjonsspørring:
.card-container {
container: card / inline-size; /* implictly a style query container as well */
}
Ekskluderer en beholder fra å bli spurt
Kanskje vi ikke ønsker at en container skal delta i matchingsprosessen. Det er der det kan være mulig å stille inn container-type: none
på et element.
.some-element {
container-type: none;
}
Spørringsbeholdere med eksplisitt stil gir mer kontroll over hva som blir spurt
Hvis for eksempel vi skulle skrive en stilspørring for padding
, er det ingen pålitelig måte å finne den best samsvarende beholderen, uavhengig av om vi jobber med en eksplisitt navngitt beholder eller nærmeste direkte overordnede. Det er fordi padding
er ikke en arvelig eiendom.
Så i slike tilfeller bør vi bruke container-name
for å eksplisitt informere nettleseren hvilke containere de kan hente fra. Vi kan til og med gi en beholder flere eksplisitte navn for å få den til å samsvare med flere betingelser:
.card {
container-name: card layout theme;
}
Oh, og container-name
godtar et hvilket som helst antall valgfrie og gjenbruk navn på en container! Det er enda mer fleksibilitet når det gjelder å hjelpe nettleseren med å velge når de søker etter treff.
.theme {
container-name: theme;
}
.grid {
container-name: layout;
}
.card {
container-name: card layout theme;
}
Jeg lurer litt på om det også kan betraktes som en "fallback" i tilfelle en container passeres.
Stilspørringer kan kombineres
De or
og and
operatører lar oss kombinere produkter for å holde ting TØRT:
@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. */
}
Bytte stiler
Det er litt overlapping mellom beholderstilsøk og arbeid som gjøres for å definere en toggle()
funksjon. For eksempel kan vi sykle gjennom to font-style
verdier, si italic
og normal
:
em, i, q {
font-style: italic;
}
@container style(font-style: italic) {
em, i, q {
font-style: normal;
}
}
Kul. Men forslaget til CSS Toggles antyder at toggle()
funksjon ville være en enklere tilnærming:
em, i, q {
font-style: toggle(italic, normal);
}
Men alt utover denne typen binære brukstilfeller er hvor toggle()
er mindre egnet. Stilspørringer er imidlertid gode å gå. Miriam identifiserer tre tilfeller der stilsøk er mer egnet enn en 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;
}
}
Stilspørringer løser "Custom Property Toggle Hack"
Legg merke til at stilspørringer er en formell løsning for "CSS egendefinert egenskap bytte triks". Der inne setter vi en tom egendefinert egenskap (--foo: ;
) og bruk den kommaseparerte reservemetoden for å "veksle" egenskaper på og av når egendefinert egenskap er satt til en reell verdi.
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. */
}
Det er superkult, også mye arbeid som stilbeholderspørringer gjør trivielt.
Stilspørringer og CSS-generert innhold
For generert innhold produsert av content
tilhører ::before
og ::after
pseudo-elementer, er den matchende beholderen elementet som innholdet genereres på.
.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;
}
}
Stilspørringer og webkomponenter
Vi kan definere en webkomponent som en beholder og spørre etter stil. For det første har vi av komponenten:
…
…
…
Så bruker vi :host
pseudo-element som en beholder for å sette en container-name
en container-type
, og noen attributter på høyt nivå på den:
:host {
container: media-host / inline-size;
--media-location: before;
--media-style: square;
--theme: light;
}
Elementer inne i kan spørre parametrene til
element:
@container media-host style(--media-style: round) {
[part='img'] {
border-radius: 100%;
}
}
Hva blir det neste?
Igjen, alt jeg har notert ned her er basert på Miriams notater, og disse notatene er ikke en erstatning for den offisielle spesifikasjonen. Men de er en indikasjon på hva som diskuteres og hvor ting kan lande i fremtiden. Jeg setter pris på at Miriam koblet sammen en håndfull enestående diskusjoner som fortsatt finner sted som vi kan følge for å holde deg oppdatert: