Kaivaudu syvemmälle säilötyylisiin kyselyihin

Lähdesolmu: 1765194

Kirjoitin muutaman varhaisia ​​ajatuksia konttityylisistä kyselyistä vähän aikaa sitten. On vielä alkupäiviä. Ne on jo määritelty CSS Containment Module Level 1 -spesifikaatio (tällä hetkellä Editor's Draft -tilassa), mutta vielä on käynnissä pari ratkaisevaa keskustelua.

Perusideana on, että voimme määritellä säilön ja soveltaa sitten tyylejä ehdollisesti sen jälkeläisiin sen lasketun tyylin perusteella.

@container ?  {
  /* conditional styles */
}

Paras esimerkki, jonka olen tähän mennessä nähnyt, on kursiivin poistaminen jostain vastaavasta , ja kun niitä käytetään kontekstissa, jossa sisältö on jo kursivoitu:

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

Se on yleinen ajatus. Mutta jos et tiennyt sitä, Miriam Suzanne, joka on spesifikaatioiden toimittaja, pitää jatkuvaa ja perusteellista sarjaa henkilökohtaiset muistiinpanot konttityylisistä kyselyistä joka on julkisesti saatavilla. Se päivitettiin toissapäivänä, ja vietin siellä jonkin aikaa yrittäen kietoa pääni tyylikyselyjen vivahteikampiin näkökohtiin. Se on epävirallista asiaa, mutta ajattelin kirjoittaa ylös joitain asioita, jotka jäivät mieleeni. Kuka tietää? Ehkä se on asia, jota voimme lopulta odottaa!

Jokainen elementti on tyylisäiliö

Meidän ei edes tarvitse nimenomaisesti määrittää a container-name or container-type määrittääksesi tyylisäilön, koska kaikki on oletusarvoisesti tyylisäilöä.

Joten näetkö yllä olevan esimerkin, joka poistaa kursiivin? Huomaa, että se ei tunnista konttia. Se hyppää suoraan kyselyyn käyttämällä style() toiminto. Joten mitä konttia kysellään? Se tulee olemaan elementtien suora vanhempi sovellettujen tyylien vastaanottaminen. Ja jos ei sitä, niin sitten se on seuraavaksi lähin suhteellinen kontti joka menee etusijalle.

Pidän siitä. Se on erittäin CSS-y, jotta kysely etsii vastaavuutta ja jatkaa sitten kuplaa, kunnes se löytää vastaavan ehdon.

Pikkuaivojeni oli vaikea ymmärtää, miksi voimme päästä eroon tyyleihin perustuvasta implisiittisestä säilöstä, mutta ei niinkään, kun käsittelemme ulottuvuuskyselyitä, kuten size ja inline-size. Miriam selittää sen kauniisti:

Ulottuvuuskyselyt vaativat css:n hillitseminen säilön koosta, asettelusta ja tyylistä, jotta vältetään asettelusilmukat. Suojaus on invasiivinen asia, jota voidaan soveltaa laajasti, joten oli tärkeää, että kirjoittajat valvovat tarkasti, mitkä elementit ovat (tai eivät ole) kokoisia säiliöitä.

Tyylipohjaisilla kyselyillä ei ole samoja rajoituksia. CSS:ssä ei ole jo mahdollista, että jälkeläisten tyyleillä olisi vaikutusta esivanhemman laskettuihin tyyleihin. Joten mitään eristämistä ei tarvita, eikä elementin muodostamisessa ole invasiivisia tai odottamattomia sivuvaikutuksia. tyylinen kyselysäilö.

(korostus minun)

Kaikki riippuu seurauksista – joista ei ole mitään, sillä kaikki on tyylikkäitä kyselysäilöjä heti valmiina.

  • Jos kontti löytyy: ehdot ratkaistaan ​​konttia vastaan.
  • Jos useat säilöt täsmäävät: lähin suhteellinen säilö on etusijalla.
  • Jos osumia ei löydy: unknown palasi.

Se on sama "anteeksiantava" henki kuin muu CSS.

Säilö voi tukea sekä ulottuvuus- että tyylikyselyitä

Oletetaan, että haluamme määrittää tyylikyselyn ilman nimenomaista container-name:

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

Tämä toimii, koska kaikki elementit ovat tyylisäiliöitä, ei väliä container-type. Tämän ansiosta voimme epäsuorasti kysyä tyylejä ja luottaa lähimpään vastaavuuteen. Ja tämä on täysin hienoa, koska taaskaan tyylisäiliöitä laadittaessa ei ole haitallisia sivuvaikutuksia.

Meidän on käytettävä eksplisiittiä container-type ulottuvuuskyselyille, mutta ei niinkään tyylikyselyille, koska jokainen elementti on tyylikysely. Tämä tarkoittaa myös, että tämä säiliö on sekä tyyli ja ulottuvuuskysely:

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

Säilön poissulkeminen kyselystä

Ehkä emme halua kontin osallistuvan sovitusprosessiin. Sinne se saattaa olla mahdollista asettaa container-type: none elementissä.

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

Eksplisiittisen tyylin kyselysäilöillä voit hallita paremmin sitä, mitä kysytään

Jos esimerkiksi kirjoittaisimme tyylikyselyn padding , ei ole luotettavaa tapaa määrittää parhaiten vastaavaa säilöä, riippumatta siitä, työskentelemmekö nimenomaisesti nimetyn säilön vai lähimmän suoran ylätason kanssa. Se johtuu siitä padding ei ole perinnöllinen omaisuus.

Joten näissä tapauksissa meidän pitäisi käyttää container-name ilmoittaa selaimelle selkeästi, mistä säilöistä he voivat hakea. Voimme jopa antaa säilölle useita nimenomaisia ​​nimiä, jotta se vastaa useampia ehtoja:

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

Niin, ja container-name hyväksyy minkä tahansa määrän valinnaisia ​​ja uudelleen käytettävä kontin nimet! Se on vieläkin enemmän joustavuutta, kun se auttaa selainta tekemään valintoja etsiessään osumia.

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

Ihmettelen, voidaanko sitä myös pitää "varana" siinä tapauksessa, että yksi kontti ohitetaan.

Tyylikyselyitä voidaan yhdistää

- or ja and operaattorit antavat meille mahdollisuuden yhdistää wuerioita pitääksemme asiat KUIVANA:

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

Tyylien vaihto

Säilötyyliset kyselyt ovat hieman päällekkäisiä työtä tehdään a toggle() toiminto. Voimme esimerkiksi selata kaksi font-style arvot, sano italic ja normal:

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

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

Viileä. Mutta CSS Toggles -ehdotus ehdottaa, että toggle() toiminto olisi yksinkertaisempi lähestymistapa:

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

Mutta mikä tahansa muu kuin tällainen binäärikäyttötapaus on missä toggle() on vähemmän sopiva. Tyylikyselyt ovat kuitenkin hyviä. Miriam tunnistaa kolme tapausta, joissa tyylikyselyt ovat sopivampia kuin 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;
  }
}

