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

  • if() omogućava uslovnu logiku na CSS vrijednostima sa style(), media() i supports().
  • Uslove procijenite redom; prvi tačan vraća njegovu vrijednost, a ostali pokrivaju.
  • Idealno za promjenu svojstva bez otvaranja @media/@supports; koristite rezervne opcije radi kompatibilnosti.
  • Kombinujte sa prilagođenim svojstvima i atributima podataka za autonomnije komponente.

Šta 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 Nekada su nam omogućavali da mijenjamo stilove na osnovu konteksta. Sada dolazi nova funkcija koja podiže ljestvicu i bolje se uklapa u način na koji razmišljamo prilikom dizajniranja: uslovna funkcija if() direktno u vrijednostima svojstava.

Nije dim: Počevši od Chromea 137, možete testirati if() za kreiranje inline stilova s ​​uvjetnom logikom zasnovanom na stilu, medijima i upitima za podršku. Međutim, podrška je i dalje ograničena izvan Chromiuma, pa je najbolje koristiti je mudro. kombinovanje sa rezervnim opcijama za preglednike koji ga ne razumiju.

Šta je bilo prije: „uslovni izrazi“ koje smo već koristili u CSS-u

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

  • @mediaPrimjenjuje pravila ako prozor ili uređaj ispunjava kriterij (širina, orijentacija, pokazivač itd.).
  • @supportsAktivira stilove ako preglednik prepoznaje funkciju ili vrijednost.
  • @kontejner: reaguje na veličinu ili stil kontejnera, korisno za dizajn zasnovan na komponentama.
  • var() sa zadanom vrijednošću: nije if, ali dozvoljava „ako varijabla ne postoji, koristi ovu rezervnu opciju“.

Ovi pristupi su moćni, iako su „vezani“ za svoju svrhu: mediji, podrška ili kontejneriFunkcija if() ne zamjenjuje ove alate; umjesto toga, ona ih besprijekorno integrira. interkalirani i granularni u vrijednostima nekretnina.

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

Web dizajn

Funkcija ako() Omogućava vam da unutar vrijednosti svojstva definirate listu parova uslov:vrijednost, koji se evaluiraju po redoslijedu. Kada je prvi uslov ispunjen, njemu pridružena vrijednost će biti 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 uslova: stil() (upiti stila na samom elementu), prosjek() (upiti medija) i podržava() (upiti za podršku funkcijama). Osim toga, možete dodati inače: vrijednost da pokrije slučaj gdje ništa drugo ne odgovara.

Detaljna sintaksa i evaluacija

Opšta struktura je lista grana tipa odvojena tačkom-zarezom :Svaki uslov je ili (style(), media() ili supports()) ili ključnu riječ drugo, što se uvijek evaluira kao tačno.

