Kopanje globlje v poizvedbe v slogu vsebnika

Izvorno vozlišče: 1765194

Nekaj ​​sem jih napisal zgodnje misli o poizvedbah v slogu vsebnika malo nazaj. Še zgodaj je. Opredeljeni so že v Specifikacija CSS Containment Module Level 1 (trenutno v statusu urednikovega osnutka), vendar še vedno poteka nekaj odprtih razprav.

Osnovna ideja je, da lahko definiramo vsebnik in nato pogojno uporabimo sloge za njegove potomce na podlagi njegovega izračunanega sloga.

@container ?  {
  /* conditional styles */
}

Najboljši primer, ki sem ga do zdaj videl, je odstranjevanje ležečega tiska iz nečesa podobnega , in ko se uporabljajo v kontekstu, kjer je vsebina že v poševnem tisku:

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;
  }
}

To je splošna ideja. Če pa tega niste vedeli, Miriam Suzanne, ki je urednica spec, vodi stalen in temeljit nabor osebne opombe o poizvedbah v slogu vsebnika ki je javno dostopen. Prejšnji dan so ga posodobili in tam sem preživel nekaj časa, ko sem poskušal oviti glavo okoli bolj niansiranih vidikov stilskih poizvedb. To so neuradne stvari, vendar sem mislil, da bi zapisal nekaj stvari, ki so se mi zdele. Kdo ve? Mogoče je to nekaj, česar se lahko na koncu veselimo!

Vsak element je vsebnik sloga

Sploh nam ni treba izrecno dodeliti a container-name or container-type da definirate vsebnik sloga, ker je vse privzeto vsebnik sloga.

Torej, vidite zgornji primer, ki odstranjuje poševno pisavo? Upoštevajte, da ne identificira vsebnika. Skoči naravnost na poizvedbo z uporabo style() funkcijo. Torej, kateri vsebnik se poizveduje? To bo neposredni starš elementov prejemanje uporabljenih stilov. In če ne to, potem je naslednji najbližji relativni vsebnik ki ima prednost.

To mi je všeč. Za poizvedbo je zelo podobno CSS-ju, da poišče ujemanje, nato pa nadaljuje z brskanjem, dokler ne najde ujemajočega se pogoja.

Mojim malim možganom je bilo težko razumeti, zakaj se lahko izognemo implicitnemu vsebniku, ki temelji na slogih, vendar ne toliko, ko imamo opravka z dimenzijskimi poizvedbami, npr. size in inline-size. Miriam to lepo razloži:

Dimenzijske poizvedbe zahtevajo css Vsebovanje na velikost, postavitev in slog vsebnika, da preprečite zanke postavitve. Zadrževanje je invazivna stvar za široko uporabo, zato je bilo pomembno, da imajo avtorji skrben nadzor nad tem, kateri elementi so (ali niso) vsebniki velikosti.

Poizvedbe, ki temeljijo na slogu, nimajo enake omejitve. V CSS-ju že ni možnosti, da bi slogi potomci vplivali na izračunane sloge prednika. Zadrževanje torej ni potrebno in ni invazivnih ali nepričakovanih stranskih učinkov pri vzpostavitvi elementa kot vsebnik slogovnih poizvedb.

(poudarek moj)

Vse se zmanjša na posledice - ki jih ni, saj je vse vsebnik slogovnih poizvedb takoj po izdelavi.

  • Če je vsebnik najden: pogoji so razrešeni za ta vsebnik.
  • Če se ujema več vsebnikov: ima prednost najbližji relativni vsebnik.
  • Če ni ujemanja: unknown vrnil.

To je isto »odpuščajočega« duha kot ostali CSS.

Vsebnik lahko podpira tako dimenzijske kot slogovne poizvedbe

Recimo, da želimo definirati slogovno poizvedbo brez eksplicitnega container-name:

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

To deluje, ker vsi elementi so vsebniki sloga, ne glede na container-type. To je tisto, kar nam omogoča, da implicitno poizvedujemo po slogih in se zanašamo na najbližje ujemanje. In to je popolnoma v redu, saj spet ni nobenih škodljivih stranskih učinkov pri postavljanju stilskih posod.