Tyylikyselyt ratkaisevat "Mukautetun ominaisuuden vaihtamisen"

Huomaa, että tyylikyselyt ovat muodollinen ratkaisu "CSS:n mukautetun ominaisuuden vaihtotemppu". Asetamme sinne tyhjän mukautetun ominaisuuden (--foo: ;) ja käytä pilkuilla erotettua varamenetelmää ominaisuuksien kytkemiseen päälle ja pois, kun mukautettu ominaisuus on asetettu todelliseen arvoon.

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

Se on erittäin siistiä, myös paljon työtä, jonka tyyliset säilökyselyt tekevät triviaalista.

Tyylikyselyt ja CSS:n luoma sisältö

Luodulle sisällölle, jonka on tuottanut content Omaisuutta ::before ja ::after pseudoelementtejä, vastaava säiliö on elementti, jolle sisältö luodaan.

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

Tyylikyselyt ja verkkokomponentit

Voimme määritellä verkkokomponentin säilöksi ja kysyä sitä tyylin mukaan. Ensinnäkin meillä on komponentista:


  
… …

Sitten käytämme :host pseudoelementti säilönä asettamiseksi container-name, The container-type, ja joitain sen korkean tason attribuutteja:

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

Elementit sisällä voi tiedustella parametreja elementti:

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

Mitä seuraavaksi?

Jälleen kaikki asiat, jotka olen kirjoittanut tänne, perustuvat Miriamin muistiinpanoihin, eivätkä nuo muistiinpanot korvaa virallisia tietoja. Mutta ne ovat osoitus siitä, mistä keskustellaan ja mihin asiat voivat laskeutua tulevaisuudessa. Arvostan, että Miriam linkitti kourallisen vielä käynnissä olevia merkittäviä keskusteluja, joita voimme seurata pysyäksemme ajan tasalla:

Aikaleima:

Lisää aiheesta CSS-temppuja