CSS if(): Ugrađeni uvjeti za pametnije stiliziranje

  • if() omogućuje uvjetnu logiku na CSS vrijednostima sa style(), media() i supports().
  • Uvjete procijenite redom; prvi true vraća njegovu vrijednost, a ostali pokrivaju.
  • Idealno za promjenu svojstva bez otvaranja @media/@supports; koristite rezervne opcije za kompatibilnost.
  • Kombinirajte s prilagođenim svojstvima i atributima podataka za autonomnije komponente.

Što su selektori atributa u CSS-u

Godinama smo pretpostavljali da CSS ne može "misliti". Ipak, imali smo zaobilazna rješenja: @media, @supports, @container i rezervne varijable Prije su nam omogućavali promjenu stilova na temelju konteksta. Sada dolazi nova značajka koja podiže ljestvicu i bolje se uklapa u način na koji razmišljamo prilikom dizajniranja: uvjetna funkcija if() izravno u vrijednostima svojstava.

Nije dim: Počevši od Chromea 137, možete testirati if() za stvaranje inline stilova s ​​uvjetnom logikom na temelju stila, medija i upita za podršku. Međutim, podrška je još uvijek ograničena izvan Chromiuma, stoga ju je najbolje mudro koristiti. kombinirajući ga s rezervnim opcijama za preglednike koji ga ne razumiju.

Što je bilo prije: „uvjeti“ koje smo već koristili u CSS-u

Prije if(), CSS je već nudio uvjetne mehanizme, svaki sa svojim vlastitim opsegom. Nisu pravi ako, ali ispunjavaju na njihovoj zemlji:

  • @mediaPrimjenjuje pravila ako prozor ili uređaj zadovoljava kriterij (širina, orijentacija, pokazivač itd.).
  • @podrška: Aktivira stilove ako preglednik razumije značajku ili vrijednost.
  • @kontejner: reagira na veličinu ili stil kontejnera, korisno za dizajn temeljen na komponentama.
  • var() s zadanom vrijednošću: nije if, ali dopušta „ako varijabla ne postoji, koristi ovu rezervnu opciju“.

Ovi pristupi su moćni, iako su „vezani“ za svoju svrhu: mediji, nosači ili spremniciFunkcija if() ne zamjenjuje ove alate; već ih besprijekorno integrira. interkalirani i granularni u vrijednostima nekretnina.

Što je if() u CSS-u i zašto je važan

Web dizajn

Funkcija ako() omogućuje vam definiranje, unutar vrijednosti svojstva, popisa parova uvjet:vrijednost, procijenjenih redom. Kada je prvi uvjet istinit, njemu pridružena vrijednost bit će ona koja "pobjeđuje". To je tok sličan kao if…else JS-a, ali ugrađen u CSS.

U svojoj trenutnoj verziji, if() razumije tri vrste upita unutar svojih uvjeta: stil() (upiti stila na samom elementu), prosjek() (upiti medija) i podržava() (upiti za podršku značajkama). Osim toga, možete dodati inače: vrijednost pokriti slučaj gdje ništa drugo ne odgovara.

Detaljna sintaksa i evaluacija

Opća struktura je popis grana tipa odvojen točka-zarezom :Svaki uvjet je ili (style(), media() ili supports()) ili ključnu riječ drugo, što se uvijek evaluira kao istina.

/* Estructura básica */
propiedad: if(
  style(--estado: activo): valor-1;
  media(width < 700px): valor-2;
  supports(color: lch(60% 50 40)): valor-3;
  else: valor-por-defecto
);

Motor ocjenjuje grane redom. Prvi koji je istinit vraća svoju vrijednostAko nijedan uvjet nije istinit i nema drugog uvjeta, rezultat funkcije je zajamčeno-nevažeće, što se ponaša kao nevažeća vrijednost i dopušta vanjske rezerve dolaze do izražaja (na primjer, zadana vrijednost prilagođenog svojstva ili kaskadna prethodna vrijednost).

Ključni detalj: ako uvjet ili određena vrijednost unutar popisa nije valjana, ne poništava cijelu funkciju; parser nastavlja sa sljedećim parom. To čini if() otporan na kvarove u jednoj točki unutar grana.

Vrste testova: style(), media() i supports()

style(): upiti o stilu

Stilizirajte upite pomoću stil() omogućuju vam da pitate ima li ciljni element određenu vrijednost za svojstvo (posebno korisno s prilagođena svojstva). Za razliku od upita u stilu @container, stil() U if() se evaluira na samom elementu i odmah, bez potrebe da se oslanja na roditelja.