/* 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 procjenjuje grane po redu. Prvi koji je tačan vraća svoju vrijednostAko nijedan uslov nije tačan i nema drugog uslova, rezultat funkcije je zagarantovano-nevažeće, što se ponaša kao nevažeća vrijednost i dozvoljava vanjske rezervne opcije dolaze do izražaja (na primjer, zadana vrijednost prilagođenog svojstva ili kaskadna prethodna vrijednost).

Ključni detalj: ako je uslov ili određena vrijednost unutar liste nevažeća, ne poništava cijelu funkciju; parser nastavlja sa sljedećim parom. Ovo čini if() otporan na kvarove na jednoj tački unutar grana.

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

style(): upiti o stilu

Stilizirajte upite pomoću stil() omogućavaju vam da pitate da li ciljni element ima određenu vrijednost za svojstvo (posebno korisno sa prilagođena svojstva). Za razliku od upita u stilu @container, stil() U if() funkciji, vrijednost se procjenjuje na samom elementu i to odmah, bez potrebe za oslanjanjem 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 pojedinačnog svojstva samog elementa.

media(): isprepleteni medijski upiti

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

/* 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 koncentriše logiku na jednom mjestu. Također možete koristiti vrste medija (na primjer, štampa) ili medijske funkcije 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 trebaš 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

con podržava() Pitate da li preglednik razumije određenu funkciju (svojstvo, vrijednost, selektor itd.) i shodno tome birate vrijednost. Idealno za progresivno poboljšanje bez dupliranja @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 sa podržava() unutar funkcije if(), sam preglednik mora podrška za if()Stoga je važno definirati čvrste rezervne opcije izvan funkcije.

Učestalost i pozicija 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 uslovi 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, je sintaktički valjano, iako nije baš korisno. Bolje je direktno dodijeliti vrijednost ako nema logike.

Pune, djelomične vrijednosti i ugniježđivanje

Funkcija može uzeti cijelu vrijednost svojstva ili samo njegov dio unutar stenografijaOvo omogućava vrlo ekspresivne kompozicije bez odstupanja od iste izjave, sa 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 calc()Ovo omogućava preciznije modeliranje odluka bez dupliranja 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() da odlučimo rastresiti dijelovi nekretnine kao margina na vrhu unutar skraćenice ili određena pozadinska komponenta, bez dupliranja onoga što se ne mijenja.

Praktični primjeri isprepleteni

1) Dugme je dostupno u zavisnosti od tipa pokazivača

Ako uređaj ima fini pokazivač (npr. miš), dugme će biti manje; na ekranima 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-lokacija i smanjuju mogućnost grešaka.

2) Širok raspon boja s rezervnim opcijama

Ako preglednik razumije OKLCH, koristimo tu boju i, usput rečeno, prikazujemo informativnu poruku u ::poslijeU suprotnom, 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 interfejsa

Pohranjuje stanje u status-podataka, pročitajte to sa attr() prema prilagođenom svojstvu i donositi odluke s njim stil()Elegantan način da 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 dodirivanja dodatnog CSS-a ili JS-a koji mijenja klase.

Else i redoslijed evaluacije: kako if() razmišlja

Uslovi se procjenjuju redoslijedom kojim se pojavljujuPrvi tačan rezultat vraća vrijednost i evaluacija se zaustavlja. Ako nijedan ne prođe, rezultat će biti zagarantovano-nevažeće, što omogućava vanjske alternative (npr. kaskadno dodavanje prethodne vrijednosti ili zadanu vrijednost preglednika).

Možete i postaviti drugo u sredini Za otklanjanje grešaka: ako želite znati da li prvi uslov ne funkcioniše, 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() funkcije

if() ne uzrokuje magično automatsku degradaciju: potrebna vam je vrijednost rezervacijePrvo stavite naredbu sigurnu za više preglednika, a zatim verziju funkcije if() koja je poništava 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 funkcije if() će koristiti prvu liniju; oni koji je podržavaju će procijeniti drugu i zamijenit će ga.

Kompatibilnost i trenutni status

Programiranje

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

Neke procjene govore o otprilike ~47% pokrivenosti za sada (u vrijeme njegovog 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 okruženjima.

Odnos sa @media, @supports i @container

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

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

Prijedlog @when i @else

Pored funkcije if(), postoje i predlozi kao što su @kada / @drugo koji postavljaju uvjete na nivou pravila, sa sintaksom dizajniranom da bolje čitati složene uslove što, sa @media i @supports povezanim zajedno, postaje teško održavati.

@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 dobija 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 primjena može potrajati, ali im je cilj pojednostaviti proširene uvjetne izraze na nivou stilskog lista.

Obrasci, ograničenja i savjeti

  • Održavajte grane urednima radi vjerovatnoće i jasnoće. Prvi tačan odgovor pobjeđuje, pa sortirajte imajući na umu performanse i čitljivost.
  • SAD inače konačno kao zadanu vrijednost; ako je podesite unaprijed, skraćujete evaluaciju od ostalih uslova.
  • Zapamtite da if() odlučuje jedna nekretnina po jednaAko trebate promijeniti mnogo stvari odjednom, razmislite o @media/@supports ili njihovom dijeljenju u više naredbi.
  • para otklanjanje grešaka, dodajte naredbu else između sa svijetlom bojom ili slikom upozorenja. Brzo ćete vidjeti koja grana ne radi kako treba.
  • Kombinujte sa 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 uslovnih izraza; ako izgubite čitanje, vrijeme je da logika izdvajanja na drugo mjesto.

Brzo poređenje sa „uobičajenim“

Prije: base + @media/@supports s prepisivanjem; 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() da se odrede svojstva. Pomoću if() smanjujete ovisnost o imperativni kod za jednostavne vizualne varijacije.

Bilješke o implementaciji i buduće kombinacije

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

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

Ideja o "uslovima u CSS-u" je od puste želje postala konkretan alat koji se, uz nijanse, sada može koristiti u kompatibilnim okruženjima. Sa if(), stilovi dobijaju... 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 interfejse: donošenje odluka tačno tamo gdje su primjenjive.