Uporabiti moramo eksplicitno container-type za dimenzijske poizvedbe, vendar ne toliko za slogovne poizvedbe, saj je vsak element slogovna poizvedba. To tudi pomeni, da je ta posoda hkrati slog in dimenzijska poizvedba:

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

Izključitev vsebnika iz poizvedbe

Morda ne želimo, da vsebnik sodeluje v procesu ujemanja. Tam bi se morda dalo nastaviti container-type: none na elementu.

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

Vsebniki poizvedb v eksplicitnem slogu ponujajo večji nadzor nad tem, kaj se poizveduje

Če bi, recimo, napisali slogovno poizvedbo za padding , ni zanesljivega načina za določitev vsebnika, ki se najbolje ujema, ne glede na to, ali delamo z eksplicitno imenovanim vsebnikom ali najbližjim neposrednim staršem. To je zato, ker padding ni podedovana lastnina.

Torej, v teh primerih bi morali uporabiti container-name da brskalniku izrecno sporočijo, iz katerih vsebnikov lahko črpajo. Vsebniku lahko damo celo več izrecnih imen, da se ujema z več pogoji:

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

Oh, in container-name sprejme poljubno število neobveznih in za večkratno uporabo imena za posodo! To je še večja prilagodljivost, ko gre za pomoč brskalniku pri izbiri pri iskanju ujemanja.

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

Nekako se sprašujem, ali bi se to lahko štelo tudi za "nadomestno" v primeru, da gre mimo en vsebnik.

Slogovne poizvedbe je mogoče kombinirati

O or in and operaterji nam omogočajo združevanje wueries, da stvari ostanejo SUHE:

@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. */
}

Preklop slogov

Malo se prekrivajo poizvedbe v slogu vsebnika in poteka delo za opredelitev a toggle() funkcija. Na primer, lahko krožimo skozi dva font-style vrednote, recimo italic in normal:

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

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

Kul. Toda predlog za CSS Toggles nakazuje, da je toggle() funkcija bi bila preprostejši pristop:

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

Toda vse, kar presega to vrsto binarnega primera uporabe, je kje toggle() je manj primeren. Poizvedbe o slogu pa so dobre. Miriam identificira tri primere, kjer so slogovne poizvedbe primernejše od 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;
  }
}

Slogovne poizvedbe rešujejo »Custom Property Toggle Hack«

Upoštevajte, da so slogovne poizvedbe formalna rešitev za »Trik za preklop lastnosti po meri CSS«. Tam smo nastavili prazno lastnost po meri (--foo: ;) in uporabite nadomestno metodo, ločeno z vejicami, za »vklop in izklop« lastnosti, ko je lastnost po meri nastavljena na resnično vrednost.

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. */
}

To je super kul, poleg tega je veliko dela, ki ga poizvedbe vsebnika slogov naredijo nepomembnega.

Slogovne poizvedbe in vsebina, ustvarjena s CSS

Za ustvarjeno vsebino, ki jo proizvaja content lastnina ::before in ::after psevdoelementi, je ujemajoči se vsebnik element, na katerem je ustvarjena vsebina.

.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;
  }
}

Stilske poizvedbe in spletne komponente

Spletno komponento lahko definiramo kot vsebnik in poizvedujemo po njej po slogu. Prvič, imamo komponente:


  
… …

Nato uporabimo :host psevdoelement kot vsebnik za nastavitev a container-nameA container-typein nekaj atributov na visoki ravni na njem:

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

Elementi znotraj lahko povpraša po parametrih Element:

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

Kaj je naslednje?

Še enkrat, vse stvari, ki sem si jih zapisal tukaj, temeljijo na Miriaminih zapiskih in ti zapiski niso nadomestilo za uradne specifikacije. So pa pokazatelj, o čem se razpravlja in kam bi stvari lahko pristale v prihodnosti. Cenim, da je Miriam povezala peščico izjemnih razprav, ki še vedno potekajo, ki jih lahko spremljamo, da smo na tekočem:

Časovni žig:

Več od Triki CSS