Het probleem
We moeten vaak filtercriteria van verschillende typen combineren, bijvoorbeeld selectors + mediaquery's, mediaquery's + containerquery's, enzovoort.
Combineer bijvoorbeeld (prefers-color-scheme: dark) met een kiezer die kleurenschema-overschrijvingen target (bijvoorbeeld :root:has(> head > meta[name="color-scheme"][content="dark"]) of :root.dark) om bepaalde stijlen toe te passen in de lichte/donkere modus, ongeacht hoe het kleurenschema is ingesteld.
De naïeve aanpak leidt tot dubbele code:
/* Light mode styles */
.card.featured {
font-weight: 400;
}
#logo-dark {
display: none;
}
@media (prefers-color-scheme: dark) {
/* Dark mode styles */
:root:not(.light) {
.card.featured {
font-weight: 300;
}
#logo-dark {
display: inline;
}
#logo {
display: none;
}
}
}
/* Dark mode styles, again */
:root.dark {
.card.featured {
font-weight: 300;
}
#logo-dark {
display: inline;
}
#logo {
display: none;
}
}
Wat je in plaats daarvan kunt doen
Sla het resultaat van het gecombineerde filter op in een aangepaste eigenschap en gebruik dan containerstijlquery's om regels in te stellen op basis van die eigenschap.
BELANGRIJK: Vanwege de manier waarop containerquery's werken, werkt deze techniek alleen als we de aangepaste eigenschap kunnen instellen op een bovenliggend element van regels die moeten overeenkomen.
1. Selectielogica loskoppelen van toegepaste regels
:root {
--color-scheme: light;
@media (prefers-color-scheme: dark) {
--color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="dark"]) {
--color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="light"]) {
--color-scheme: light;
}
}
2. Sleutel van de aangepaste eigenschap voor toegepaste regels
@container not style(--color-scheme: dark) {
.card.featured {
font-weight: 400;
}
#logo-dark {
display: none;
}
}
@container style(--color-scheme: dark) {
.card.featured {
font-weight: 300;
}
#logo {
display: none;
}
}
3. OPTIONEEL: Hulpprogrammaklassen om de zichtbaarheid aan of uit te zetten
Een veelvoorkomend geval is de zichtbaarheid aan- of uitzetten op basis van of de criteria overeenkomen.
Hulpprogrammaklassen moeten winnen van willekeurige componentstijlen (vandaar !important) en de getoonde display is onbekend, dus ze kunnen geen overschrijvingen gebruiken. Beperk ze met not style(...):
@container not style(--color-scheme: dark) {
.if-dark {
display: none !important;
}
}
@container not style(--color-scheme: light) {
.if-light {
display: none !important;
}
}
Reserves
Er zijn 2 typen fallbacks, afhankelijk van hoe kritiek de vertakking is en wat een acceptabele fallback is.
- Voor kritieke vertakkingen, waarbij alle statussen correct moeten werken, zelfs als stijlquery's niet worden ondersteund, kun je stijlquery's gewoon niet gebruiken. Gebruik in plaats daarvan de bovenstaande eenvoudige aanpak en dupliceer de regels voor elke staat. Hulpprogrammaklassen kunnen nog steeds worden gebruikt, zolang ze ook op die manier zijn gedefinieerd.
- Voor niet-kritieke vertakkingen, waarbij een standaardstatus acceptabel is, kunt u de basisstijlen buiten een
@container-regel definiëren en stijlquery's alleen gebruiken als overschrijvingen. Zo blijft de essentie van deze aanpak behouden. Het belangrijkste nadeel is de koppeling van waarden die overschrijvingen introduceren.
#logo-dark {
display: none;
}
@container style(--color-scheme: dark) {
#logo-dark {
display: inline; /* override */
}
#logo {
display: none;
}
}