CSS-valitsimet, jatkomateriaali

Esitiedot

Tämä sivu jatkaa siitä, mihin kurssin ITKP1011 valitsinluento päättyy. Oletuksena on, että osaat jo perusvalitsimet, yhdistelmävalitsimet ja pseudoluokat :link, :visited, :hover, :first-child, :last-child ja :root.

Käsitteet äitielementti, lapsi, jälkeläinen, esi-isä ja sisarus oletetaan tunnetuiksi; perussivun luku 1 kertaa ne.

Oppimistavoitteet

Tämän materiaalin jälkeen sinun pitäisi osata:

1. Attribuuttivalitsimet

Attribuuttivalitsimella elementtejä valitaan niiden HTML-attribuuttien perusteella. Näin esimerkiksi kaikki PDF-linkit tai kaikki ulkoiset linkit voidaan merkitä ilman, että niihin tarvitsee lisätä luokkia käsin.

Attribuuttivalitsimet. Sanat attribuutti ja ominaisuus tarkoittavat eri asioita: attribuutti on HTML:ssä, ominaisuus CSS:ssä.
ValitsinOsuu, kun attribuutin arvo
E[attr]on olemassa, oli se mikä tahansa, myös tyhjä
E[attr="arvo"]on täsmälleen arvo
E[attr~="sana"]on välilyönnillä eroteltu lista, jossa esiintyy sana
E[attr^="alku"]alkaa merkeillä alku
E[attr$="loppu"]päättyy merkkeihin loppu
E[attr*="osa"]sisältää merkit osa missä tahansa kohtaa
E[attr|="fi"]on fi tai alkaa merkeillä fi-. Tarkoitettu kielikoodeille
E[attr="arvo" i]on arvo, isoista ja pienistä kirjaimista riippumatta
a[href^="https://"]    { font-weight: bold; }     /* ulkoiset linkit */
a[href$=".pdf"]::after { content: " [PDF]"; }     /* PDF-linkit */
a[href*="jyu.fi"]      { color: #7a3b12; }        /* oman organisaation linkit */

2. Lisää pseudoluokkia

2.1 Tilan mukaan

Tilaan perustuvat pseudoluokat perussivun kolmen lisäksi.
PseudoluokkaOsuu, kun
:focusElementti on valittuna, esimerkiksi sarkaimella siirryttäessä
:focus-visibleKuten edellinen, mutta vain kun selain arvioi kohdistuksen tarpeelliseksi näyttää. Ei siis hiirellä klikattaessa
:focus-withinElementin sisällä on kohdistus. Kätevä lomakeryhmien korostamiseen
:activeElementtiä painetaan parhaillaan
:targetElementti on se, johon osoiterivin risuaitaosa viittaa

Linkin neljä pseudoluokkaa kirjoitetaan järjestyksessä :link, :visited, :hover, :active. :focus-sääntö voi olla missä kohtaa tahansa, koska se ei osu samaan tilaan muiden kanssa.

2.2 Sijainnin mukaan

Rakenteeseen perustuvat pseudoluokat.
PseudoluokkaOsuu elementtiin, joka
:only-childon äitinsä ainoa lapsi
:nth-child(n)on äitinsä n:s lapsi. Arvoiksi käyvät myös even, odd ja kaavat kuten 3n+1
:nth-last-child(n)on n:s lapsi lopusta laskien
:first-of-type, :last-of-type, :nth-of-type(n)on ensimmäinen, viimeinen tai n:s samannimisistä sisaruksistaan
:emptyei sisällä mitään, ei edes tekstiä
:nth-child ja :nth-of-type eroavat toisistaan

:nth-child(2) osuu elementtiin, joka on äitinsä toinen lapsi riippumatta siitä, minkä niminen se on. p:nth-of-type(2) taas osuu toiseen p-elementtiin sisarusten joukossa, vaikka välissä olisi muunnimisiä elementtejä.

Vanhoissa ohjeissa :nth-of-type(4n) selitetään joskus muodossa "joka neljäs elementti". Se ei pidä paikkaansa: laskenta tapahtuu aina samannimisten sisarusten kesken.

<div>
  <h3>Otsikko</h3>      <!-- :nth-child(1), h3:nth-of-type(1) -->
  <p>Eka</p>            <!-- :nth-child(2), p:nth-of-type(1)  -->
  <p>Toka</p>           <!-- :nth-child(3), p:nth-of-type(2)  -->
</div>

2.3 Lomakekenttien tila

Lomakkeisiin liittyvät pseudoluokat.
PseudoluokkaOsuu kenttään, joka
:checkedon valittu, eli valintaruutu tai valintanappi
:disabled, :enabledon pois käytöstä tai käytössä
:required, :optionalon pakollinen tai vapaaehtoinen
:valid, :invalidläpäisee selaimen tarkistuksen tai ei läpäise
:user-invalidei läpäise tarkistusta ja käyttäjä on jo ehtinyt käsitellä kenttää
Käytä :user-invalid, älä :invalid

Pelkkä :invalid värjää pakolliset kentät virheellisiksi heti sivun latautuessa, ennen kuin käyttäjä on tehnyt mitään. :user-invalid odottaa, että kenttää on kerran käsitelty. Lomakekenttien tarkistuksesta on lisää lomakeluennon luvussa 10.

2.4 Loogiset pseudoluokat

Valitsimia yhdistelevät pseudoluokat.
PseudoluokkaMerkitys
:not(...) Osuu elementteihin, joihin sulkeissa oleva valitsin ei osu
:is(...) Osuu, jos jokin sulkeissa luetelluista valitsimista osuu. Lyhentää pitkiä listoja. Virheellinen valitsin sulkeissa ei kaada koko sääntöä
:where(...) Kuten :is(), mutta spesifisyys on aina nolla. Kätevä oletustyyleissä, jotka halutaan helposti ylikirjoitettaviksi
:has(...) Osuu elementtiin, jonka sisällä tai jälkeen sulkeissa oleva valitsin osuu. Tällä voi valita äitielementin lapsen perusteella
li:not(.valmis)        { font-weight: bold; }   /* kaikki paitsi luokka valmis */
:is(h1, h2, h3) strong { color: #b3261e; }      /* sama kuin h1 strong, h2 strong, h3 strong */
p:has(img)             { text-align: center; }  /* kappale, jonka sisällä on kuva */
label:has(+ input:required)::after { content: " *"; }
:has() on uusi ja tärkeä

Pitkään CSS:ssä ei ollut lainkaan tapaa valita elementtiä sen sisällön perusteella, ja siksi vanhoissa ohjeissa neuvotaan lisäämään luokkia käsin. :has() on ollut tuettuna kaikissa yleisissä selaimissa vuodesta 2023, ja se poistaa suuren osan noista luokista. Huomaa silti, ettei CSS:ssä vieläkään voi valita elementtiä sen tekstisisällön perusteella.

:is() pelastaa pilkkulistan

Jos pilkulla erotellussa valitsinlistassa on yksi valitsin, jota selain ei ymmärrä, koko sääntö hylätään eikä mikään sen valitsimista toimi. :is()-pseudoluokan sisällä virheellinen valitsin ohitetaan ja muut jäävät voimaan.

3. Pseudoelementit

Pseudoelementti ei valitse olemassa olevaa elementtiä vaan osan elementistä tai luo elementille kuvitteellisen osan. Pseudoelementti kirjoitetaan kahdella kaksoispisteellä, mikä erottaa sen pseudoluokasta.

Tavallisimmat pseudoelementit.
PseudoelementtiKohdistuu
::beforeElementin sisällön alkuun luotavaan osaan
::afterElementin sisällön loppuun luotavaan osaan
::first-letterEnsimmäiseen kirjaimeen
::first-lineEnsimmäiseen riviin sellaisena kuin se selaimessa taittuu
::markerListan numeroon tai pallukkaan
::placeholderLomakekentän vihjetekstiin
::selectionKäyttäjän maalaamaan tekstiin
::before lisää sisällön elementin sisään

Vanhoissa ohjeissa sanotaan, että ::before lisää sisältöä "ennen elementtiä". Se on harhaanjohtavaa: sisältö tulee elementin sisään, sen oman sisällön eteen. Mitään ei siis synny elementin ulkopuolelle, eikä sisältöä voi sijoittaa kahden elementin väliin.

p::before { content: "Huomaa: "; }

Tuottaa saman lopputuloksen kuin jos olisit kirjoittanut HTML:ään:

<p><span>Huomaa: </span>Kappaleen oma teksti.</p>

::before ja ::after vaativat aina content-ominaisuuden. Ilman sitä mitään ei synny. Arvo voi olla merkkijono, tyhjä merkkijono "", attribuutin arvo attr(href) tai laskurin arvo.

Älä laita olennaista tietoa content-ominaisuuteen

Sisältö kuuluu HTML-dokumenttiin. content-ominaisuudella tuotettu teksti on ulkoasua: se ei näy ilman tyylitiedostoa, sitä ei voi maalata ja kopioida kaikissa selaimissa, eivätkä apuvälineet käsittele sitä johdonmukaisesti. Käytä sitä koristeisiin, merkkeihin ja numerointiin, älä leipätekstiin.

3.1 Automaattinen numerointi laskureilla

Laskurilla otsikot tai muut elementit voidaan numeroida automaattisesti, jolloin numerot pysyvät oikeina vaikka väliin lisättäisiin uusi luku. Tarvitaan kolme asiaa:

body {
  counter-reset: osa;
}

h1 {
  counter-increment: osa;
  counter-reset: luku;      /* jokainen osa aloittaa lukunumeroinnin alusta */
}

h1::before {
  content: "Osa " counter(osa) ". ";
}

h2 {
  counter-increment: luku;
}

h2::before {
  content: counter(osa) "." counter(luku) " ";
}

Tuloksena otsikot numeroituvat muotoon Osa 1., 1.1, 1.2, Osa 2., 2.1 ja niin edelleen.

4. Spesifisyys

Spesifisyys tämän sivun valitsimilla.
ValitsinSpesifisyys
li::marker0, 0, 2 (pseudoelementti lasketaan kuin elementti)
li:nth-child(2)0, 1, 1 (pseudoluokka lasketaan kuin luokka)
a[href$=".pdf"]0, 1, 1 (attribuutti lasketaan kuin luokka)
:is(h1, h2) strong0, 0, 2 (:is() saa spesifisimmän argumenttinsa arvon)
:where(h1, h2) strong0, 0, 1 (:where() ei lisää mitään)
p:not(.varoitus)0, 1, 1 (:not() saa argumenttinsa arvon)

5. Lisätietoa

Käyttäjien kommentit

Kommentoi Lisää kommentti