/* Estado embebido en una custom property */
.card {
  --status: attr(data-status type(<custom-ident>));
  border-color: if(
    style(--status: pending): royalblue;
    style(--status: complete): seagreen;
    else: gray
  );
  background-color: if(
    style(--status: pending): #eff7fa;
    style(--status: complete): #f6fff6;
    else: #f7f7f7
  );
}

Unutar stil() Možete koristiti logičke operatore i, or y ne, plus zagrade za grupiranje, što olakšava složene kombinacije država. Imajte na umu da pitanja o stilu @kontejner danas ne podržavaju „normalna“ svojstva (samo prilagođena), dok stil() unutar if() Koristi se za određivanje vrijednosti jednog svojstva samog elementa.

media(): isprepleteni medijski upiti

s prosjek() Vrijednost svojstva možete uvjetovati određenim medijskim upitom, bez odvajanja stila u drugi @media blok. To je idealno kada samo želite promijeniti nekretninu ovisno o okolini.

/* Ejemplo para puntero fino vs grueso */
button {
  aspect-ratio: 1;
  width: if(
    media(any-pointer: fine): 30px;
    else: 44px
  );
}

Ovaj blok je ekvivalentan pisanju osnovnog pravila plus @media što redefinira vlasništvo, ali koncentrira logiku na jednom mjestu. Također možete koristiti vrste medija (na primjer, ispis) ili medijske značajke s logikom i/ili/ne.

/* Media type */
.elemento {
  background: if(
    media(print): white;
    else: #eee
  );
}

/* Media feature con rango */
.caja {
  margin: if(
    media(width < 700px): 0 auto;
    else: 20px auto
  );
}

Ako trebate promijeniti mnogo selektora ili nekoliko svojstava Istovremeno, tradicionalni @media blok je i dalje bolji. Za specifične varijacije jedne izjave, if() je izražajniji.

supports(): upiti za podršku

s podržava() Pitate razumije li preglednik određenu značajku (svojstvo, vrijednost, selektor itd.) i u skladu s tim birate vrijednost. Idealno za progresivno poboljšanje bez dupliciranja @supports blokova.

/* Color de amplia gama si está soportado */
body {
  background-color: if(
    supports(color: oklch(0.7 0.185 232)): oklch(0.7 0.185 232);
    else: #00adf3
  );
}

/* Consulta de soporte de selector */
video {
  outline-width: if(
    supports(selector(:buffering)): 1em;
    else: initial
  );
}

Imajte na umu da za granu s podržava() unutar funkcije if(), sam preglednik mora podrška ako()Stoga je važno definirati čvrste rezervne opcije izvan funkcije.

Učestalost i položaj drugog

Možete koristiti jedan ili više drugih unutar funkcije i postavite ih gdje god želite. Međutim, najčešći način je postavljanje jednog drugo na kraju kao zadanu vrijednost. Ako stavite else na početak, uvijek će pobijediti i sljedeći uvjeti neće biti ocijenjeno.

/* Útil para depurar: colocamos un else intermedio */
.elemento {
  background-image: if(
    style(--flag: on): url("ok.png");
    else: url("debug.png"); /* si la primera no encaja, mostramos pista */
    supports(background: paint(foo)): paint(foo)
  );
}

Osim toga, funkcija ako() sastavljen samo od inače: vrijednost, ili čak prazno, sintaktički je valjano, iako nije baš korisno. Bolje je vrijednost dodijeliti izravno ako nema logike.

Pune, djelomične vrijednosti i ugniježđivanje

Funkcija može uzeti cijelu vrijednost svojstva ili samo njegov dio unutar stenografijaTo omogućuje vrlo ekspresivne kompozicije bez odstupanja od iste izjave, s manje ponavljanja koda.

/* Decidimos solo el color dentro de un shorthand */
.box {
  border: 2px solid if(
    supports(color: lch(60% 50 40)): lch(60% 50 40 / 0.7);
    else: rgb(100 120 200 / 0.7)
  );
}

funkcije ako() mogu se ugnijezditi unutar drugih ako(), a također i u ulogama kao što su izračun()To omogućuje preciznije modeliranje odluka bez dupliciranja selektora ili otvaranja novih blokova.

/* Anidación doble: esquema y preferencia de color */
.elemento {
  color: if(
    style(--scheme: ice): if(
      media(prefers-color-scheme: dark): oklch(85% 0.04 220);
      else: oklch(35% 0.04 220)
    );
    style(--scheme: fire): if(
      media(prefers-color-scheme: dark): oklch(90% 0.1 30);
      else: oklch(40% 0.1 30)
    );
    else: black
  );
}

/* calc() con porcentaje condicionado */
.panel {
  width: calc(
    if(style(--scheme: wide): 70%; else: 50%) - 50px
  );
}

Također možemo koristiti if() za odlučivanje labavi dijelovi nekretnine kao margin-top unutar skraćenice ili određene pozadinske komponente, bez dupliciranja onoga što se ne mijenja.

Praktični primjeri isprepleteni

1) Gumb dostupan ovisno o vrsti pokazivača

Ako uređaj ima fini pokazivač (npr. miš), gumb će biti manji; na zaslonima osjetljivim na dodir povećali smo ga na 44px kako bismo ispunili preporuke za pristupačnost. Jedna izjava, dva ponašanja.

button {
  aspect-ratio: 1;
  width: if(
    media(any-pointer: fine): 30px;
    else: 44px
  );
}

Gornje je ekvivalentno bazi + @media bloku, ali ovako ne širite logiku na više web-mjesta i smanjiti mogućnost pogrešaka.

2) Širok raspon boja s rezervnom mogućnošću

Ako preglednik razumije OKLCH, koristimo tu boju i, usput rečeno, prikazujemo informativnu poruku u ::nakonInače, primjenjujemo sigurni heksadecimalni ključ. Kompatibilnost bez drame.

body {
  background-color: if(
    supports(color: oklch(0.7 0.185 232)): oklch(0.7 0.185 232);
    else: #00adf3
  );
}

body::after {
  content: if(
    supports(color: oklch(0.7 0.185 232)): "Tu navegador admite OKLCH";
    else: "Tu navegador no admite OKLCH"
  );
}

Ako želite istražiti vizualnu razliku između RGB i modernih prostora, pogledajte resursi poput oklch.comVidjet ćete zašto se isplati usvojiti ove prostore kada postoji podrška.

3) Kartice koje se mijenjaju prema statusu korisničkog sučelja

Pohranjuje stanje u status podataka, pročitajte ga s attr() prema prilagođenom svojstvu i donositi odluke s njim stil()Elegantan način za samostalne komponente.

<div class="card" data-status="complete">...</div>

.card {
  --status: attr(data-status type(<custom-ident>));
  border-color: if(
    style(--status: pending): royalblue;
    style(--status: complete): seagreen;
    else: gray
  );
  background-color: if(
    style(--status: pending): #eff7fa;
    style(--status: complete): #f6fff6;
    else: #f7f7f7
  );
}

S ovim uzorkom, promijeniti atribut podataka u HTML-u mijenja više svojstava bez diranja dodatnog CSS-a ili JS-a koji mijenja klase.

Inače i redoslijed evaluacije: kako if() razmišlja

Uvjeti se procjenjuju redoslijedom kojim se pojavljujuPrvi true vraća vrijednost i evaluacija se zaustavlja. Ako nijedan ne prođe, rezultat će biti zajamčeno-nevažeće, što omogućuje vanjske zamjenske vrijednosti (npr. kaskadno prethodnu vrijednost ili zadanu vrijednost preglednika).

Također možete postaviti drugo u sredini Za otklanjanje grešaka: ako želite znati radi li prvi uvjet, postavite naredbu else koja vraća, na primjer, sliku za otklanjanje grešaka i tako dalje. vizualizirate problem jasno.

Rezervne opcije za preglednike bez if()

if() ne uzrokuje magično automatsku degradaciju: potrebna vam je vrijednost rezervacijePrvo stavite naredbu sigurnu za više preglednika, a zatim verziju if() koja je nadjačava kada je podržana. To je preporučeni uzorak.

.box {
  padding: 16px; /* Fallback para navegadores sin if() */
  padding: if(
    style(--size: "2xl"): 24px;
    else: 16px
  );
}

Dakle, preglednici bez if() funkcije koristit će prvi redak; oni koji je podržavaju, procijenit će drugi i zamijenit će ga.

Kompatibilnost i trenutno stanje

programiranje

Prema najnovijim dostavljenim informacijama, Chrome 137 sada omogućuje testiranje funkcije if() a Edge u svojoj ekvivalentnoj verziji nasljeđuje podršku. Drugi izvori podsjećaju da je, osim Chromiuma, implementacija još nije rašireno i da će prijedlog nastaviti sazrijevati u W3C-u, stoga je preporučljivo zadržati realna očekivanja.

Neke procjene govore o otprilike ~47% pokrivenosti za sada (u trenutku prvog izdanja). Moja preporuka je da ga koristite u produkciji samo ako kontrolirate okruženje ili ako vaša rezervna strategija je čvrst; u suprotnom, nanosite ga u progresivnim slojevima ili u kontroliranim uvjetima.

Odnos s @media, @supports i @container

Pravila if() i at se nadopunjuju, a ne isključuju međusobno. @media ili @supports su i dalje bolji kada želite primijenite potpune skupove pravila na više svojstava/selektora. if() je odličan kada vam je potreban pravovremena odluka o jednoj vrijednosti, zadržavajući logiku vezanu uz nekretninu, što olakšava održavanje.

U dizajnu orijentiranom na komponente, dvojac @kontejner (kako bi se prilagodio rasporedu spremnika) i ako() sa stilom() (za promjenu specifičnih svojstava same komponente) otvara vrlo snažne tokove i manje opširno.

Prijedlog @when i @else

Osim if(), postoje i prijedlozi kao što su @when / @else koji postavljaju uvjete na razini pravila, sa sintaksom osmišljenom za bolje čitati složene uvjete koji, s povezanim @media i @supports, postaju teški za održavanje.

@when media(width <= 600px) {
  .container { display: flex; flex-direction: column; }
}
@else {
  .container { display: flex; flex-direction: row; }
}

Možete kombinirati i, ili, ne i koristite zagrade za grupiranje. U trivijalnim slučajevima, @media je dovoljan, ali u bogatijim kombinacijama @when/@else dobiva na čitljivosti.

@when media(width <= 600px) and supports(display: grid) {
  /* ... */
}
@else media(width >= 600px) and supports(display: flex) {
  /* ... */
}
@else {
  /* Fallback final */
}

Ova pravila se još uvijek razvijaju i njihova stvarna provedba može potrajati, ali im je cilj pojednostaviti proširene uvjete na razini stilskog lista.

Obrasci, ograničenja i savjeti

  • Održavajte grane urednima radi vjerojatnosti i jasnoće. Prvi točan odgovor pobjeđuje, stoga sortirajte imajući na umu performanse i čitljivost.
  • Koristiti inače konačno kao zadanu vrijednost; ako je pomaknete naprijed, skraćujete evaluaciju od ostalih uvjeta.
  • Zapamtite da if() odlučuje jednu nekretninu istovremenoAko trebate promijeniti puno stvari odjednom, razmislite o @media/@supports ili njihovoj podjeli u više naredbi.
  • u otklanjanje pogrešaka, dodajte naredbu else između sa svijetlom bojom ili slikom upozorenja. Brzo ćete vidjeti koja grana ne radi.
  • Kombinirati s prilagođena svojstva izvoziti stanja iz HTML-a (atributi podataka) ili iz drugih selektora i odlučivati ​​o vrijednostima bez JS-a.
  • Izbjegavajte zloupotrebu vrlo dugih lančanih uvjetnih naredbi; ako izgubite čitanje, vrijeme je za logika izdvajanja na drugo mjesto.

Brza usporedba s „uobičajenim“

Prije: base + @media/@supports s prepisivanjima; sada: if() isprepleteno bez cijepanja logike. Manje CSS-a, više lokalne kohezije u deklaraciji. Održavanje pobjede.

Prije: JS za prebacivanje klasa ili stanja; sada: prilagođena svojstva + stil() odlučiti o svojstvima. Pomoću if() smanjujete ovisnost o imperativni kod za jednostavne vizualne varijacije.

Bilješke o implementaciji i buduće kombinacije

Pojava funkcije if() podudara se s drugim linijama evolucije jezika: upiti o stilu po narudžbi, moguće upiti raspona integrirano u budućnost i prijedlog @funkcija za prilagođene funkcije. Zajedno, ovi dijelovi privlače više deklarativni i kompozibilni.

Za sada se usredotočite na tri dostupna testa (stil(), prosjek(), podržava()) i učvrstite svoju rezervnu strategiju. S Chromeom 137 sada možete započeti prototip i mjera stvarni utjecaj na vašu kodnu bazu.

Ideja o "uvjetima u CSS-u" prešla je put od puste želje do konkretnog alata koji se, uz nijanse, sada može koristiti u kompatibilnim okruženjima. Pomoću if(), stilovi dobivaju isprepletena logika, manje ponavljanja i bolja enkapsulacija, i savršeno se uklapa s prilagođenim varijablama, atributima podataka i medijskim upitima. Iako njegova podrška još nije univerzalna, usvajanje progresivnih obrazaca i priprema za rezervne opcije omogućit će vam da već danas počnete imati koristi od načina razmišljanja o CSS-u koji je bliži načinu na koji dizajniramo sučelja: donošenje odluka upravo tamo gdje se primjenjuju.