Skip links en inhoudsopgave

Selector, identiteit, class, specificiteit: hoe overleef ik de nieuwe klassenstrijd?

Laatst aangepast: .

www.css-voorbeelden.nl

Als je dit artikel afdrukt, wordt automatisch een printvriendelijke versie afgedrukt.
Dit artikel is van toepassing op alle browsers op alle systemen.
Links in dit artikel, vooral links naar andere sites, kunnen verouderd zijn. Op de pagina met links vind je steeds de meest recente links.
Tekst die tussen << en >> staat, is een link naar internet.
Tekst die omgeven is door een lijn (meestal een stippellijn), verwijst naar een andere plaats binnen het artikel. Op de site zijn dit ankers, maar dat werkt nou eenmaal niet op papier.

Algemene opmerkingen

Dit artikel gaat alleen over simpele selectors: alleen namen van elementen, id's en classes, en combinaties daarvan. En als toetje de universele selector. Alles wat ingewikkelder is dan dat komt mogelijk ooit nog eens in 'n ander artikel aan bod, maar niet hier.

Pseudo-elementen en pseudo-classes worden hier alleen besproken, voor zover ze van belang zijn voor de specificiteit. De werking ervan wordt hier verder niet besproken.

Als je nou denkt: wat heb ik er dan aan?, dan is dit artikel waarschijnlijk niet erg nuttig voor jou. Als je daarentegen bij een pseudo-class alleen aan Marx, die leuke klassenleraar of een enge tropische ziekte kunt denken, dan vind je in dit artikel misschien wel wat nuttige informatie.

Wat is nou eigenlijk het nut van CSS?

Een pagina met HTML is opgebouwd uit elementen als een <p>, een <div>, een <h2>, enzovoort. De soort element wordt aangegeven met behulp van een tag. Deze begint altijd met < en eindigt altijd met >. Daartussen staat de soort element. (De meeste elementen hebben ook een eind-tag. Deze begint met </, maar die zijn verder niet interessant voor CSS.)

De meeste elementen hebben standaard-instellingen. Zo heeft een <p> automatisch een marge aan de boven- en aan de onderkant. Daar is geen CSS voor nodig, deze marge is er automatisch, zodra je een <p> gebruikt.

Als deze standaard-instellingen niet bevallen, kun je die veranderen. Vroeger kon dat alleen met HTML. Als je een andere lettergrootte wilde, moest je voor elk element die andere lettergrootte opgeven met het element <font>. Er bestond een groot aantal van dat soort elementen, die eigenlijk alleen maar voor de opmaak dienden.

Dat leverde een enorme hoeveelheid extra code op en maakte sites ook moeilijk toegankelijk voor schermlezers en dergelijke. Het onderhoud van zo'n site is een nachtmerrie.

Als je expert bent op het gebied van de paringsdans van de Kleine Wilde Amazone-mier, wil je daar natuurlijk een website over maken. En omdat je 'n échte expert bent, krijgt die site honderden pagina's. Vanzelfsprekend heeft de expert hele goede ogen, want anders zou hij de paringsdans van de kleine miertjes niet hebben kunnen bestuderen. Hij gebruikt dus geen zwarte letter, maar een mooi kleurtje op een frisse achtergrond. Lekker apart.

Waarop het klachten regent van bezoekers. Die willen wel lezen, maar hebben zelf nooit paringsdansen van kleine mieren bekeken, dus hebben ze moeite met de mooie lichtblauwe letters op de frisse grijze achtergrond. De letters moeten dus 'n andere kleur krijgen.

Op elk van die honderden pagina's staat enkele tientallen keren de letterkleur aangegeven. Dat is op de hele site enkele duizenden keren. Die allemaal veranderd moeten worden. Daar gaan de goede ogen en het goede humeur van de expert.

En dan gaat het alleen nog maar over de letterkleur...

Het zou fantastisch zijn als er een manier bestond, waarmee je op één centrale plaats die letterkleur (en allerlei andere dingen natuurlijk, de hele opmaak) zou kunnen veranderen. Die manier bestaat: CSS. Met behulp van CSS kun je vanuit één (of enkele) centrale bestanden het uiterlijk van een hele site aansturen. Zo'n bestand heet een stijlbestand, in het Engels stylesheet.

Naast het veel makkelijker onderhoud wordt de site ook veel toegankelijker voor zoekmachines, schermlezers, en dergelijke. Bovendien wordt de site sneller geladen, omdat de bestanden veel en veel kleiner zijn.

Om allerlei redenen, waarvan er 'n paar hierboven staan, wordt het gebruik van HTML voor opmaak (zoals <font>) al meer dan twintig jaar afgeraden. In het in 2012 ingevoerde HTML5, de huidige versie van HTML, wordt het niet meer afgeraden: het is ronduit verboden.

Inmiddels is CSS zo veelzijdig dat je er ook bijvoorbeeld allerlei animaties mee kunt maken. Iets wat vroeger alleen met behulp van JavaScript kon.

HTML, CSS, enzovoort werken via internationale standaarden. CSS wordt bijgehouden door w3c, HTML door w3c en WHATWG. Als je zeker wilt weten dat je site ook in de toekomst bekeken kan worden, is het belangrijk volgens die standaarden te werken. En HTML voor opmaak valt buiten die standaarden.

Nog even een waarschuwing. CSS is bedoeld voor de lay-out, de opmaak, van de pagina. Er horen geen inhoudelijke dingen in te staan. Inhoud hoort in de HTML. Net zoals JavaScript alleen gebruikt hoort te worden voor extra's. Als de echte informatie van de site in de HTML staat, en niet afhankelijk is van CSS en/of JavaScript en dergelijke, is de pagina ook toegankelijk voor schermlezers en dergelijke.

Helemaal haalbaar is dit niet, want het zal nooit mogelijk zijn een volledig voor blinden toegankelijke slideshow te maken, om maar iets te noemen. Maar je kunt het wel zo goed mogelijk proberen. Overigens is de spider van een zoekmachine (die indexeert je site) redelijk te vergelijken met een blinde, dus het is ook in je eigen belang om een site toegankelijk te maken.

Je moet om nog een andere reden niet volledig op CSS (of JavaScript, of ...) vertrouwen. CSS, JavaScript, en dergelijke kunnen worden uitgezet. Gebruikers kunnen eigen CSS hebben opgegeven of zelf JavaScript tussenvoegen, die jouw CSS overrulet. Bijvoorbeeld omdat ze moeite hebben met contrast en dus bepaalde kleuren afdwingen.

Dat is allemaal niet zo'n probleem, als je er maar enigszins rekening mee houdt. Een site is nou eenmaal iets totaal anders dan een gedrukt stuk papier, waar niets meer aan veranderd kan worden, nadat het is gedrukt. Ook zonder CSS (en zonder JavaScript, zonder...) hoort een site nog alle feitelijke inhoud toegankelijk te maken. Tekst, links, essentiële afbeeldingen, enzovoort moeten nog steeds zichtbaar zijn en werken. Alleen extra's mogen verdwijnen.

Hoe koppel je bepaalde CSS aan bepaalde elementen?

Als je de opmaak wilt bepalen met behulp van CSS, moet je op een of andere manier bepaalde CSS aan bepaalde elementen koppelen. Als je de gewone tekst zwart wilt hebben, maar alle <h2>'s oranje, moet je dat onderscheid kunnen maken. En misschien wil je wel de meeste <h2>'s oranje, maar eentje gifgroen.

Inline-stijl

Soms zie je CSS gebruikt worden op dezelfde manier als in het verleden de opmaak-tags van HTML:

<p style="color: black; background: white;">

Bij elke tag staat de CSS die bij die tag hoort: een inline-stijl. Omdat de CSS gelijk achter de tag staat, hoef je verder niet aan te geven, bij welk HTML-element de CSS hoort.

Dat is dan ook het enige voordeel. Als je iets wilt veranderen, moet je dat nog steeds op achtduizend plaatsen doen. De bestanden zijn nog steeds groter dan nodig. Bovendien kunnen dingen als :hover nooit werken met een inline-stijl. enzovoort, enzovoort.

Een inline-stijl kan wel uiterst handig zijn bij het maken van een pagina, om even snel iets uit te proberen, of om erachter te komen waarom de foto van ome Piet pertinent weigert naast z'n echtgenote tante Klazina te blijven staan, maar steeds bovenop de foto van de buurvrouw springt. (Disclaimer: dit is slechts een verzonnen voorbeeld. Elke overeenkomst met de werkelijkheid berust op toeval.)

Stijlregels

Met uitzondering van de methode hierboven, waarbij de CSS gelijk achter de bijbehorende tag staat, moet op een of andere manier worden duidelijk gemaakt, bij welk element bepaalde CSS hoort. Dit gebeurt met behulp van een stijlregel. Bij zowel een stijlblok in de <head> van een pagina als bij een extern stijlbestand gebeurt dit op dezelfde manier.

Een stijlregel is altijd op dezelfde manier opgebouwd:

p {color: black; background: white;}

Tussen de accolades staat de eigenlijke CSS. Dat zijn altijd één of meer eigenschappen met bijbehorende waarde of waarden. Vóór de openings-accolade staat de eigenlijke selector. Deze bepaalt, waarvoor de CSS geldt, en om dat deel gaat het hier. De CSS die tussen de accolades staat, heeft geen invloed op waar de CSS voor bedoeld is. De selector voor de openings-accolade selecteert, waar de CSS voor geldt.

Enkele selector

In bovenstaande regel is de selector de p. Deze hoort bij het element <p>. De selector is gewoon de naam van het element, zonder de < en >. Bij een <p> houd je dan dus een p over, bij een <div> div, bij een <h1> h1, enzovoort.

Omdat in de bovenstaande regel alleen een p staat, heet dit een enkele selector. Enkel, omdat er maar één element wordt genoemd. Selectors kunnen enorm ingewikkeld worden, dit is de meest simpele vorm.

Deze selector is heel eenvoudig. Dat is lekker makkelijk, maar het nadeel is dat hij heel grof is. Omdat er geen enkele beperking is, geldt deze selector voor álle <p>'s. Zonder uitzondering. Heel vaak is dat te grof, omdat bijvoorbeeld niet alle tekst dezelfde kleur moet krijgen, dezelfde lettergrootte, enzovoort.

Meerdere selectors

Het komt vaak voor dat meerdere elementen dezelfde CSS moeten krijgen:

p {color: black; background: white;} h1 {color: black; background: white;} div {color: black; background: white;}

Dit is maar heel weinig CSS, maar als er ook nog een border, outline, enzovoort bij komen, wordt dit natuurlijk onwijs veel. Gelukkig kun je in één stijlregel meerdere selectors gebruiken:

p, h1, div {color: black; background: white;}

In de onderste regel staat precies hetzelfde als in de drie afzonderlijke regels daarboven. De drie selectors worden gewoon achter elkaar gezet, vóór de eerste accolade, gescheiden door een komma. Je kunt zo een onbeperkt aantal selectors dezelfde CSS geven.

Let er wel op dat je de komma niet vergeet. Zonder komma krijg je een Gecombineerde selector, zoals gelijk hieronder wordt beschreven, en dat is heel wat anders dan twee afzonderlijke selectors.

Gecombineerde selector

Ook in Nederland wordt deze selector vaak met zijn Engelse naam aangeduid: descendant selector. 'Descendant' betekent 'nakomeling'. Bij selectors, HTML, en dergelijke wordt een indeling gebruikt, die heel erg lijkt op die van een familie.

div h2 {font-size: 1.2em;}

In bovenstaande regel is de selector div h2. De standaard-lettergrootte van een <h2> wordt verkleind tot 1,2 em. Maar dit geldt hier niet voor élke <h2>. Omdat h2 volgt op een div en een spatie, geldt het hier alleen voor een <h2> die binnen een <div> staat.

De h2 is een 'descendant', een nakomeling, van de div. <h2>'s die buiten een <div> staan, worden niet beïnvloed door deze regel, omdat ze niet aan de voorwaarde van de selector voldoen: ze zijn geen nakomeling van een <div>.

Op deze manier is het mogelijk om, met twee stijlregels, alle <h2>'s rood te maken, behalve als ze binnen een <div> staan. Die maak je met behulp van een tweede regel groen:

h2 {color: red;} div h2 {color: green;}

Door op zo'n manier elementen te combineren krijg je al iets meer mogelijkheden. Dit kan in theorie heel diep gaan:

div p span strong abbr {...}

Een <abbr>, maar alleen als die binnen een <strong> staat, maar alleen als die <strong> binnen een <span> staat, maar alleen als die <span> binnen een <p> staat, maar alleen als die <p> binnen een <div> staat. Alleen als aan ál deze voorwaarden is voldaan, geldt deze regel.

Toch zijn deze gecombineerde selectors nog steeds vaak veel te grof. Want wat als je alleen elke tweede <h2> binnen een <div> groen wilt maken? Of alleen de zevende, maar niet in élke <div>?

Daarvoor moeten we het element in een class indelen of het 'n naam geven, een identiteit.

class en id

Er zijn drie manieren om een naam te geven aan een element: name, class en id(entity). Daarvan hebben alleen class en id met CSS te maken. name kan, wat CSS betreft, alleen worden gebruikt in de attribuut-selector en wordt hier verder niet besproken.

Class

Een class is te vergelijken met een schoolklas. Een schoolklas bestaat uit een (groot) aantal kinderen. Een class bestaat uit een (groot) aantal elementen. En zoals kinderen uit een klas hetzelfde krijgen te leren, krijgen die elementen allemaal precies dezelfde CSS. (Voordat woeste ouders beginnen te klagen: bij kinderen wordt dat hopelijk wel enigszins individueel aangepast.)

Om een element lid te maken van een class, moet je het element in de HTML indelen in een class:

<p class="tekst">Deze <p> zit in de class 'tekst'</p>

De bijbehorende stijlregel:

p.tekst {color: black; background: white;}

Om aan te geven dat tekst de naam van een class is, wordt die in de CSS voorafgegaan door een punt. p.tekst wil dus zeggen: alle <p>'s die de class-naam 'tekst' hebben. Dat kan één <p> zijn, maar het kunnen er ook driehonderd of drieduizend zijn (hoewel er dan waarschijnlijk betere manieren zijn, maar dat voert hier te ver).

Je mag zo vaak als je wilt dezelfde class gebruiken op een pagina, ook met verschillende soorten elementen. Als je ook een <h1> met dezelfde kleuren hebt als de p.tekst hierboven, komt die er gewoon bij te staan in de CSS:

p.tekst, h1.tekst {color: black; background: white;}

De verschillende selectors worden gescheiden door een komma, net als bij meerdere selectors zonder class.

Ook de gecombineerde selector kun je gebruiken:

p.tekst, div h2.tekst {color: black; background: white;}

Deze CSS is geldig voor álle <p>'s met class="tekst". Daarnaast is hij geldig voor de <h2>'s met class="tekst", maar alleen als die binnen een <div> staan. Dit werkt precies hetzelfde als bij alle gecombineerde selectors.

Ook een stijlregel als de volgende is mogelijk:

.tekst {color: black; background: white;}

Nu wordt élk element, ongeacht welke soort het is, met een class="tekst" aangesproken. De punt geeft aan dat het om een class gaat, en omdat er geen enkel element voor staat, worden automatisch álle elementen verondersteld.

Selectors met een class kunnen ook gewoon worden gecombineerd met selectors met een id. Pardon, een id?

id

Als de hele klas een musical aan het zingen is, is het fantastisch als ze allemaal netjes de maat houden en zo. Hoe meer ze hetzelfde doen, hoe beter het is. De klas gedraagt zich, en moet zich gedragen, als een class.

Maar als er een spreekbeurt gehouden moet worden, is het wat onhandig als de hele klas naar voren rent en hetzelfde verhaal begint op te dreunen. Bij een spreekbeurt horen we liever een individu, iemand met een eigen persoonlijke identiteit, een id, niet de hele class.

Om degene die de spreekbeurt gaat houden aan te kunnen spreken, moet die een naam, een eigen identiteit, hebben. Bij kinderen uit een klas is dat een kindernaam, bij CSS is dat een id.

id is een afkorting van identity. Het belangrijkste verschil met een class is dat een id maar één keer gebruikt mag worden op een pagina. Ook al zijn het verschillende elementen, ze mogen toch niet dezelfde id hebben.

Anders dan bij kinderen met dezelfde naam uit één klas, kun je bij een technische taal prima regelen dat er geen twee id's met dezelfde naam op één pagina staan: gewoon verbieden. Kinderen met dezelfde naam kun je ook wel verbieden, maar dat levert toch al snel ernstige ethische en juridische problemen op.

Het is vrij makkelijk om twee keer dezelfde id te gebruiken op één pagina. Soms gaat dat goed, soms levert dat een volledig verstoorde pagina op. Daar is weinig zinnigs over te zeggen: het ligt eraan, waar de dubbele id toevallig staat, aan de gebruikte browser, enzovoort. Voor het voorkomen van dit soort fouten is een validator ideaal.

Een validator controleert een taal op syntactische fouten: fouten tegen de regels. 'Intelligente' fouten worden meestal niet gevonden. Een afschuwelijke kleurencombinatie wordt enthousiast gevalideerd. Maar iets als een dubbele id vinden, daar is een validator erg goed in.

HTML kan worden gevalideerd op validator.w3.org.

CSS kan worden gevalideerd op jigsaw.w3.org/css-validator.

Om een element een id te geven, moet je het in de HTML gewoon de naam van een id geven:

<p id="tekst">Hier staat, o verrassing, tekst</p>

De bijbehorende stijlregel:

p#tekst {color: black; background: white;}

Om aan te geven dat tekst de naam van een id is, wordt het in de CSS voorafgegaan door een #. p#tekst wil dus zeggen: de <p> die de id 'tekst' heeft. Dat kan per definitie maar één <p> per pagina zijn. Andere elementen op dezelfde pagina mogen niet diezelfde id hebben. Op andere pagina's van dezelfde site mag wel weer dezelfde id worden gebruikt.

Je kunt selectors met en zonder een class of een id gewoon combineren in dezelfde stijlregel. Als je ook een <h1> met dezelfde kleuren hebt als de p#tekst hierboven, komt die er gewoon bij te staan in de CSS:

p#tekst, h1 {color: black; background: white;}

Dit werkt precies hetzelfde als bij alle meerdere selectors.

Ook de gecombineerde selector kun je gebruiken:

p.tekst, div#hoofdstuk h2.tekst {color: black; background: white;}

Deze CSS is geldig voor álle <p>'s met class="tekst". Daarnaast is hij geldig voor de <h2>'s met class="tekst", maar alleen als die binnen een <div> staan. Die <div> moet bovendien een id="hoofdstuk" hebben.

<h2>'s binnen een <div> met bijvoorbeeld een id="footer" (div#footer), of een <div> zonder id, worden niet aangesproken door deze regel. Dit werkt verder precies hetzelfde als bij alle gecombineerde selectors.

Ook een stijlregel als de volgende is mogelijk:

#tekst {color: black; background: white;}

Nu wordt het element met id="tekst", ongeacht welke soort het is, aangesproken. De # geeft aan dat het om een id gaat, en omdat er geen enkel element voor staat, maakt de soort element niet uit. Maar ook hier mag maar één element op een pagina dezelfde id hebben. Zoiets is handig om bijvoorbeeld links naar home op alle pagina's dezelfde CSS te geven:

<a id="home" href="home">Home</a>

Wanneer een class en wanneer een id?

Daar is weinig over te zeggen, wat niet wegneemt dat er complete bibliotheken over vol zijn geschreven door classici en idealisten.

Het belangrijkste verschil is dat je een id maar één keer mag gebruiken op een pagina, en een class zo vaak als je wilt.

Verder heeft een id meer specifiteit, maar dat speelt nauwelijks een rol bij het kiezen voor id of class.

Een echt verschil is het gebruik als anker. Een anker is een plaats binnen een pagina, waar naartoe kan worden gelinkt vanuit dezelfde pagina of vanaf een andere pagina. Elk element met een id kan als anker worden gebruikt:

<h2 id="hier-moet-u-wezen">Wat kom je hier doen?</h2>

Naar deze <h2> kan vanaf elke plek op de pagina worden gelinkt:

<a href="#hier-moet-u-wezen">Klik hier</a>

Vanaf een andere plek op internet zet je er de naam van de pagina en eventueel ook nog de naam van de site bij.

Als een element ook als anker wordt gebruikt, kun je dus beter een id dan een class gebruiken.

Verder is het eigenlijk vooral een kwestie van voorkeur. Op deze site bijvoorbeeld wordt bij de inhoudsopgave bovenaan de pagina's met uitleg id 'nav-inhoud' gebruikt. Een inhoudsopgave mag maar één keer op de pagina staan. Daarom lijkt een id hier meer op z'n plaats. Bijkomend voordeel: als je per ongeluk die id nog 'n keer op dezelfde pagina zou gebruiken, krijg je gelijk een foutmelding als je de HTML valideert.

Veel sitebouwers gebruikten in het verleden ook id's als 'header' en 'footer'. De hele header staat in een <div> met id="header", en de footer in een <div> met id="footer". Dat maakte het een stuk makkelijker om de weg te vinden in het stijlbestand (het bestand met de CSS).

HTML5 heeft een hele serie elementen met namen als <header>, <footer>, <menu>, en dergelijke. Dit maakt het gebruik van dingen als een <div> met id="header" overbodig. Belangrijkste is dat pagina's hierdoor veel beter toegankelijk gaan worden voor schermlezers en dergelijke, en dus ook voor zoekmachines.

Namen van classes en id's

Er zijn wat regels, waaraan namen móéten voldoen, omdat er anders fouten kunnen optreden. Daarnaast zijn er wat dingen, waarvan het handig is om er rekening mee te houden. Dat zijn geen verplichte dingen, maar dingen die helpen misverstanden, slecht leesbare code, en dergelijke te voorkomen.

Geldige namen

Een naam moet met een hoofd- of kleine letter beginnen. Na die beginletter mogen cijfers, verbindingsstreepjes ('-', hyphen in het Engels) en onderstrepingen ('_', underscore in het Engels) worden gebruikt.

Daarnaast mogen ook dubbele punten en punten worden gebruikt. Die kom je eigenlijk nooit tegen, want namen worden daar bepaald niet leesbaarder door. En een JavaScript-bibliotheek als jQuery zou daar, in ieder geval in het verleden, problemen mee hebben.

In feite is het dus heel simpel: beginnen met een letter en alleen letters, cijfers, verbindingsstreepje en onderstreping gebruiken.

Op deze site worden altijd kleine letters gebruikt voor namen van een class of id. In het verleden maakten sommige browsers onderscheid tussen kleine letters en hoofdletters. Er zijn op dat gebied ook verschillen tussen Windows en alle andere besturingssystemen. En de meeste computertalen maken ook verschil tussen hoofd- en kleine letters.

Door alleen kleine letters te gebruiken voorkom je mogelijke problemen. Je kunt ook alleen hoofdletters gebruiken. Of een combinatie. Als het maar steeds hetzelfde is, dan weet je zeker dat er geen problemen ontstaan in een of andere exotische browser of een buitenaards besturingssysteem.

Een veel gebruikte combinatie van hoofd- en kleine letters heet in goed Nederlands CamelCase. (Er bestaat geen Nederlandse vertaling. Het geweldige Google Translate vertaalt het als 'kameelkoffer'...) Hierbij begint elk deel van een naam met een hoofdletter. Iets als hoofdtitel wordt dan hoofdTitel of HoofdTitel.

Beschrijvende namen

Het is geen goed idee de naam van een HTML-tag te gebruiken als naam voor een class of id. In het verleden gaf dat problemen in sommige browsers. Daarnaast is het hoogst verwarrend. Het verschil tussen body en .body in een stijl is maar één puntje verschil in schrijfwijze. Maar in de uitwerking is het het verschil tussen het element <body>, dus de hele pagina, en de class "body", dus alleen de elementen met een class="body". Een wereld van verschil.

Het gebruik van dit soort namen voor classes en id's maakt CSS uiterst moeilijk te begrijpen en is vragen om fouten. Het missen van één rottig puntje kan eindeloze zoekpartijen naar een fout opleveren.

Een hele leuke, die je met enige regelmaat tegenkomt, is het gebruik van namen als "groene-knop" en "rode-knop". Als je deze code leest, is nog wel te begrijpen welk element er wordt bedoeld. Alleen, als je later besluit om 'rood' en 'groen' om te wisselen, omdat dat toch mooier is, zit je dus tot in de eeuwigheid met code die eigenlijk alleen voor een kleurenblinde nog is te volgen. Elke keer moet je eraan denken dat div#groene-knop de rode knop is, en omgekeerd.

Een aardige variant op bovenstaande is die met namen als "span-1", "span-2", (...), "span-327". Over zeven maanden weet je echt niet meer, wat voor soort <span> span-37 is. Terwijl je over zeven maanden nog wel weet wat de bedoeling van <span class="waarschuwing"> is. En heb ook een beetje medelijden met anderen die jouw code moeten lezen, zoals bij vragen op een forum het geval is...

Het is dus beter om geen naam te kiezen, die voor iets staat dat later veranderd kan worden, zoals een kleur of een positie. De naam 'rechterkolom' lijkt in eerste instantie prima. Tot je je realiseert dat het met CSS kinderlijk eenvoudig is om de rechterkolom aan de linkerkant neer te zetten, omdat dat toch beter blijkt te zijn. Hier kan zelfs kleurenblindheid geen redding meer bieden.

Betere namen beschrijven wat het element doet, het zijn beschrijvende namen. Een naam als 'zijkolom' is goed, want een zijkolom zal altijd aan de zijkant staan. De kans dat een zijkolom plotsklaps in het midden wordt neergezet, is niet heel erg groot. 'fout-adres', 'straat', 'telefoon' zijn ook goede namen. De kans dat een straat opeens een telefoon wordt, is ook niet zo heel erg groot.

<code class="html">(...)</code> en <code class="css">(...)</code> zijn prima. De tag maakt duidelijk dat het code is, en de class maakt duidelijk wat voor soort code het is. En met behulp van CSS kun je eventueel het verschil accentueren. De kans dat HTML plotsklaps in CSS verandert, is ook niet heel erg groot.

De combinatie van de juiste HTML-tags en de juiste namen van id's en classes maakt code echt 'n heel stuk begrijpelijker. En voorkomt mede daardoor conflicten tussen verkeerd gebruikte namen.

Conflicten tussen namen van classes en id's kun je ook helpen voorkomen door namen in te delen in groepen. Zo begint op deze site - tenzij dat echt niet anders kan - elke id die als anker binnen de pagina wordt gebruikt met 'a-'. Die begin 'a-' is gereserveerd voor deze 'lokale' id's. Id's die nooit als anker worden gebruikt, beginnen nooit met 'a-'.

Dit voorkomt dat voor een anker een id wordt gekozen, die al wordt gebruikt in een extern stijlbestand. En dat voorkomt dus weer eindeloze zoekpartijen: ik begrijp het niet, ik heb hier alleen maar 'n anker, en er verschijnt opeens een marge aan de bovenkant... Dat soort dingen. (Ja, klopt, hier spreekt de afdeling Schade en Schande en Wijs worden.)

Pseudo-element

Naast de gewone elementen als <div>, <p>, <h1>, zoals die in HTML voorkomen, bestaan er ook nog zogenaamde pseudo-elementen. Van een pseudo-element zie je niets in de HTML zelf. Een pseudo-element wordt aangemaakt in de CSS, maar het gedraagt zich ongeveer hetzelfde als een echt element. Het uiterlijk ervan kan met behulp van CSS worden aangepast, hoewel niet alle CSS bij alle pseudo-elementen gebruikt kan worden.

Een van de meer gebruikte pseudo-elementen is ::first-line. Dit kan bijvoorbeeld zo gebruikt worden in een stijlregel:

p::first-line {font-size: 1.1em;}

Van elke <p> krijgt de eerste regel een iets grotere letter. Maar alleen de éérste regel. Je zou hetzelfde kunnen bereiken door de eerste regel in een eigen <span> te zetten. Die <span> geef je dan een iets grotere letter. Dat geldt eigenlijk voor veel pseudo-elementen: je zou met HTML hetzelfde kunnen bereiken.

Maar niet helemaal.

Om te beginnen zou je dan, om bij ::first-line te blijven, elke eerste regel in een <span> moeten zetten, en mogelijk die <span> ook nog een class moeten geven. Ontzettend veel extra werk. Als de lettergrootte door de gebruiker wordt veranderd, verandert de lengte van de eerste regel en krijgt dus iets meer of minder dan alleen de eerste regel een iets grotere letter. Als je 'n woord toevoegt of weghaalt, moet je de <span> ook weer aanpassen.

Het voordeel van een pseudo-element is dat dit geen extra HTML vergt. En het past zich automatisch aan bij een andere lettergrootte, meer of minder tekst, enzovoort. Veel en veel minder werk dus en ook nog 'ns veel flexibeler.

CSS3 heeft een enorm aantal nieuwe pseudo-elementen toegevoegd. In het verleden stond hier een lijstje daarvan, maar die pseudo-elementen jongen als de konijnen, dus zo'n lijstje staat hier nu niet meer. Op mozilla.org staat een volledige lijst met pseudo-elementen. Op caniuse.com kun je zien welke browser vanaf wanneer wat ondersteunt.

Pseudo-elementen worden voorafgegaan door twee dubbele punten: ::after, ::highlight, ::target-text, enzovoort. In CSS 2.1 bestonden alleen de pseudo-elementen ::after, ::before, ::first-letter en ::first-line. Die werden niet voorafgegaan door twee, maar door één dubbele punt: p:before, enzovoort. In oudere code kun je dus deze vier pseudo-elementen tegenkomen voorafgegaan door slechts één dubbele punt. Alle andere pseudo-elementen zijn vanaf hun introductie altijd gebruikt met twee dubbele punten.

Die dubbele punt is om ze makkelijk te kunnen onderscheiden van pseudo-classes, die vooraf worden gegaan door slechts één dubbele punt.

Wat je verder met pseudo-elementen kunt doen, gaat ver buiten de bedoeling van dit artikel. Voor wat betreft de CSS is een pseudo-element volledig hetzelfde als een gewoon element, zoals dat in HTML voorkomt.

Pseudo-class

Een pseudo-class wordt, anders dan een echte class, niet toegekend in de HTML. In de HTML zie je er helemaal niets van. Maar in de CSS kun je ze gewoon gebruiken, ze worden automatisch toegekend. Ze hebben te maken met de plaats van een element in de structuur van de HTML (bijvoorbeeld het eerste of derde kind), met waar geklikt of gehoverd wordt, met een bepaalde voorwaarde (bijvoorbeeld of een link wel of niet al is bezocht), en dergelijke.

De pseudo-class :hover bijvoorbeeld treedt op als over een element wordt gehoverd:

a:hover {color: orange; background: blue;}

Bij hoveren over een link wordt de voorgrondkleur, en dus de tekst, oranje en de achtergrond blauw. (Terzijde: een kleurcombinatie waar alleen een kleurenblinde vrolijk van wordt.)

Een andere regelmatig gebruikte pseudo-class is :first-child. Stel dat je alle <p>'s wilt laten inspringen, behalve de eerste <p> binnen een <li>. Dat kan heel simpel:

li p:first-child {text-indent: 0;}

Bij een <p> binnen een <li> moet de tekst in de eerste regel niet inspringen. Maar alleen als de <p> het eerste kind is van de <li>, als er niet eerst een ander element binnen de <li> voor de <p> staat. Dus alleen als in de HTML staat: <li><p>. Volgende <p>'s springen gewoon weer in.

Pseudo-classes sparen enorm veel code uit, omdat je niet handmatig allerlei elementen een class moet geven. Ze zijn ook uiterst flexibel. Als er een nieuwe <p> wordt tussengevoegd gelijk na de <li>, is die de nieuwe :first-child en springt niet in. De voormalige :first-child springt nu gewoon in, want die is nu niet meer het eerste kind. Gelukkig gaat dit wat probleemlozer dan soms bij échte families het geval is.

"Piet, doe jij even open, er wordt gebeld." "Hallo pa, leuk je te leren kennen, ik ben je eerstgeborene." Wordt toch niet echt overal zonder meer enthousiast op gereageerd. HTML-elementen zijn wat dit soort dingen betreft beslist soepeler dan mensen. Ook veel saaier trouwens, dat wel. Onmenselijk saai.

Sommige dingen zijn zonder pseudo-classes stomweg onmogelijk, zoals vaststellen of er wordt gehoverd over een element. Zonder pseudo-classes zou je dat alleen met iets als JavaScript kunnen vaststellen.

CSS 2.1 kende alleen de volgende pseudo-classes: :active, :first-child, :focus, :hover, :lang(), :link en :visited.

CSS3 voegt daar een enorm aantal pseudo-classes aan toe. Ook hiervan stond hier in het verleden een lijstje, maar ook pseudo-classes blijken zich met de snelheid van konijnen voort te planten, dus zo'n lijstje staat hier nu niet meer. Op mozilla.org staat een volledige lijst met pseudo-classes. Op caniuse.com kun je zien welke browser vanaf wanneer wat ondersteunt.

Waar je pseudo-classes voor kunt gebruiken, gaat de bedoeling van dit artikel ver te buiten. Voor wat betreft de CSS is een pseudo-class volledig hetzelfde als een gewone class, zoals die in de HTML wordt toegekend. Alleen hebben de pseudo-classes :has(), :is(), :not(), :scope en :where() invloed op de specificiteit van de CSS, en daarmee op het wel of niet uitvoeren van de CSS. Dit wordt verder besproken bij De invloed van geneste CSS, :has(), :is(), :not(), :scope en :where() op specificiteit.

Attribuut-selector

Een attribuut-selector (Engels: attribute selector) is simpel te herkennen aan het gebruik van [ en ]:

abbr[title] {border: 0;}

Haal de border weg bij <abbr>, maar alleen als de <abbr> een title-attribuut heeft, bijvoorbeeld:

<abbr title="nederland"> select[name="land"] {border-color: green}

Maak de border groen, maar alleen als de <select> het attribuut name="land" heeft. Een <select> met het attribuut name="adres" krijgt geen groene border.

Een attribuut-selector wordt gebruikt om een stijlregel wel of niet te laten werken, afhankelijk van of een attribuut aanwezig is (of juist afwezig). Ook kunnen bepaalde voorwaarden aan het attribuut worden gesteld, zoals dat het moet beginnen met "https://", om maar iets te noemen. Wordt niet aan deze voorwaarden voldaan, dan wordt de CSS niet uitgevoerd.

Ook de attribuut-selector wordt niet speciaal aangegeven in de HTML. Je gebruikt gewoon normale attributen in de HTML, en in de CSS wordt gekeken of die HTML aan bepaalde voorwaarden voldoet. Waardoor ook deze selector veel code uitspaart.

Waar je attribuut-selectors voor kunt gebruiken, gaat de bedoeling van dit artikel ver te buiten. Voor wat betreft de CSS is een attribuut-selector volledig hetzelfde als een gewone class, zoals die in de HTML worden aangegeven.

Elementen met (meer dan) een class én een id

Een element mag een id én een of meer classes hebben, daar is niets op tegen. Je geeft gewoon in de HTML een id én een class aan een element. Voor de CSS maakt dat verder niet zo heel veel uit.

Class én id

Vaak is een combinatie van een class en een id handig. Je zou bijvoorbeeld een serie tabellen dezelfde basis-opmaak kunnen geven. Alle tabellen krijgen dezelfde class, en via die class dezelfde CSS. En vervolgens zou je elke tabel een eigen id kunnen geven, en via die id een eigen kleur. Dat wordt dan zoiets in de HTML:

<table class="algemeen" id="parken">(...) <table class="algemeen" id="huizen">(...)

En in de bijbehorende CSS:

table.algemeen {width: 300px; height: 500px; background: white; color: black; border: black solid 1px;} table#parken {border: solid green 1px;} table#huizen {border: solid red 1px;}

Dit kan heel veel CSS uitsparen, omdat je op deze manier de gemeenschappelijke kenmerken van elementen in één stijlregel kunt opgeven. Vervolgens geef je de afwijkende eigenschappen voor elke id apart op.

Hierboven krijgen alle tabellen met class="algemeen" een aantal eigenschappen, waaronder een zwarte border. Voor de tabellen die een andere kleur border moeten krijgen, geef je dat vervolgens via een id aan.

Meerdere classes

Een element kan ook probleemloos meerdere classes krijgen:

<div class="een twee drie vier">

of een id én meerdere classes:

<div id="hoofdstuk" class="een twee drie vier">

In de CSS wordt zo'n element op precies dezelfde manier benaderd als wanneer het maar één class of id zou hebben. Voor bovenstaande <div> gelden al deze stijlregels:

div#header {...} div.een {...} div.twee {...} div.drie {...} div.vier {...}

Dit geeft de mogelijkheid om, door verschillende classes aan verschillende elementen te geven, met relatief weinig CSS veel combinaties te maken. <div class="een twee drie"> komt er anders uit te zien dan <div class="twee drie vier">, omdat je ze andere stijlregels kunt geven .

Alleen moet je hierbij wel oppassen voor de zogenaamde classitis: een overdaad aan classes. Het is niet de bedoeling dat je elke mogelijke eigenschap en elke mogelijke waarde een eigen class gaat geven, want dan krijg je iets als:

<div class="rode-border witte-achtergrond grote-letter links-boven">

Dan is het simpeler om gewoon de verouderde HTML-tags te blijven gebruiken voor de opmaak, want de CSS levert dan nog nauwelijks voordelen op en is uiterst onduidelijk. Voor de zekerheid: dit is geen advies om die verouderde troep te blijven gebruiken, maar een advies om niet een overdaad aan classes aan te maken.

(Terzijde: zijn er nog meer besmettelijke ziektes? Ja. Divitis. Een overdaad aan <div'>s. Soms zie je dat élk element in een <div> wordt gezet, of dat nou nodig is of niet. Je kunt door de <div'>s de <body> niet meer zien. Hoe ingewikkelder de code, hoe groter de kans op moeilijk te vinden fouten, en hoe moeilijker het voor derden is de code te begrijpen.)

Je kunt ook in de CSS classes combineren. De namen van de classes worden gewoon tegen elkaar gezet. De betreffende stijlregel geldt dan alleen voor een element dat álle classes heeft:

div.een.twee.drie{...}

Deze regel geldt voor <div class="een twee drie">, maar niet voor <div class="een"> of <div class="twee drie">, want alleen de eerste <div> uit dit rijtje heeft alle drie de classes. De regel geldt ook voor <div class="een twee drie vier vijf">, want ook deze heeft alle drie de benodigde classes.

De volgorde van de classes is hierbij niet van belang. De volgorde mag in de HTML anders zijn dan in de CSS, als ze maar allemaal aanwezig zijn.

Zoiets kan soms handig zijn. Een site heeft een pagina met huizen die een zwembad hebben, huizen die een garage hebben, en huizen die een zwembad én een garage hebben, zodat de auto makkelijk gewassen kan worden.

De zwembadhuizen staan in een <div> die een rode border moet krijgen. De huizen met een garage krijgen een groene border. En de huizen met zwembad én garage moeten een blauwe border krijgen. De HTML:

<div class="zwembad"><div> <div class="garage"><div> <div class="zwembad garage"><div>

Met deze twee classes kun je toch drie verschillende borders geven:

div.zwembad {border: red solid 1px;} div.garage {border: groen solid 1px;} div.zwembad.garage {border: blue solid 1px;}

De huizen in <div>'s met class="zwembad garage" krijgen, op grond van de eerste regel, een rode border. Op grond van de tweede regel krijgen ze een groene border. En die regel wint van de eerste, omdat hij later komt in de CSS en evenveel specificiteit heeft. Dus de tweede regel overrulet de eerste.

De derde regel komt nog later in de CSS en overrulet dus de bovenste twee regels (en heeft meer specificiteit). Uiteindelijk krijgen de <div>'s met een class="zwembad garage" dus een blauwe border, zonder dat ik daar een extra class voor nodig heb. En als de garage afbrandt, hoef ik alleen maar de class "garage" weg te halen om de border rood te maken.

Ook een id en een class kun je in de CSS combineren, maar dat is zelden zinvol. De volgende HTML is voor álle <div>'s met id="hoofdstuk" binnen een site:

div#hoofdstuk {background: red; color: orange; border: blue dashed 10px; outline: yellow dashed 5px;}

Een kleurencombinatie waarmee je zelfs de meest gemotiveerde kleuter wegjaagt, maar dat maakt voor de CSS niets uit.

Als er nu één div#hoofdstuk is met <div id="hoofdstuk" class="saai">, zal deze <div> gewoon de CSS van bovenstaande regel gebruiken. Maar de volgende regel wordt alleen door déze <div> gebruikt:

div#hoofdstuk.saai {background: white;}

Deze div#hoofdstuk ziet er dus hetzelfde uit als de andere <div>'s met id="hoofdstuk", maar de achtergrond is wit. En omdat in de selector een id én een class staan, heeft die regel meer specificiteit dan de stijlregel met alleen de id. Het maakt dus niet uit of hij voor of na de regel met alleen de id komt: hij overrulet altijd de regel met alleen de id. Hij heeft meer specificiteit.

Dat *(x##*-ding gaat de gracht in. Het werkt niet!

Als CSS niet werkt, zoals het volgens jou zou horen te werken, is dat volstrekt normaal. Het is pas vreemd als het gelijk werkt, zoals jij vindt dat het zou moeten werken. Er is een vrijwel oneindig aantal mogelijke oorzaken.

Het komt heel vaak voor dat de browser trouwhartig uitvoert, wat jij hebt opgegeven. Alleen bedoelde jij iets anders, dan wat er staat. Als je twee elementen over elkaar heen positioneert, laat de browser gehoorzaam de onderste verdwijnen achter de bovenste. Dat wilde je toch?

Tegen dat soort fouten helpt alleen maar het nalopen van de code. Het kan dan nuttig zijn er iemand anders naar te laten kijken, omdat het vaak voorkomt dat de schrijver van de code over iets heel simpels heen ziet, wat 'n ander gelijk ziet.

(Op de pagina met links vind je onder Gereedschap → Debuggen een serie links naar hulpmiddelen bij het nalopen van je code.)

De rest van dit artikel gaat niet over dit soort logische fouten, maar over dingen als de volgorde waarin CSS wordt uitgevoerd, fouten in de syntax (taalregels), en dergelijke. Het is geen handleiding om CSS en HTML volledig te debuggen (fouten eruit te halen). Daarvoor is een eigen uitgebreid artikel, eigenlijk een compleet boek, nodig. Het is ook geen handleiding over hoe je moet testen in verschillende browsers en met verschillende resoluties en zo. Ook dat is uitgebreid genoeg voor een apart artikel.

Ontwikkelgereedschap

Het is vaak heel lastig om te zien welke CSS door welk element bij een bepaalde eigenschap wordt gebruikt. Je kunt bijvoorbeeld in een stijlbestand hebben opgegeven dat alle <p>'s binnen een <div> een rode achtergrond moeten krijgen. Iets later geef je dan op dat elke derde <p> een witte achtergrond moet krijgen. Maar de <span>'s binnen zo'n derde <p> moeten juist wel weer een rode achtergrond krijgen. Behalve de <abbr>'s die in zo'n <span> staan, die krijgen een gele achtergrond.

Omdat een achtergrondkleur de achtergrondkleur van de voorouders overlapt, heeft de <abbr> in die derde <p> eigenlijk vier keer een achtergrondkleur gekregen: rood van alle <p>'s, wit omdat de <abbr> binnen een derde <p> staat, weer rood omdat de <abbr> binnen een <span> staat, en uiteindelijk wit. En soms gaat dit nog veel dieper. Je raakt daardoor snel het overzicht kwijt.

In browsers voor de desktop en voor de laptop is ontwikkelgereedschap aanwezig dat enorm kan helpen om weer overzichtelijk te maken, welke CSS nou precies waarvoor wordt gebruikt. Hieronder staat een afbeelding van het ontwikkelgereedschap in Firefox. Vrijwel alle browsers hebben soortgelijke hulpmiddelen Op de pagina met links staan onder het kopje Gereedschap → Debuggen handleidingen en dergelijke voor het gebruik ervan.

(In browsers voor mobiele apparaten is geen ontwikkelgereedschap aanwezig. CSS en dergelijke bekijken is daarin veel lastiger. Op de pagina met links is daar onder het kopje Mobiele apparatuur → Emulators, SDK's, specificaties, hulpprogramma's, en dergelijke voor en van specifieke systemen meer over te vinden.)

Schermafbeelding van het ontwikkelgereedschap in Firefox.

Op de afbeelding is in de linkerkolom de <h2> met 'Algemene opmerkingen' geselecteerd in de HTML. In de rechterkolom is de CSS te zien, die het uiterlijk van deze kopregel bepaalt. Deze CSS staat in het stijlbestand 'uitleg.css'.

Helemaal onderaan staat body {color: black; font-family: Arial, Helvetica, sans-serif;}. Hierachter staat 'uitleg.css : 4'. Dat wil zeggen dat deze CSS op de vierde regel van 'uitleg.css' staat. De CSS staat bij het element <body>, maar color en font-family worden geërfd door de nakomelingen van <body>, dus deze CSS geldt ook voor de <h2>.

Iets daarboven staat @media screen and (min-width: 760px) {body {font-size: 110%;}}. Daarachter staat weer 'uitleg.css: 1074'. Dit staat dus op regel 1074 van 'uitleg.css'. De CSS hier gelijk onder wordt alleen uitgevoerd als het browservenster minimaal 760 px breed is. In smallere vensters wordt deze regel niet getoond. De regel met de lettergrootte is doorgestreept, omdat een andere regel de lettergrootte later weer verandert voor de <h2>.

Weer daarboven staat h2 {font-size: 1.35em; margin: 1em 0 0.5em;}. Dit staat op regel 415 van 'uitleg.css'. Hier is de lettergrootte niet doorgestreept: dit is de lettergrootte die de <h2> uiteindelijk krijgt. De marge is echter wel doorgestreept, want die wordt op regel 1228 van 'uitleg.css' veranderd.

Hier gaat het om een klein aantal regels, maar vooral bij (veel) meer regels CSS kan dit enorm helpen om te zien, waarom iets niet werkt, zoals het zou moeten werken. Als je bijvoorbeeld ziet dat een eigenschap is doorgestreept, weet je dat die eigenschap om een of andere reden ergens anders wordt aangepast.

Als je bovenaan het venster het kopje 'Berekend' aanvinkt, krijg je álle eigenschappen te zien, die voor de <h2> gelden. Dat kunnen er, afhankelijk van het element, honderden zijn, want alle standaardwaarden en het standaard-stijlbestand van de browser worden allemaal weergegeven. Ook dit kan helpen bij het opsporen van problemen. Zo hadden in het verleden verschillende browsers enorm afwijkende standaardmaten bij lijsten. Dat was goed te zien in het tabblad 'Berekend'.

Syntactische fouten

Syntactische fouten zijn fouten tegen de regels van de taal, hier de HTML en/of de CSS. Zolang er nog syntactische fouten in je HTML of CSS zitten, is het echt volstrekt zinloos naar andere oorzaken van problemen te gaan zoeken. Een fout helemaal bovenin je pagina kan tot de wildste dingen onderin je pagina leiden.

Als op een forum een vraag binnenkomt, wordt vaak de code bekeken. Heel vaak blijken daar dan fouten in te zitten. Als je daar dan op wijst, krijg je met grote regelmaat als reactie dat die fout echt niets te maken heeft met het probleem. Dat is echter nooit zo te zeggen. Het is echt eerst nodig dat soort fouten eruit te halen. Pas daarna is het zinvol naar de rest van deze tekst te kijken.

De meeste fouten tegen de syntax van HTML en CSS kunnen door een validator worden gevonden. Maar dat zijn alleen overtredingen van de regels. Als je zelf twee elementen over elkaar heen zet, maar je houdt je aan de regels, wordt dat niet gevonden, want dat is geen syntactische fout. Dat is gewoon de soort onhandigheid, waar mensen nou eenmaal in grossieren.

HTML kan worden gevalideerd op validator.w3.org.

CSS kan worden gevalideerd op jigsaw.w3.org/css-validator.

Elke goede editor en IDE geeft ook syntactische fouten weer. Op de pagina met links kun je onder het kopje Gereedschap → Editors, IDE's, en dergelijke links naar dat soort programma's vinden.

Als alle fouten eruit zijn en je CSS werkt nog niet zoals het zou moeten, is er mogelijk een kans dat je hieronder eventueel met 'n beetje geluk de oorzaak zou kunnen vinden. Of dat je in ieder geval iets gerichter kunt zoeken naar de oorzaak.

Standaardwaarden en standaard stijlbestand

Veel elementen hebben standaardwaarden, die automatisch worden gebruikt. Maar zodra met behulp van CSS een andere waarde wordt opgegeven, wordt die andere waarde gebruikt. Een waarde opgegeven met behulp van CSS wint áltijd van een eventuele standaardwaarde. De standaardwaarden komen uit het standaard stijlbestand van de browser, in het Engels 'default stylesheet'. Overigens zitten er nogal wat verschillen tussen de diverse browsers wat betreft sommige standaardwaarden, hoewel dat gelukkig wel minder wordt.

Als een element verschillend wordt weergegeven in verschillende browsers, terwijl je er geen CSS voor hebt opgegeven, is dit mogelijk de oorzaak. Je kunt dat makkelijk controleren door CSS op te geven voor de eigenschap, die verschillend wordt weergegeven. Als die nu hetzelfde wordt weergegeven in alle browsers, heb je de oorzaak mogelijk al gevonden.

Ook kun je onder het tabblad 'Berekend' (of een tabblad met soortgelijke naam) van het ontwikkelgereedschap zien, wat de standaardwaarde in een bepaalde browser is. Op de pagina met links zijn onder het kopje CSS → Default stylesheets (standaard stijlbestanden) links naar de standaard stijlbestanden te vinden.

Stijlbestand van gebruiker

Ook een gebruiker kan zelf een stijlbestand opgeven. Als zo'n stijlbestand aanwezig is en de bouwer van de site zelf geen CSS heeft opgegeven, wordt de CSS van de gebruiker gebruikt. Maar zodra de bouwer CSS heeft opgegeven, wint de CSS van de bouwer.

Omdat dit een stijlbestand is dat, als het al aanwezig is, van gebruiker tot gebruiker verschilt, zal het weinig problemen opleveren. De gebruiker kent het en weet dus wat het doet, en de bouwer weet niet eens dat het bestaat. Het is alleen handig om te weten dat het kán bestaan. Dit is bijvoorbeeld de reden dat het in de regel goed is om te zorgen voor een voorgrondkleur én een achtergrondkleur, en niet alleen maar een van die twee.

Als de gebruiker, bijvoorbeeld omdat deze moeite heeft met contrast, zelf kleuren opgeeft, kan het misgaan als de tekstkleur van de bouwer en de achtergrondkleur van de gebruiker worden gebruikt. Het contrast kan dan te laag zijn, of zelfs volledig ontbreken, als beide kleuren toevallig hetzelfde of bijna hetzelfde zijn.

In principe wint de CSS van de bouwer dus. Daar is één uitzondering op: als de gebruiker !⁠important heeft gebruikt, wint de bijbehorende stijlregel van de gebruiker altijd. Ook als de bouwer !important heeft gebruikt, wint het !⁠important van de gebruiker.

Overigens heeft de gebruiker ook nog de mogelijkheid om JavaScript te injecteren. Dat kan bijvoorbeeld met behulp van een extensie, zoals greasemonkey bij Firefox. Ook dan kan de CSS van de bouwer worden overschreven. Kortom: nooit alleen op CSS vertrouwen voor het overbrengen van belangrijke dingen.

Overerving

In het Engels: inheritance.

Elementen erven vaak, maar niet altijd, de eigenschappen van één of meer voorouders. En net als bij echte families kan dat tot forse ruzies leiden. 'Die dochter van jou lijkt op je moeder'. 'Hoe kom je erbij. Ze heeft dat van jouw grootvader. En heb je al 'ns naar jezelf gekeken?'

Als een element binnen een ander element staat, is dat element een nakomeling van het buitenste element. En dat buitenste element is, je raadt het al, een voorouder.

Als een element een nakomeling is van een ander element, kan het soms eigenschappen erven van dat andere element. Bijvoorbeeld de regelhoogte van een <div> wordt doorgegeven aan alle <p>'s, <span>'s, enzovoort binnen de <div>. Hetzelfde geldt bijvoorbeeld voor de voorgrond- en de achtergrondkleur, de lettersoort, en nog veel meer eigenschappen.

Maar niet alle eigenschappen worden doorgegeven. Een border bijvoorbeeld wordt niet doorgegeven aan de nakomelingen, omdat je anders een enorme hoeveelheid borders zou krijgen. Die je dan grotendeels weer zou moeten verwijderen. Elk goed overzicht van CSS zal bij elke eigenschap opgeven, of die erfelijk is of niet. Op de pagina met links staan onder het kopje CSS → Overzicht eigenschappen, tips, specificatie, en dergelijke links naar dat soort overzichten.

Overerving verschilt dus van eigenschap tot eigenschap bij CSS. Ook zonder dat je dat verder in de CSS apart aangeeft, worden sommige eigenschappen doorgegeven aan nakomelingen.

Zodra je zelf CSS voor een bepaalde eigenschap van een element opgeeft, wint die altijd van overerving.

Je kunt wel met behulp van de gecombineerde selector een bepaalde eigenschap beperken tot de nakomelingen van één of meer specifieke elementen.

In het ontwikkelgereedschap van de browser kun je zien, of een eigenschap wordt geërfd van een voorouder: in dat geval wordt de voorouder met de geërfde eigenschap ook getoond.

@media

Met behulp van een 'media query' kunnen allerlei voorwaarden worden opgegeven, waaraan het apparaat moet voldoen. Er is een groot aantal voorwaarden dat kan worden opgegeven, bijvoorbeeld een minimale breedte van het browservenster, het aantal kleuren dat een apparaat kan weergeven, of dat het scherm in landschaps- of portretrichting moet staan.

@media screen and (min-width: 500px) { body {background-color: black;} }

Bovenstaande CSS kleurt de achtergrond van <body> zwart, maar alleen in browservensters die minimaal 500 px breed zijn. In smallere vensters wordt deze CSS niet uitgevoerd.

Als het apparaat niet aan de eisen van de media query voldoet, wordt de CSS niet getoond in het ontwikkelgereedschap van de browser. De CSS wordt dan niet uitgevoerd. Je kunt dit nagaan door de regel met @media (en de bijbehorende afsluitende }) even weg te commentariëren. Als de CSS dan wel zichtbaar is, komt het mogelijk (mede) door de media query dat de CSS niet wordt uitgevoerd.

Dit is maar een heel korte beschrijving van media query's. Op de pagina met links kun je onder het kopje CSS → Media Query's, Container Query's en Responsive Web Design meer info over media query's vinden.

@container

@container wordt pas sinds februari 2023 door de meeste browsers ondersteund, en lang niet door alle browsers volledig. Op caniuse.com kun je zien welke browser sinds wanneer wat ondersteunt.

Container query's werken ongeveer hetzelfde als @media hier gelijk boven, maar dan voor een element in plaats van voor het hele browservenster. Je kunt met behulp hiervan de CSS binnen een element afhankelijk maken van bijvoorbeeld de breedte van dat element.

<section id="naampje"> <h3>Kopregel</h3> </section>

In de bovenstaande HTML staat een kopregel binnen een <section>. De bedoeling is dat die kopregel alleen rood wordt als <section> breder is dan 400 px. Dat staat helemaal los van de breedte van het browservenster (zoals bij @media), het gaat echt om de breedte van de <section>. De volgende CSS kan daarvoor zorgen:

section#naampje { container-type: inline-size; container-name: hoera; }
@container hoera (width > 400px) { h3 {color: red;} }

De regel @container hoera koppelt de <h3> aan section#naampje: section#naampje is de container voor de <h3>. Met container-name: hoera; heeft de container een naam gekregen. Die naam komt terug in de @container regel bij de <h3>. Een naam is niet verplicht, maar is wel aan te raden. Zeker als er meerdere containers zijn.

Alleen de <h3>'s binnen de container met de naam hoera (section#naampje) worden rood, maar alleen als section#naampje breder dan 400 px is.

Als de container niet aan de eisen achter @container voldoet, wordt de CSS niet getoond in het ontwikkelgereedschap van de browser. De CSS wordt dan niet uitgevoerd. Je kunt dit nagaan door de regel met @container (en de bijbehorende afsluitende }) even weg te commentariëren. Als de CSS dan wel zichtbaar is, komt het mogelijk (mede) door de container query dat de CSS niet wordt uitgevoerd.

Dit is maar een heel korte beschrijving van container query's. Op de pagina met links kun je onder het kopje CSS → Media Query's, Container Query's en Responsive Web Design meer info over container query's vinden.

@scope()

@scope() wordt pas sinds 2024-2025 door de meeste browsers geleidelijk ondersteund, maar er zijn nog browsers die het helemaal niet ondersteunen. Ook iets oudere browsers zullen @scope() vaak niet ondersteunen. Op caniuse.com kun je zien welke browser sinds wanneer wat ondersteunt.

Met behulp van @scope kan CSS worden beperkt tot de nakomelingen van een element:

<div id="voorouder"> <p>Ik sta binnen div#voorouder</p> </div>
<p>Ik sta niet binnen div#voorouder</p>

En de bijbehorende CSS:

p {color: red;}
@scope (div#voorouder) { p {color: blue;} }

Met bovenstaande CSS krijgen alle <p>'s door de eerste regel een rode kleur.

De derde regel geeft de <p>'s een blauwe kleur. Omdat de derde regel onder de eerste regel staat, zou deze regel winnen van de eerste regel: alle <p>'s zouden een blauwe kleur krijgen.

Maar de tweede regel beperkt de 'scope' van de derde regel tot de <p>'s die binnen div#voorouder staan. Alleen de <p>'s binnen div#voorouder krijgen een blauwe kleur, op de <p> buiten div#voorouder heeft de derde regel geen invloed.

Je kunt tussen de haakjes bij @scope() ook meerdere selectors opgeven:

@scope(div#voorouder, section > p) { p {color: blue;} }

Nu krijgen <p>'s binnen div#voorouder én <p>'s die een direct kind van een <section> zijn een blauwe kleur.

Het gebruik van alleen een regel met @scope() heeft geen invloed op de specificiteit. Zodra je echter :scope gaat gebruiken binnen @scope(), kan dat wel invloed hebben op de specificiteit, en daarmee op het wel of niet uitvoeren van de CSS. Meer hierover is te vinden bij :scope en specificiteit.

Als de CSS buiten de scope valt, wordt de CSS niet getoond in het ontwikkelgereedschap van de browser. De CSS wordt dan niet uitgevoerd. Je kunt dit nagaan door de regel met @scope (en de bijbehorende afsluitende }) even weg te commentariëren. Als de CSS dan wel zichtbaar is in het ontwikkelgereedschap, komt het mogelijk (mede) doordat de CSS niet binnen de scope valt dat de CSS niet wordt uitgevoerd.

Dit is maar een heel korte beschrijving van @scope(). Op de pagina met links kun je onder het kopje CSS → Selectors, specificiteit, id, erfelijkheid, @layer, @scope(), en dergelijke → @scope() en :scope meer info over @scope() vinden.

Niet ondersteund en @supports()

Als een browser een bepaalde CSS-eigenschap niet ondersteunt, wordt die CSS uiteraard niet uitgevoerd. De CSS is wel te zien in het ontwikkelgereedschap van de browser, maar is doorgestreept en er staat een icoontje met een waarschuwing bij.

Op caniuse.com is te zien welke versie van welke browser wat ondersteunt.

Je kunt in de CSS met behulp van @supports() testen, of een browser een bepaalde CSS-eigenschap ondersteunt. Dit geeft de mogelijkheid om, als een eigenschap niet wordt ondersteund, alternatieve CSS op te geven. Als je eerst de alternatieve CSS opgeeft en daaronder binnen @supports() de CSS als de eigenschap wordt ondersteund, wint de CSS binnen @supports van de alternatieve CSS: als de browser iets niet ondersteunt, wordt de alternatieve CSS gebruikt. Maar als de browser het wel ondersteunt, wordt de CSS binnen @supports gebruikt, omdat die lager staat.

Op de pagina met links kun je onder het kopje CSS → Bugs, hacks en @supports → CSS wegfilteren/aanpassen meer info over @supports() vinden.

Volgorde van uitvoeren

Bij CSS worden de afzonderlijke stijlregels volgens een strikte volgorde uitgevoerd. Dit is niet heel erg ingewikkeld, maar je moet het wel even weten. Als je bijvoorbeeld een extern stijlbestand gebruikt én een stijlblok in de <head> van de pagina, en er zitten tegenstrijdige stijlregels in, welke wint er dan?

Alle CSS op één plaats

Normaal genomen worden stijlregels die binnen hetzelfde bestand staan, volgens de volgorde binnen dat bestand uitgevoerd: van boven naar beneden. Daarbij wint een latere regel van een eerdere. Hetzelfde geldt voor de stijlregels die bij elkaar in een stijlblok binnen de <head> van een pagina staan. Stel dat in de CSS de volgende regels staan:

div {color: black;} (...) andere CSS (...) div {color: red;} (...) andere CSS (...) div {color: blue;}

De kleur van de <div> wordt nu blauw, want dat is de laatste regel in de CSS. En die wint van de twee eerdere regels. Het maakt niet uit als er andere regels tussen deze drie regels staan: de laatste regel met blauw wint van de twee eerdere met zwart en rood.

Hierbij is een heel belangrijke voorwaarde dat de selector - in bovenstaande regels div - hetzelfde is, evenveel gewicht, evenveel specificiteit heeft. Als daar verschil in zit, gaan hele andere regels spelen.

Ook wordt van links naar rechts gelezen. Als er bijvoorbeeld twee kleuren in dezelfde stijlregel staan, wordt de laatste kleur gebruikt. Dat kan handig zijn als een (oudere) browser een bepaalde eigenschap en/of waarde niet ondersteunt. Je geeft dan eerst de eigenschap en/of waarde op, die alle browsers ondersteunen, gevolgd door de eigenschap en/of waarde die niet alle browsers ondersteunen. Je zou bijvoorbeeld eerst een simpele achtergrondkleur kunnen opgeven, gevolgd door bijvoorbeeld een achtergrondkleur met een gradiënt voor nieuwere browsers.

Alle browsers ondersteunen de simpele achtergrondkleur. Browsers die een gradiënt niet ondersteunen, gebruiken die simpele achtergrondkleur. Browsers die een gradiënt ondersteunen, gebruiken de gradiënt, omdat de achtergrondkleur met de gradiënt volgt op de simpele achtergrondkleur.

Maar normaal genomen is het volstrekt zinloos om twee keer dezelfde eigenschap te gebruiken in dezelfde regel, omdat de eerste eigenschap gewoon genegeerd zal worden. Het kan nog wel handig zijn als je aan het testen bent, om even uit te proberen hoe iets eruit ziet of zoiets.

Meerdere externe stijlbestanden

Als er vanuit de pagina naar meerdere externe stijlbestanden wordt gelinkt, worden deze in volgorde van linken uitgevoerd. Ze worden als het ware achter elkaar gezet. Als je in het eerste stijlbestand een achtergrond rood maakt bij div#floepie, en in het tweede stijlbestand maak je bij div#floepie de achtergrond blauw, dan wordt de achtergrond blauw.

In het ontwikkelgereedschap van de browser wordt aangegeven, op welk regelnummer in welk stijlbestand een bepaalde eigenschap staat. Je kunt daarin dus zien, welk stijlbestand wint.

Meerdere stijlbestanden kunnen handig zijn als de pagina bijvoorbeeld geprint moet worden. Door het toevoegen van media="print" aan de link naar het stijlbestand, wordt deze CSS alleen uitgevoerd als er wordt geprint. De link voor het stijlbestand voor het printen moet ná de link naar de algemene CSS komen. Door die volgorde winnen stijlregels uit het printbestand van gelijke regels uit het algemene stijlbestand.

En dat is precies wat je wilt. Nu kun je gewoon een stijlbestand voor algemeen gebruik maken. Voor het printen hoef je dan meestal maar weinig aan te passen en kun je meestal voor het grootste deel gewoon het algemene stijlbestand gebruiken.

Hierbij is een heel belangrijke voorwaarde dat de stijlregels uit de verschillende bestanden evenveel gewicht, evenveel specificiteit, hebben. Als daar verschil in zit, gaan hele andere regels spelen.

Extern stijlbestand én stijlblok

Bovenin de <head> van een pagina mag ook CSS worden neergezet. Dat kan soms handig zijn als CSS alleen maar voor één specifieke pagina nodig is. Als je het dan binnen die specifieke pagina zet, spaar je mogelijk 'n aanroep naar de server voor een extern stijlbestand uit. En in ieder geval wordt het algemene stijlbestand niet nodeloos groot door code die maar op één pagina nodig is.

Een stijlblok is te herkennen aan de eerste en laatste regel:

<style> (...) CSS (...) </style>

(In oudere code kun je nog <style type="text/css"> tegenkomen. In HTML5 en later kun je volstaan met <style>.)

Hierbij wordt ook weer de volgorde van stijlbestand(en) en stijlblok aangehouden. Als het stijlblok onderaan staat, wint dit van externe stijlbestanden. Als een extern stijlbestand onderaan staat, wint de CSS uit het externe stijlbestand.

Maar ook hier geldt weer dat de specificiteit, het gewicht van de selector, gelijk moet zijn. Als de regel uit het externe stijlbestand meer specificiteit heeft dan de regel uit het stijlblok, wint de regel uit het externe stijlbestand altijd, ongeacht de volgorde van stijlbestand en stijlblok. En omgekeerd: als de regel uit het stijlblok meer specificiteit heeft, wint deze altijd.

In het ontwikkelgereedschap van de browser wordt weer aangegeven welke regels uit welk extern stijlbestand of stijlblok worden gebruikt. Bij een extern stijlbestand wordt de naam van het stijlbestand gegeven. Bij een stijlblok geven sommige browsers als naam het HTML-bestand, waar het stijlblok in staat. Andere browsers geven als naam iets als 'inline'.

@import

Met behulp van @import kan een extern stijlbestand worden geïmporteerd. @import moet altijd helemaal bovenaan in de <head> staan, alleen meta charset en @layer-regels mogen erboven staan.

Het geïmporteerde stijlbestand komt boven eventuele andere externe stijlbestanden en stijlblokken te staan. De volgorde van de CSS bepaalt weer welke regel wordt uitgevoerd. Bij gelijke specificiteit winnen de andere externe stijlbestanden en stijlblokken dus van het geïmporteerde stijlbestand, omdat de CSS daarin onder de CSS in het geïmporteerde stijlbestand staat.

Meestal wordt @import in combinatie met het gelijk hieronder staande @layer en layer() gebruikt. In dat geval gelden andere regels voor welke CSS wordt uitgevoerd: het is dan niet meer alleen de specificiteit die dat bepaalt. Als je @layer en layer() niet gebruikt, is er eigenlijk geen goede reden om @import te gebruiken.

@layer en layer()

@layer en layer() worden vrijwel alleen gebruikt bij grotere projecten waar meer mensen aan meewerken, of als externe frameworks worden gebruikt. Het kan voorkomen dat de CSS van de een ongewild wint van de CSS van de ander, omdat dezelfde elementen in verschillende bestanden worden geselecteerd. Met behulp van @layer en layer() kan als het ware worden aangegeven, welk bestand 'voorrang' krijgt boven welk ander bestand.

Je doet dit door met behulp van @layer een bepaalde volgorde aan te geven, bijvoorbeeld:

<style> @layer algemeen, header, main, footer; </style>

Stel dat je nu de volgende CSS opgeeft:

@layer algemeen { div p {color: red;} }
@layer main { p {color: green;} }

Normaal genomen zouden de <p>'s rood worden, omdat de selector div p meer specificiteit heeft dan de selector met alleen p. Maar bij layers wordt eerst gekeken naar de volgorde van de layers. Bij @layer algemeen, header, main, footer komt de layer met de naam 'main' na de layer met de naam 'algemeen'. Daardoor wint de CSS uit 'main' altijd van de CSS in 'algemeen', waarbij de specificiteit geen enkele rol speelt: alleen de volgorde van de layers is van belang. De CSS bij p in 'main' zou ook nog winnen van de selector div#een div#twee div#drie div#vier p in 'algemeen'.

Bij het gebruik van @layer om layers te definiëren, wint een latere layer van een eerdere. Maar als er ook CSS is die niet in een layer staat, wint die weer altijd van CSS binnen een layer. (De browser voegt voor die CSS zonder layer zelf een layer toe, die achteraan komt te staan. En dus altijd wint van layers met een naam.)

Als !important wordt gebruikt, kan dat veranderen welke layer wint.

Je kunt layers ook definiëren met behulp van @import:

<style> @import url("algemeen.css") layer algemeen; @import url("header.css") layer kop; @import "main.css" layer tekst; @import "footer.css layer voet; </style>

Ook hier wint een latere layer weer van eerdere. Maar omdat dit veel onoverzichtelijker is dan het gebruik van de regel met @layer, wordt aangeraden om de methode met @layer te gebruiken.

In het ontwikkelgereedschap van de browser staat aangegeven uit welke layer de CSS wordt gebruikt.

Omdat @layer en layer() vooral bij grotere projecten worden gebruikt, wordt dit hier maar heel summier besproken. Op de pagina met links is er onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), en dergelijke → @import, @layer en layer() meer over te vinden.

Specificiteit

Specificiteit is het gewicht dat een bepaalde selector, en daardoor de bij de selector horende CSS, heeft. Selectors met meer specificiteit overrulen selectors met minder specificiteit. De specificiteit kun je berekenen met behulp van bepaalde regels.

Omdat de specificiteit in de specificatie tamelijk onduidelijk wordt beschreven, waren er hier in het verleden veel misverstanden over. Op heel veel sites werd het berekenen van specificiteit verkeerd uitgelegd, zelfs op heel bekende sites. Inmiddels is dat op de meeste sites gecorrigeerd. Hoe het komt dat dit (vooral in het verleden) verkeerd werd uitgelegd, staat uitgebreider beschreven bij Waarom er veel misverstanden over specificiteit bestonden.

Het berekenen van specificiteit kan soms knap lastig zijn. Vaak is het veel makkelijker en sneller om een selector gewoon even uit te proberen, zolang dat niet tot onwijs lange selectors leidt.

In essentie is specificiteit heel simpel. Het aantal (pseudo-)elementen, (pseudo-)classes, attribuut-selectors en id's wordt geteld. Elk van die onderdelen heeft meer of minder gewicht. Door de totalen te vergelijken en rekening te houden met het gewicht van de afzonderlijke soorten, kun je de specificiteit bepalen. Hoe hoger de specificiteit, hoe meer gewicht de selector en dus de bijbehorende stijl heeft.

Als je denkt dat de selector te weinig specificiteit heeft, kun je gewoon even één of meer elementen toevoegen aan het begin van de selector. Meestal is er nog wel 'n <body> of div#huppeldepup of zoiets vrij. Stel dat je denkt dat de specificiteit van de volgende selector te laag is, en dat die daarom niet werkt:

p span.waarschuwing {color: red;}

Als je voor de p wat ouders van de <p> neerzet (die zullen er vrijwel altijd zijn), krijgt de selector meer specificiteit:

body footer div#tekst p span.waarschuwing {color: red;}

Door het toevoegen van body, footer en div#tekst zijn er drie elementen en een id bijgekomen. Als de regel nu wel werkt, weet je vrijwel zeker dat het aan een te lage specificiteit lag dat hij eerst niet werkte (of aan een te hoge specificiteit van een andere regel, dat kan natuurlijk ook).

Ook kun je even !important aan het eind van de regel toevoegen. Als de regel nu wel werkt, is ook dit een indicatie dat het aan een te lage specifiteit ligt. Overigens kun je !important prima even gebruiken om iets uit te proberen, maar daarna kun je het beter weer weghalen. De redenen daarvoor kun je vinden bij !⁠important, een steenpuist op je achterste.

Selectors moeten altijd zo kort mogelijk worden gehouden. Het verwerken van selectors kost tijd, maar dat is met de tegenwoordige krachtige computers eigenlijk geen probleem meer. Wat nog wel een probleem is, is de leesbaarheid van de code. Als je specificiteit op wilt lossen door steeds langere selectors te gebruiken, kun je beter een spaghetti-restaurant beginnen. Spaghetti in een restaurant is prima (als de kok kan koken), spaghetti in code leidt altijd tot geestelijke verstopping en virtuele buikloop.

De volgende selector werd in het verleden gebruikt voor een horizontaal uitklapmenu op deze site. Vanwege alle :hover's kon de selector eigenlijk niet korter:

#menu ul li:hover ul li:hover ul li:hover ul a:hover

Het ontrafelen van dit soort selectors levert geen bijdrage aan het Bruto Nationaal Geluk van Nederland. Als het dus enigszins kan: houdt selectors zo kort mogelijk. Tegenwoordig kan dat gelukkig ook veel makkelijker met pseudo-classes als :nth-of-type.

HTML-opmaakcodes (<font> en dergelijke)

We beginnen met een hele simpele: opmaakcodes in de HTML, zoals de zwaar verouderde <font>-tag. De specificiteit daarvan is heel makkelijk te berekenen: ze hebben altijd een specificiteit van 0. Gewoon helemaal geen specificiteit. En omdat een CSS-regel altijd minimaal een heel klein beetje specificiteit heeft, wint CSS áltijd van de opmaakcode in de HTML. Als je dus met behulp van <font> de tekstkleur rood maakt, en in de CSS geef je zwart op, dan wordt de tekstkleur áltijd zwart.

Je komt dit soort opmaakcodes alleen nog tegen in zwaar verouderde sites. Als een site niet meer wordt veranderd en goed werkt: die oude tags lekker zo laten staan. En als een site nog wel verandert en je CSS wilt gaan gebruiken, is het echt veel beter om die verouderde tags gewoon helemaal weg te halen.

Inline-stijl (<div style="...">)

Een inline-stijl is een stijl die rechtstreeks bij het element staat, waar de stijl voor is bedoeld. Voorafgegaan door style=" en afgesloten door ".

<div style="background: blue;"> <span style="color: red;"> <p style="border: black dashed 1px; outline: blue solid 3px;">

De drie tags hierboven bevatten alle drie een inline-stijl.

Ook dit is een makkelijke. Een inline-stijl wint gewoon áltijd van elke andere stijlregel. Daardoor is een inline-stijl heel handig te gebruiken als je even snel iets uit wilt proberen.

Hier is één uitzondering op. Als je !⁠important gebruikt in een stijlregel in een extern stijlbestand of in een stijlblok in de <head>, dan wint de regel met !⁠important.

(De truc om een inline-stijl bij het berekenen van de specificiteit een waarde van 1000 te geven, zoals je die vooral in het verleden veel op internet zag, is onjuist. Waarom dat onjuist is, staat bij Waarom er veel misverstanden over specificiteit bestonden.)

Specificiteit van de selector berekenen

Bij een gewone stijlregel zonder !⁠important, wordt de specificiteit vastgesteld aan de hand van de selector. De selector is het deel voor de {

div {background: red;}

Selector: div

body#ul p span.waarschuwing {color: red;}

Selector: body#ul p span.waarschuwing

Meer dan één selector

Vaak zijn er meerdere selectors. Dat is te herkennen aan de komma tussen de verschillende selectors. In dat geval moet voor elke selector apart de specificiteit worden berekend. De specificiteit van een selector geldt alleen maar voor de elementen, waar de selector betrekking op heeft.

div#een, p.twee {color: red;}

In bovenstaande regel heeft de selector div#een helemaal niets te maken met de selector p.twee. Ze hebben alleen toevallig dezelfde CSS, meer niet.

Als Pietje hetzelfde model broek draagt als Keesje, maakt ze dat nog niet tot broertjes van elkaar. In bovenstaande regel is de specificiteit van div#een ook nog 'ns anders dan die van p.twee, zoals verderop aan de orde komt.

id's tellen

Om de specificiteit van een selector te bepalen tel je allereerst het aantal id's in de selector. Een id is de naam die je in de HTML met id="..." aan een element hebt gegeven. In de CSS is een id te herkennen aan de # die eraan voorafgaat:

div#uitleg {background: red;}

1 id: #uitleg

body#tekst #uitleg p#waarschuwing {color: red;}

3 id's: #tekst, #uitleg en #waarschuwing

Classes, pseudo-classes en attribuut-selectors tellen

Vervolgens tel je hoeveel classes,   pseudo-classes en   attribuut-selectors in de selector zitten.

Een element wordt in de HTML ingedeeld in een class met class="...". In de CSS is een class te herkennen aan de . (punt) die eraan voorafgaat.

Een pseudo-class is iets als :hover of :first-child. Voor de bepaling van de specificiteit telt dit net zo mee als een gewone class. Een uitgebreidere beschrijving van een pseudo-class staat bij pseudo-class.

Een attribuut-selector is iets als abbr[attribuut]. Het is te herkennen aan de [ en ]. Voor de bepaling van de specificiteit telt dit net zo mee als een gewone class. Een iets langere beschrijving vind je bij attribuut-selector.

Voorbeelden:

div.afbeelding {background: blue;}

1 class: .afbeelding

div.hoofdstuk p.inleiding .kop {font-size: 1.2em;}

3 classes: .hoofdstuk, .inleiding en .kop

div.hoofdstuk p.inleiding a:hover {background: blue;}

2 classes: .hoofdstuk en .inleiding. 1 pseudo-class: :hover. Voor de bepaling van de specificiteit telt dit gewoon als 2 + 1 = 3 classes.

div.hoofdstuk p.inleiding:hover abbr[title] {display: block;}

2 classes: .hoofdstuk en .inleiding. 1 pseudo-class: :hover. 1 attribuut-selector: [title]. Voor de bepaling van de specificiteit telt dit gewoon als 2 + 1 + 1 = 4 classes.

Er zijn (op het moment van schrijven) vijf pseudo-classes die de specifiteit (fors) kunnen veranderen. Deze worden beschreven bij :has() en specificiteit,    :is() en specificiteit,    :not() en specificiteit,    :scope en specificiteit    en :where() en specificiteit.

Elementen en pseudo-elementen tellen

Ten slotte tel je hoeveel elementen en pseudo-elementen er in de selector zitten. Elementen en pseudo-elementen zijn even belangrijk voor het bepalen van de specificiteit. Ook dit is weer een kwestie van simpel tellen.

Een element is hetzelfde als een element in de HTML, dus dingen als <body>, <div>, <h1>, <span>, enzovoort. De universele selector * telt niet mee, want dat is geen HTML-element. (Officieel zou je hier een 'element' trouwens 'type-selector' moeten noemen: wat in de HTML een element heet, heet in de CSS type-selector.)

Een pseudo-element is iets als ::first-letter. Voor de bepaling van de specificiteit telt dit net zo mee als een gewoon element. Een iets uitgebreidere beschrijving kun je vinden bij pseudo-elementen.

div {background: red;}

1 element: div

div p {background: blue;}

2 elementen: div en p

div p span::first-letter {color: #faa;}

3 elementen: div, p en span. 1 pseudo-element: ::first-letter. Voor de bepaling van de specificiteit telt dit gewoon als 3 + 1 = 4 elementen.

Wat niet meetelt (*, <, + en ~)

In selectors kun je vier tekens tegenkomen, die niet meetellen voor de specificiteit.

Universele selector (*)

Ook in Nederlandse teksten wordt de universele selector vaak op z'n Engels 'universal selector' genoemd.

Deze selector is een geval apart. Zoals de naam al aangeeft, selecteert hij álle elementen:

* {margin: 0; padding: 0;}

zal bij álle elementen de marge en padding weghalen.

Dit lijkt misschien een goed idee, omdat je dan niets meer hebt te maken met de standaardinstellingen van browsers, die soms wat verschillen. Toch is het dat meestal niet.

Als je de marge en padding bij álle elementen weghaalt, haal je die bij wel heel erg veel elementen weg, ook waar er geen verschil is tussen browsers. En je moet het dan ook weer overal terugzetten.

Dit gaat nog meer spelen als je erfelijke eigenschappen als regelhoogte erin opneemt:

* {line-height: 1.2em;}

Normaal genomen wordt een eigenschap als regelhoogte automatisch door nakomelingen geërfd van de voorouders. Normaal genomen is die overerving ook precies, wat je wilt. Maar als je met behulp van de universele selector in de CSS de regelhoogte instelt, wint dat van de overerving. Elke vorm van CSS overrulet nou eenmaal de overerving. <html> krijgt dan een regelhoogte van 1,2 em, <body> krijgt een regelhoogte van 1,2 x 1,2 em, de <div> krijgt een regelhoogte van 1,2 x 1,2 x 1,2 em en de <p>'s ten slotte krijgen een regelhoogte van 1,2 x 1,2 x 1,2 x 1,2 = 2,0736 em. Wat waarschijnlijk helemaal niet de bedoeling is, waardoor je dan op heel veel plaatsen die regelhoogte weer moet corrigeren.

Als je de standaard-instellingen van browsers gelijk wilt krijgen, is het beter om een zogenaamde 'reset style' te gebruiken. Als je daarnaar zoekt op internet, vind je verschillende goede. Zo'n reset style stelt de standaard-instellingen op een gecontroleerde manier in. Overigens wordt ook over het gebruik van reset styles nogal verschillend gedacht. Op deze site worden ze niet gebruikt, maar er zijn ook mensen die ze bij elke site gebruiken. Net wat je prettig vindt.

Omdat de universele selector zo enorm botst met het mechanisme van overerving, kan hij beter niet zonder meer in z'n eentje worden gebruikt. Maar de universele selector is wel bruikbaar als onderdeel van een langere selector:

div#content * a {color: red;}

Deze CSS maakt de tekst van een link rood. Maar niet van alle links, er moet aan twee voorwaarden worden voldaan.

div#content bepaalt dat de link binnen div#content, een <div> met id="content", moet staan. Maar het geldt niet voor álle links binnen div#content.

De * geeft aan dat de link een kind van een ander element moet zijn, wat zelf weer een kind is van div#content. Het maakt niet uit wat voor element er tussen de link en de <div> staat, als er maar een element is. De <a> moet een kleinkind van div#content zijn, geen rechtstreeks kind.

Deze CSS geldt dus niet voor <div><a>, want er staat hier geen element tússen de <div> en de <a>: de link is een direct kind van div#content.

Maar hij geldt wel voor <div><h2><a> en ook voor <div><p><a ...>, want nu staat er een element tussen div#content en de <a>: de <a> is nu een kleinkind van div#content. En omdat de universele selector * is gebruikt, maakt het niet uit dat in het ene geval een <h2> en in het andere geval een <p> de ouder van de link is.

Je kunt dit in principe net zo ingewikkeld maken als je wilt:

body * ul ul * * span

levert een groene tekst op in de laatste <span> bij:

<body><div><ul><li><ul><li><strong><span>(...)

en ook bij:

<body><ul><li><ul><li><ul><li><span><span>(...)

maar niet bij:

<body><div><ul><li><strong><span>(...)

Veel zul je dit niet gebruiken. De reden daarvoor heb je mogelijk al gemerkt: je moet de regels hierboven zeven keer lezen en hebt bijkans een telraam nodig om uit te tellen, hoe het werkt. Maar het is nuttig te weten dat er zoiets als een universele selector bestaat, en dat die soms handig kan zijn.

>, + en ~

Naast de hierboven al genoemde universele selector *, tellen nog drie symbolen niet mee voor de bepaling van de specificiteit: >, + en ~.

Deze drie symbolen zeggen alleen iets over de elementen waarvoor bepaalde CSS geldt, maar ze veranderen de waarde van de specificiteit niet. Net zoals de *: gewoon volledig negeren dus, wat betreft de specificiteit.

Alles samen tellen

Als je, zoals hierboven beschreven, alles hebt geteld, heb je drie getallen: eentje voor de id's, eentje voor de (pseudo)-classes en attribuut-selectors, en eentje voor de (pseudo-)elementen. Als een van die drie niet aanwezig is, is het getal gewoon nul. Dus je hebt altijd drie getallen.

(Als je geneste CSS, :has(), :is(), :not(), :scope of :where() gebruikt binnen een selector, kan dat (forse) invloed hebben op het berekenen van de specificiteit, zoals die hieronder wordt beschreven. Dit wordt verderop besproken bij De invloed van geneste CSS, :has(), :is(), :not(), :scope en :where() op specificiteit.)

div#content p span.waarschuwing {color: #faa;}

1 id: #content. 1 class: .waarschuwing. 3 elementen: div, p en span. Dit geeft een specificiteit van 1-1-3.

div#content div[title] p a:hover span.waarschuwing::first-letter {color: #faa;}

1 id: #content. 1 class: .waarschuwing. 1 pseudo-class: :hover. 1 attribuut-selector: [title]. 4 elementen: div, div, p en span. 1 pseudo-element: ::first-letter.

Pseudo-classes, attribuut-selectors en classes zijn hetzelfde wat betreft specificiteit, dus er zijn 1 + 1 + 1 = 3 classes.

Elementen en pseudo-elementen zijn hetzelfde wat betreft specificiteit, dus er zijn 4 + 1 = 5 elementen.

In totaal zijn er dus 1 id, 3 classes en 5 elementen. Dit geeft een specificiteit van 1-3-5.

Elke stijlregel levert op deze manier drie getallen op: het aantal id's, het aantal (pseudo-)classes en attribuut-selectors, en het aantal (pseudo-)elementen.

Neem de volgende HTML:

<div id="buitenste"> <div class="binnenste"> <p id="para">tekst</p> </div> </div>

Hieronder staan vier stijlregels, die alle vier gelden voor deze HTML: een <p> binnen twee <div>'s, elk met een id of class. Alle vier de regels leveren blauwe tekst in de <p> op:

div div p#para {color: blue;}

1 id, 0 (pseudo-)classes en attribuut-selectors, 3 elementen. Dit geeft een specificiteit van 1-0-3.

div#buitenste div p#para {color: blue;}

2 id's, 0 (pseudo-)classes en attribuut-selectors, 3 elementen. Dit geeft een specificiteit van 2-0-3.

div#buitenste div.binnenste p#para {color: blue;}

2 id's, 1 class, 3 elementen. Dit geeft een specificiteit van 2-1-3.

div div.binnenste p#para {color: blue;}

1 id, 1 class, 3 elementen. Dit geeft een specificiteit van 1-1-3.

De specificiteit van deze vier regels is anders. En in dat geval bepaalt niet de volgorde van de stijlregels in het CSS-bestand, maar de specificiteit welke regel er wint.

Nog 'n keer dezelfde CSS, maar nu met vier verschillende kleuren:

div div p#para {color: blue;}

1 id, 0 (pseudo-)classes en attribuut-selectors, 3 elementen. Dit geeft een specificiteit van 1-0-3.

div#buitenste div p#para {color: red;}

2 id's, 0 (pseudo-)classes en attribuut-selectors, 3 elementen. Dit geeft een specificiteit van 2-0-3.

div#buitenste div.binnenste p#para {color: black;}

2 id's, 1 class, 3 elementen. Dit geeft een specificiteit van 2-1-3.

div div.binnenste p#para {color: white;}

1 id's, 1 class, 3 elementen. Dit geeft een specificiteit van 1-1-3.

Welke kleur krijgt de <p> nu? De volgorde zegt niet alles meer, want die is alleen bepalend als de specificiteit hetzelfde is.

Om de specificiteit te bepalen, kijk je eerst naar het aantal id's: het eerste getal. Een id wint altijd van classes, hoeveel classes er ook zijn, al staan er duizend. En hoe hoger het aantal id's, hoe hoger de specificiteit.

In bovenstaande CSS hebben de kleuren red en black beide 2 id's, en blue en white maar 1. Blue en white verliezen dus van red en black, ongeacht de volgorde van de regels, want ze hebben minder specificiteit.

Blijven red en black over als mogelijke winnaars. Beide hebben 2 id's, dus dat maakt geen verschil, dat levert geen winnaar op.

black heeft 1 class. En 'n class wint altijd van elementen, hoeveel elementen er ook staan. Red heeft helaas geen class. Dus black wint. Dat ze allebei drie elementen hebben speelt verder helemaal geen rol meer.

Nog eens, maar met andere aantallen id's, classes en elementen:

div#content div#hoofdstuk p#para {color: blue;}

3 id's, 0 (pseudo-)classes en attribuut-selectors, 3 elementen. Dit geeft een specificiteit van 3-0-3.

body div#buitenste div p#para {color: red;}

2 id's, 0 (pseudo-)classes en attribuut-selectors, 4 elementen. Dit geeft een specificiteit van 2-0-4.

div#buitenste div.binnenste p#para a:hover[title] {color: black;}

2 id's, 1 class, 1 pseudo-class, 1 attribuut-selector, 4 elementen.
1 class, 1 pseudo-class en 1 attribuut-selector tellen als 3 classes, dus dit wordt:
2 id's, 3 classes, 4 elementen. Dit geeft een specificiteit van 2-3-4.

body#pagina div div.binnenste p#para.een.twee.drie.vier.vijf.zes {color: white;}

2 id's, 7 classes, 4 elementen. Dit geeft een specificiteit van 2-7-4.

Wie wint? Heel simpel. Er is er maar één met 3 id's, dus die wint: blue. Naar het aantal classes en elementen hoef je niet eens meer te kijken.

Als laatste een voorbeeld van een typische instinker. De HTML:

<div id="buitenste"> <div id="binnenste"> <p id="para">tekst</p> </div> </div>

Twee bijbehorende stijlregels:

div div p#para {color: blue;} div#buitenste div#binnenste p {color: red;}

Welke kleur krijgt de tekst? Je zou misschien denken blauw, omdat de id van p#para wordt gebruikt.

Mooi niet dus. Beide regels hebben 3 elementen. Maar de tweede regel bevat 2 id's, en de eerste maar 1. Dat die twee id's bij de ouder-<div>s van de <p> horen, maakt niets uit. 2 id's winnen gewoon van 1. Altijd. Punt.

Laten we aan de eerste regel een id toevoegen:

div#buitenste div p#para {color: blue;} div#buitenste div#binnenste p {color: red;}

Pech voor de eerste regel: nog steeds wint de tweede regel. Beide regels hebben nu 2 id's en 3 elementen: dezelfde specificiteit dus. En in dat geval wint de laatste regel.

We maken de eerste regel nóg wat langer, geven nog wat meer specificiteit:

body div#buitenste div p#para {color: blue;} div#buitenste div#binnenste p {color: red;}

Nu wint eindelijk de eerste regel. Beide regels hebben 2 id's, dus wat dat betreft hebben ze dezelfde specificiteit. Maar de eerste regel heeft nu 4 elementen, en de tweede regel maar 3. En dat geeft de eerste regel net genoeg specificiteit om te winnen van de tweede regel.

Op de pagina met links staan onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), @layer, en dergelijke → Algemeen links naar sites, waar je de specificiteit van een selector kunt laten berekenen. Deze rekenmachientjes lijken prima te werken, maar zijn hier niet getest met ingewikkelde zaken als geneste pseudo-classes.

Vuistregels voor masochisten

Mogelijk ben jij wat masochistisch aangelegd en wil je dit oerwoud aan regels over volgorde en specificiteit precies volgens de letter volgen. Dan zijn dit stukje tekst en een diep gevoel van deelneming voor deze zelfkwelling aan jou gericht.

Toch nog 'n laatste poging je van je rekenwerk af te houden...

Het is dus vrijwel altijd veel simpeler om gewoon even met het aantal elementen, classes, en dergelijke te spelen. Dat gaat veel sneller dan die berekeningen. Bovendien weet je gelijk zeker dat het werkt (dat wil zeggen: als je in alle bekende browsers test!). Specificiteit is namelijk gewoon niet helemaal foutloos. Dat was zeker in het verleden het geval en dus nog steeds bij oudere browsers. Ook bij nieuwere eigenschappen kunnen er in het begin verschillen in implementatie tussen browsers zijn. Dat was onder andere het geval bij & als dat bij @scope() werd gebruikt: sommige browsers veranderden de specificiteit bij het gebruik van &.

Het is belangrijk om selectors niet krankzinnig lang te maken. Een selector met 37 id's wint ongetwijfeld, maar daarmee steun je ook de verkoop van kalmerende middelen, en de farmaceutische industrie maakt al meer dan genoeg winst.

Als er een conflict is tussen twee stijlregels, probeer dan - als dat enigszins kan - de langere selector korter te maken. Of geef 'n element 'n id of class, zodat je het rechtstreekser kunt aanroepen.

Doe vooral niet, wat soms op deze site is gedaan. In de downloads valt het nog wel mee, maar op de site zelf staan nogal wat (hele) lange selectors. Anders hadden er nóg meer classes en id's moeten worden gebruikt, of nóg meer stijlbestanden.

Maar deze site is, wat CSS betreft, geen 'normale' site. Deze site heeft verhoudingsgewijs een idiote hoeveelheid CSS, omdat hij nou eenmaal voorbeelden op dat gebied bevat, dus heel veel pagina's hebben afwijkende CSS nodig. De gemiddelde site bevat veel en veel minder CSS en zal dus ook veel kortere selectors kunnen gebruiken, omdat er minder conflicten op het gebied van specificiteit zullen zijn.

Wat het berekenen nog ingewikkelder maakt: geneste CSS, :has(), :is(), :not(), :scope en :where() kunnen de berekening (fors) veranderen, zoals iets hieronder wordt beschreven.

Als je nou nóg aan het rekenen wilt, tja, dan houdt het op. Sterkte. Iets hierboven staan de precieze regels. En hieronder wat korte vuistregels.

!important wint bijna altijd (en zou je niet moeten gebruiken). (Alleen !important in een stijlbestand van de gebruiker wint hiervan.)

Als !important niet wordt gebruikt, wint een inline-stijl altijd.

Als !important niet wordt gebruikt en er is ook geen inline-stijl:

Het grootste aantal id's wint.

Bij een gelijk aantal id's wint het grootste aantal classes (inclusief pseudo-classes en attribuut-selectors).

Bij een gelijk aantal id's én een gelijk aantal classes, wint het grootste aantal elementen (inclusief pseudo-elementen).

Bij een gelijk aantal id's, een gelijk aantal classes én een gelijk aantal elementen, bepaalt de volgorde van uitvoeren van de stijlregels welke er wint.

De invloed van geneste CSS, :has(), :is(), :not(), :scope en :where() op specificiteit

Hierboven is het berekenen van specificiteit beschreven, en daarmee het bepalen welke CSS wel of niet wordt uitgevoerd. De in het kopje genoemde pseudo-classes en dergelijke kunnen deze specificiteit echter volledig veranderen. Voor elk van die zaken wordt dat hieronder beschreven.

Als je een van deze dingen gebruikt en je vermoedt dat die het niet goed uitvoeren van de CSS beïnvloeden, zou je die dingen even weg kunnen halen en vervangen door 'gewone' CSS (voor zover dat kan, bij bijvoorbeeld :has() kan dat niet). Als het dan wel werkt, is dat een aanwijzing dat het aan een van deze dingen zou kunnen liggen. Je zou dan bijvoorbeeld een van de pseudo-classes weer stap voor stap kunnen gaan gebruiken, tot je merkt dat dat problemen gaat opleveren. Dan heb je mogelijk de oorzaak van het probleem gevonden.

Sommige van deze pseudo-classes en dergelijke kunnen worden genest. Dan wordt het nog ingewikkelder om de CSS te berekenen. Op de pagina met links staan onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), @layer, en dergelijke → Algemeen links naar sites, waar je de specificiteit kunt laten berekenen. Deze rekenmachientjes lijken prima te werken, maar zijn hier niet getest met ingewikkelde zaken als geneste pseudo-classes.

Geneste CSS en specificiteit

Geneste CSS wordt pas sinds eind 2023 door de meeste browsers (volledig) ondersteund. Eind 2025 zijn er nog steeds enkele browsers, die het niet ondersteunen. Geneste CSS werkt dus niet in álle browsers, en zeker niet in oudere browsers. Op caniuse.com kun je zien welke browser sinds wanneer wat ondersteunt.

Volgens veel mensen zou geneste CSS makkelijker te begrijpen zijn. Het zou volgens sommigen vooral handig kunnen zijn bij grotere projecten, waarbij bijvoorbeeld ook CSS van derde partijen wordt gebruikt.

Geneste CSS kan eigenaardige bijwerkingen hebben wat betreft specificiteit. Deze worden in tutorials vaak niet eens genoemd. Meestal gaat het goed, maar áls die bijwerkingen optreden, kan het (heel) lastig te vinden problemen veroorzaken. (Die bijwerkingen worden iets hieronder beschreven.) Het is dan ook de vraag, of geneste CSS écht makkelijker is.

Een ander argument is dat het bestand met CSS hierdoor kleiner wordt. Dit is een wat eigenaardig argument, omdat geneste CSS meestal op ingewikkelder sites wordt gebruikt. Dat zijn ook precies de sites die vaak vele megabytes aan frameworks met JavaScript en CSS gebruiken. Die paar bytes besparing op de CSS zetten dan echt geen zoden aan de dijk.

Op deze site wordt geneste CSS niet gebruikt, maar voor de volledigheid wordt het hier wel besproken.

Stel dat we de volgende HTML hebben:

<div class="ouder"> <p class="kind"> <span class="kleinkind"></span> </p> </div>

Hele eenvoudige HTML: een <span> in een <p> in een <div>, met elk een class.

Deze drie elementen kun je alle drie een andere achtergrondkleur geven:

div.ouder {background: red;} div.ouder p.kind {background: green;} div.ouder p.kind span.kleinkind {background: yellow;}

De <div>'s met class="ouder" krijgen een rode achtergrond.

De <p>'s met class="kind" krijgen een groene achtergrond, maar alleen als deze binnen een <div> met class="ouder" zitten.

De <span>'s met class="kleinkind" krijgen een gele achtergrond, maar alleen als deze binnen een <p> met class="groen" zitten die weer binnen een <div> met class="ouder" zitten.

(Dat dit wat mallotige selectors zijn, maakt niet uit. Het gaat hier alleen om de werking van geneste CSS.)

Deze drie aparte regels kun je inkorten tot:

div.ouder {background : red; p.kind {background: green; span.kleinkind {background: yellow;} } }

Door de <span> binnen de <p> te zetten en die weer binnen de <div>, kan de selector een stuk korter worden. Bij bijvoorbeeld geneste lijsten kan dit behoorlijk wat herhaling van selectors schelen.

De CSS werkt precies hetzelfde als wanneer het drie afzonderlijke regels zouden zijn. De browser zet zelf automatisch de vereiste spaties tussen de verschillende delen van de selector. Zou dat niet zo zijn, dan zou de derde selector div.ouderp.kindspan.kleinkind worden, wat heel iets anders is dan div.ouder p.kind span.kleinkind.

Als je dat duidelijker vindt, kun je de geneste CSS ook met een & schrijven:

div.ouder {background : red; & p.kind {background: green; & span.kleinkind {background: yellow;} } }

De browser zet die & er zelf voor als die er niet staat. Maar daar merk je verder niets van. Maar bij bepaalde selectors moet je die & wel zelf opgeven, omdat de selector anders niet goed werkt. Neem de volgende CSS:

a { :visited {color: blue;} :hover {color: green;} :active {color: red;} }

De bedoeling is dat de <a> reageert op :visited, :hover en :active. Maar omdat, zoals iets hierboven beschreven, de browser een spatie invoegt, worden deze drie regels:

a :visited {color: blue;} a :hover {color: green;} a :active {color: red;}

Als een element binnen de <a> is bezocht, maak dat dan blauw. Als over een element binnen de <a> wordt gehoverd, maak dat dan groen. En als een element binnen de <a> wordt aangeraakt of -geklikt, maak dat dan rood. Die toegevoegde spatie verandert de werking volledig: de <a> zelf reageert niet op :visited, :hover of :active, alleen de nakomelingen van de <a> reageren erop.

Dit kan worden opgelost door bij dit soort selectors een & gelijk voor de pseudo-class te zetten, zonder spatie tussen de & en de pseudo-class:

a { &:visited {color: blue;} &:hover {color: green;} &:active {color: red;} }

Nu wordt dit omgezet naar:

a:visited {color: blue;} a:hover {color: green;} a:active {color: red;}

Precies wat de bedoeling was: nu reageert de <> zelf op :visited, :hover en :active.

Dit is nog steeds een heel summiere beschrijving van geneste CSS, waarin lang niet alle mogelijkheden (en moeilijkheden) zijn beschreven. Links naar uitgebreidere beschrijvingen van geneste CSS zijn te vinden op de pagina met links onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), en dergelijke → Nesten.

Hier gaan we verder met de beschrijving van de invloed van geneste CSS op de specificiteit. Die invloed kan heel groot zijn en volledig onverwachte effecten hebben op het wel of niet uitvoeren van CSS. In veel tutorials over geneste CSS wordt de invloed van geneste CSS op specificiteit vreemd genoeg helemaal niet beschreven.

Zolang op elke regel van de CSS alleen selectors met dezelfde specificiteit staan, is er niets aan de hand. Als op een regel bijvoorbeeld de selectors .class-een, .class-twee staan, heeft dit geen invloed op de specificiteit. Het zijn twee classes, dus beide selectors hebben dezelfde specificiteit: 0-2-0 (0 id's, 2 classes, 0 elementen).

Heel anders wordt het als twee (of meer) selectors op een regel níét dezelfde specificiteit hebben:

div, .classje, #id-tje { p {color: blue;} }
div p {color: red;}

In de bovenste regel staat als selector onder andere div. Samen met de geneste p op de tweede regel levert dit div p op met een specificiteit van 0-0-2.

De onderste regel, die buiten de geneste CSS staat, is precies hetzelfde: div p. De specificiteit is dus ook 0-0-2. En omdat deze regel onder de geneste regel staat, zou deze regel moeten winnen: de <p> zou rood moeten worden. Dat gebeurt echter niet.

In de bovenste regel staan drie selectors met drie verschillende waarden: een element, een class en een id. De browser zet deze drie selectors bij het verwerken van de CSS niet netjes op drie aparte regels, maar voegt deze min of meer samen tot :is(div, .classje, #id-tje): ze worden tussen de haakjes van de pseudo-class :is() gezet. De volledige regel met de geneste p wordt dan:

:is(div, .classje, #id-tje) p

Dit betekent: de <p>'s binnen een <div>, of binnen een element met class="classje", of binnen het element met id="id-tje".

Bij selectors die zijn samengevoegd met :is() verandert de specifiteit ingrijpend: alleen de specificiteit van de selector met de hoogste specificiteit telt, ook voor alle andere selectors. Als alle selectors dezelfde specificiteit hebben, maakt dat niets uit. Maar hier is dat niet het geval: er is een element, een class en een id. Omdat de id de hoogste specificiteit heeft, geldt die voor alle drie de selectors, ook voor div en .classje.

De specificiteit van de geneste p wordt hierdoor 1-0-0, de specificiteit van de id. Hoewel de geneste CSS wordt omgezet naar regels met de selectors div p, .classje p en #id-tje p, hebben alle drie de regels een specificiteit van #id-tje p: 1-0-1 (1 id, geen (pseudo-)classes en attribuut-selectors, en 1 element. Anders dan bij de meeste pseudo-classes voegt :is() zelf geen specificiteit toe).

De niet geneste regel div p {color: red;} heeft slechts een specificiteit van 0-0-2 (0 id's, 0 (pseudo-)classes en attribuut-selectors, en 2 elementen) en verliest daardoor van de eerdere geneste regel. Ondanks dat die lager in de CSS staat, want specificiteit wint van de volgorde in de CSS.

:has() en specificiteit

De pseudo-class :has() geeft aan, aan welke voorwaarden de selector voor de dubbele punt van :has() moet voldoen. Je kunt hiermee als het ware de ouder van een element selecteren:

section:has(img) {padding: 20px;}

Geef elke <section> een padding van 20 px, maar alleen als binnen die <section> een <img> aanwezig is. Dit is anders dan de selector section img, want daarbij krijgt niet de <section>, maar de <img> de marge.

h1:has(+ h2, + img) {margin-bottom: 5px;}

Geef elke <h1> een marge van 5 px aan de onderkant, maar alleen als gelijk op die <h1> een <h2> of een <img> volgt.

Anders dan bij de meeste pseudo-classes voegt de pseudo-class :has() zelf geen specificiteit toe. Wat tussen de haakjes van :has() staat, is wel mede bepalend voor de specificiteit, maar op een afwijkende manier: de selector met de hoogste specificiteit bepaalt de specificiteit van het deel tussen de haakjes van :has():

section:has(div#hoera, p.belangrijk.eerste, a[title]) {background-color: orange;}

Tussen de haakjes staan drie selectors, gescheiden door een komma: div#hoera, p.belangrijk.eerste en a[title].

div#hoera heeft een specifiteit van 1-0-1 (1 id, 0 (pseudo-)classes en attribuut-selectors, 1 element).

p.belangrijk.eerste heeft een specificiteit van 0-2-1 (0 id's, 2 classes, 1 element).

a[title] heeft een specificiteit van 0-1-1 (0 id's, 1 attribuut-selector, 1 element).

Van deze drie heeft div#hoera de hoogste specifiteit: 1-0-1.

De hele selector section:has(div#hoera, p.belangrijk.eerste, a[title]) heeft hiermee een specificiteit van 1-0-2 (de id #hoera, 0 (pseudo-)classes en attribuut-selectors, 2 elementen (section en div).

Stel dat je de volgende HTML hebt:

<section class="een twee drie"> <div id="hoera"></div> </section>

Met als bijbehorende CSS:

section:has(div#hoera, p.belangrijk.eerste, a[title]) {background-color: orange;} section.een.twee.drie {background-color: green;}

<section> krijgt nu een oranje achtergrond, want de specificiteit van de eerste regel is 1-0-2. De specificiteit van de tweede regel is 0-3-1 (0 id's, 3 classes en 1 element). Omdat een id altijd meer is dan hoeveel classes of elementen dan ook, wint de eerste regel.

Links naar uitgebreidere beschrijvingen van :has() zijn te vinden op de pagina met links onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), en dergelijke → :has(), :is(), :matches(), :not() en :where.

:is() en specificiteit

Met behulp van :is() kun je tussen de haakjes een lijst opgeven, waaruit gekozen kan worden. Als een van de elementen uit die lijst aanwezig is, werkt de selector:

:is(div, p, a) span

Elke span die binnen een <div>, een <p> of een <a> staat.

Pseudo-elementen zoals ::before en ::first-line mogen niet worden gebruikt binnen :is(). Een regel met als selector p:is(::before, ::after) zal dus nooit goed werken.

Anders dan de meeste pseudo-elementen, heeft :is() zelf geen enkele invloed op de specificiteit. De selectors in de lijst bij :is() hebben wel invloed op de specificiteit: de selector met de hoogste specificiteit geldt voor álle selectors in de lijst.

Bij een selector als :is(.een, .twee, .drie) span maakt dit niets uit: alle drie selectors in de lijst bestaan alleen uit een class, dus de specifiteit van alle drie is 0-1-1 (0 id's, 1 class, en 1 element).

Heel anders wordt dat als de selectors in de lijst niet dezelfde specifiteit hebben. De HTML:

<p class="drie"> <span></span> </p>

En de bijbehorende CSS:

:is(.een, #twee, .drie) span {color: red;} .drie span {color: blue;}

Beide regels geven een kleur aan de <span> binnen p.drie. Normaal genomen zou dan de tweede regel winnen van de eerste: de kleur zou blauw worden. Hier is dat echter niet het geval.

De eerste regel wordt: .drie span, hetzelfde als de tweede regel. Beide zouden normaal genomen dezelfde specificiteit hebben: 0-1-1 (0 id's, 1 class, 1 element). In dat geval zou de tweede regel winnen, omdat die in het stijlbestand onder de eerste regel staat: de kleur zou blauw worden.

Maar in de eerste regel staat in de lijst ook #twee, een id. En omdat de specifiteit bij :is() wordt bepaald door de selector met de hoogste specifiteit uit de lijst, wordt de specificiteit van de eerste regel 1-0-1 (1 id, 0 (pseudo-)selectors en attribuut-selectors, 1 element). Ook al wordt die regel gebruikt bij <p class="drie">, een <p> die helemaal geen id heeft.

Door het gebruik van :is() wordt de specificiteit van de eerste regel hoger dan die van de tweede, en daardoor wint de eerste regel en wordt de kleur rood.

Links naar uitgebreidere beschrijvingen van :is() zijn te vinden op de pagina met links onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), en dergelijke → :has(), :is(), :matches(), :not() en :where.

:not() en specificiteit

Met behulp van :not() kun je tussen de haakjes opgeven, waaraan een selector juist níét mag voldoen. Bijvoorbeeld input:not(:selected): een <input>, zoals een aankruisvakje, die niet aangevinkt mag zijn.

Anders dan de meeste pseudo-elementen, heeft :not() zelf geen enkele invloed op de specificiteit. De selectors in de lijst bij :not() hebben wel invloed op de specificiteit: de selector met de hoogste specificiteit geldt voor álle selectors in de lijst.

Bij een selector als p:not(.een, .twee, .drie) span maakt dit niets uit: alle drie selectors in de lijst bestaan alleen uit een class, dus de specifiteit van alle drie is 0-1-2 (0 id's, 1 class, en de 2 elementen p en span).

Heel anders wordt dat als de selectors in de lijst niet dezelfde specifiteit hebben. De HTML:

<p class="drie"><span></span></p>

En de bijbehorende CSS:

:not(.een, #twee, .drie) span {color: red;} .drie span {color: blue;}

Beide regels geven een kleur aan de <span> binnen p.drie. Normaal genomen zou dan de tweede regel winnen van de eerste: de kleur zou blauw worden. Hier is dat echter niet het geval.

De eerste regel wordt: .drie span, hetzelfde als de tweede regel. Beide zouden normaal genomen dezelfde specificiteit hebben: 0-1-1 (0 id's, 1 class, 1 element). In dat geval zou de tweede regel winnen, omdat die in het stijlbestand onder de eerste regel staat: de kleur zou blauw worden.

Maar in de eerste regel staat in de lijst ook #twee, een id. En omdat de specifiteit bij :not() wordt bepaald door de selector met de hoogste specifiteit uit de lijst, wordt de specificiteit van de eerste regel 1-0-1 (1 id, 0 (pseudo-)selectors en attribuut-selectors, 1 element). Ook al wordt die regel gebruikt bij <p class="drie">, een <p> die helemaal geen id heeft.

Door het gebruik van :not() wordt de specificiteit van de eerte regel hoger dan die van de tweede, en daardoor wint de eerste regel en wordt de kleur rood.

Links naar uitgebreidere beschrijvingen van :not() zijn te vinden op de pagina met links onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), en dergelijke → :has(), :is(), :matches(), :not() en :where.

:scope en specificiteit

@scope() wordt pas sinds 2024-2025 door de meeste browsers geleidelijk ondersteund, maar er zijn nog browsers die het helemaal niet ondersteunen. Ook iets oudere browsers zullen @scope() vaak niet ondersteunen. Op caniuse.com kun je zien welke browser sinds wanneer wat ondersteunt.

Met behulp van @scope() kun je de werking van CSS beperken tot een bepaald bereik:

@scope(div) { span {background: red;} }

Alleen <span>'s binnen een <div> krijgen een rode achtergrond. (Dit wordt iets uitgebreider beschreven bij @scope(), hier gaat het alleen over de invloed op de specificiteit.)

Wat tussen de haakjes bij @scope() staat, heeft geen invloed op de specificiteit. Het telt niet mee voor de waarde van de specificiteit. Maar CSS zou geen CSS zijn als er bij de CSS bij @scope() helemaal nooit iets zou veranderen aan de specificiteit. Iets wat overigens in veel tutorials over @scope() helemaal niet wordt genoemd.

Je kunt bij een @scope-regel ook CSS voor opgeven, die voor het scope-blok (in het Engels de 'scope root') geldt. De HTML:

<div class="eerste"> <p></p> </div>

En de bijbehorende CSS:

@scope (div) { :scope {background: red;} p {background: green;} }
div {background: blue;}

De CSS achter :scope geldt voor de selectors die tussen de haakjes achter @scope staan. Hier is dit er maar eentje: div. De selectors tussen de haakjes tellen niet mee voor de specificiteit.

Onder het @scope-blok staat nog een regel CSS: div {background: blue;}. Je zou mogelijk denken dat de <div> daardoor een blauwe achtergrond krijgt, want deze regel staat lager dan de regel in het @scope-blok. Toch krijgt de <div> een rode achtergrond. Dat komt doordat :scope een pseudo-class is, en de specificiteit van :scope telt wel gewoon mee.

Daardoor heeft de selector :scope {background: red;} een specificiteit van 0-1-0 (0 id's, 1 pseudo-class, 0 (pseudo-)elementen).

De selector div {background: blue;} heeft een specificiteit van slechts 0-0-1 (0 id's, 0 (pseudo-)classes en attribuut-selectors, 1 element). Dat is minder dan de regel bij :scope, waardoor de regel bij :scope wint en de achtergrond van de <div> rood wordt.

Om de achtergrond blauw te maken, moet de tweede regel iets worden als div.eerste {background: green;}. Nu heeft de selector een specificiteit van 0-1-1 (0 id's, 1 class, 1 element), waardoor de selector nu wel wint van de selector bij :scope en de achtergrond nu wel blauw wordt.

Overigens bleek bij het testen dat de specificiteit van de tweede regel (de regel buiten het @scope-blok) in sommige browsers hoger moet zijn dan de specificiteit van de regel binnen het @scope-blok. Als de specificiteit van de regel binnen het @scope-blok en de regel erbuiten hetzelfde zijn, wint de regel binnen het @scope-blok soms toch, ongeacht de volgorde van de regels. Dit is nog niet in alle browsers op precies dezelfde manier geïmplementeerd.

Links naar uitgebreidere beschrijvingen van @scope en :scope zijn te vinden op de pagina met links onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), en dergelijke → @scope() en :scope.

:where() en specificiteit

Met behulp van :where() kun je tussen de haakjes een lijst opgeven, waaruit gekozen kan worden. Als een van de elementen uit die lijst aanwezig is, werkt de selector:

section :is(div, p, a) span

Elke span die binnen een <div>, een <p> of een <a> staat, die zelf weer binnen een <section> staat.

Anders dan de meeste pseudo-elementen, heeft :where() zelf geen enkele invloed op de specificiteit. Dat geldt ook voor de selectors in de lijst bij :where(): ook die hebben geen enkele invloed op de specificiteit.

De specificiteit van een selector als :where(p, .twee, #drie) span is dus niet meer dan 0-0-1. Wat tussen de haakjes bij :where() staat en :where() zelf tellen niet mee. Alleen span daarachter telt mee. Waardoor er dus 0 id's, 0 (pseudo-)classes of attribuut-selectors, en maar 1 element is.

De volgende HTML en CSS geven een kleur aan een <span>. De HTML:

<p id="een"><span></span></p>

En de bijbehorende CSS:

:where(p, #een, .drie) span {color: red;} span {color: blue;}

Beide regels geven een kleur aan de <span> binnen p#een.

De eerste regel heeft een specificiteit van 0-0-1 (de selectors tussen de haakjes tellen niet mee, en :where() zelf ook niet, dus 0 id's, 0 (pseudo-)classes en attribuut-selectors, 1 element).

De tweede regel heeft een specificiteit van 0-0-1 (0 id's, 0 (pseudo-)classes en attribuut-selectors, 1 element).

Omdat beide regels dezelfde specificiteit hebben, wint de laatste regel. Dat er in de eerste regel een class en een id staan, heeft geen enkele invloed, want die tellen niet mee voor de specificiteit.

Links naar uitgebreidere beschrijvingen van :where() zijn te vinden op de pagina met links onder het kopje CSS → Selectors, specificiteit, class, id, erfelijkheid, @import, @layer, @scope(), en dergelijke → :has(), :is(), :matches(), :not() en :where.

Waarom er veel misverstanden over specificiteit bestonden

Op heel veel sites wordt uitgelegd, hoe je specificiteit kunt berekenen. In het overgrote deel van de gevallen, zelfs op bekende sites, was de manier van berekenen die daarbij in het verleden werd gebruikt ronduit onjuist. Inmiddels is dat op de meeste sites gecorrigeerd.

Mogelijk komt dit, doordat de uitleg in de specificatie over het berekenen van specificiteit erg summier en onduidelijk is. Tegelijkertijd wordt de manier van berekenen erg ingewikkeld voorgesteld. Bovendien staan in de specificatie alleen voorbeelden met kleine aantallen id's, classes, enzovoort. Die aantallen worden dan gewoon achter elkaar gezet, waardoor de indruk ontstaat dat er met het tientallig stelsel wordt gewerkt. Een bron van misverstanden.

De complete uitleg in versie 3 van de specificatie beperkt zich feitelijk tot:

Concatenating the three numbers a-b-c (in a number system with a large base) gives the specificity. (w3.org/TR/selectors-3/#specificity)

En daar moest je dan maar uit afleiden dat er niet opgeteld moet worden, maar dat de drie getallen los achter elkaar gezet moeten worden, en dat er geen tientallig stelsel moet worden gebruikt. In versie 4 van de specificatie is de uitleg (iets) duidelijker.

De meest gebruikelijke uitleg op internet, zoals je die in het verleden heel vaak zag:

Geef een inline-stijl 1000 punten.

Geef elke id 100 punten.

Geef elke class, pseudo-class (en attribuut-selector, als die tenminste niet gewoon werd vergeten...) 10 punten.

Geef elk element en pseudo-element 1 punt.

Deze getallen zet je nu onder elkaar en tel je op.

3 id's en 4 elementen geeft dan:

300 4 Totaal 304

Zo'n selector wint dan van een selector die bijvoorbeeld na optelling 263 heeft.

Deze manier van berekenen gaat goed, zolang je niet meer dan 9 id's, 9 classes of 9 elementen hebt. Na 9 komt 10 in het tientallig stelsel. We maken nog eens een berekening op bovenstaande manier, maar nu met 2 id's, 10 classes en 5 elementen.

2 id's en 10 classes en 5 elementen geeft:

200 100 5 Totaal 305

305 is meer dan 304, dus een stijlregel met 2 id's, 10 classes en 5 elementen zou winnen van een regel met 3 id's en 4 elementen. En dat klopt dus niet. Een stijlregel met meer id's wint áltijd van een stijlregel met minder id's.

Zou je de id's, de classes en de elementen gewoon als losse kolommen zien en niet optellen, dan zou je gelijk zien dat de 3 id's winnen van de 2 id's. Ongeacht het aantal classes en elementen.

Een variant hierop die je ook vaak zag, is het achter elkaar zetten van de totalen.

Bij 3 id's, 0 classes en 4 elementen werkt dat aldus:

3 - 0 - 4 maakt 304

Zo'n selector wint dan van een selector die bijvoorbeeld na achter elkaar zetten 263 heeft.

Ook deze manier van berekenen gaat goed, zolang je weer niet meer dan 9 id's, 9 classes of 9 elementen hebt. Na 9 komt 10 in het tientallig stelsel, en dan ontstaat er plotsklaps een waanzinnige sprong in grootte. We maken nog eens een berekening, maar nu met 2 id's, 10 classes en 5 elementen.

2 id's en 10 classes en 5 elementen geeft:

2 - 10 - 5 maakt 2105

Dat is groots, zo'n selector wint overal van! Als het zou kloppen. De fout is hier beter zichtbaar dan bij de eerste methode van optellen: na 9 komt 10 in het tientallig stelsel. Maar de '10' uit bovenstaande berekening is geen '10' zoals de '10' na '9'. De '10' uit bovenstaande berekening geeft alleen aan dat het 'meer dan 9' is, maar niet dat het een tiental is. Dat 'meer dan 9' bij ons wordt weergegeven als 10 is gewoon een menselijke afspraak, een naampje, een rekenhulp, geen natuurwet.

Alleen hebben we in het tientallig stelsel gewoon niet meer dan 10 symbolen om een cijfer weer te geven. Er zijn gewoon niet meer dan 10 namen voor een cijfer. Na de 9 zijn ze op.

In het hexadecimale (zestientallige, zijn computers ook dol op) stelsel gebruik je de cijfers 0 tot en met 9 en de letters A tot en met F. Dan kun je 16 eenheden weergeven: 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 enzovoort. Daar zou de laatste samenvoeging geen 2 - 10 - 5 worden, maar:

2 - A - 5 maakt 2A5

Maar ook hier gaat het mis, alleen nu pas bij aantallen boven de 16.

Als je ervoor kiest om specificiteit te berekenen en de pech hebt meer dan 9 id's, elementen of classes (of dingen die daar gelijkwaardig aan zijn) te gebruiken, kom je er met deze manier van berekenen nooit achter, waarom het mis gaat. Bij het berekenen van specificiteit moet je niet het tientallig stelsel gebruiken. De gevonden totalen moeten in aparte kolommen, los van elkaar, worden vergeleken.

Een uitstekende (Engelstalige) uitleg over de foutieve manier van berekenen is te vinden op Juicy Studio.

!important, een CSS-steenpuist op je achterste

Duidelijk een geval van verdringing: !⁠important was haast vergeten. Alsnog.

!important is als een steenpuist op je achterste. Je bent je steeds hinderlijk bewust van de aanwezigheid, op de meest vreemde plaatsen in je lichaam kunnen problemen ontstaan, je wordt enorm belemmerd in je flexibiliteit en het is niet echt een verrijking van je lichamelijke mogelijkheden. De steenpuist heeft ook nog met !⁠important gemeen dat ze beide voor vreselijke kleuren, enorme overflow, en andere ongewenste eigenschappen op de meest onverwachte plaatsen en de meest ongelegen momenten kunnen zorgen.

Een nettere vergelijking voor als je niet tegen een steenpuist op je zitvlak kunt: een stijlregel die zichzelf !⁠important vindt, lijkt heel erg op mensen die zichzelf belangrijk vinden. Ze richten beide rampen aan en zijn beide onuitstaanbaar. !⁠important is zeg maar wat mensen als Wilders en Van der Plas in de politiek zijn: je hebt er niets aan, maar als ze er zijn, veroorzaken ze problemen.

Het gebruik van !important maakt een stijlbestand uiterst moeilijk te volgen. Het wint bijna overal van, zelfs van een inline-stijl. Alleen !⁠important in een stijlbestand van de gebruiker wint hier nog van. En als er 'n probleem is, zoek je je ongans naar de oorzaak. Kilometers verderop blijkt dan in het stijlbestand een regel te zitten, die zichzelf zo ontzettend !⁠important vindt dat als de Femke Wiersma van de CSS over alles en iedereen heen wordt gewalst.

Kortom: niet gebruiken. Bagger. Weg ermee! En dit is een mening die door de meeste mensen wordt gedeeld.

important! is alleen zinvol in het het stijlbestand van een gebruiker. Het kan ervoor zorgen dat het stijlbestand van de gebruiker altijd wint, wat belangrijk kan zijn voor mensen die bijvoorbeeld een grotere letter willen, of meer contrast. Of om snel te kijken of die stijlregel misschien wel werkt, als je er even !⁠important bij zet tijdens het testen.

Engelse vertaling van sleutelbegrippen

De meeste informatie op internet is Engelstalig. Omdat veel van de informatie hier van internet komt, worden in dit artikel Engelse en Nederlandse begrippen vrolijk door elkaar heen gebruikt.

Bij zoeken op internet kun je vaak beter zoeken op de Engelse zoektermen, omdat je dan vrijwel altijd veel en veel meer informatie vindt. Daarom hieronder een lijstje met Nederlandse sleutelbegrippen en hun Engelse tegenhangers.

Overigens bestaan voor veel begrippen geen Nederlandse namen, dus af en toe is het een beetje een vreemde mengelmoes van Nederlands en Engels.

Tabel met Nederlandse begrippen en hun Engelse vertaling
NederlandsEngels
attribuutattribute
attribuut-selectorattribute selector
eigenschapproperty
gecombineerde selectordescendant selector
identiteitidentity
inline-stijlinline style
meerdere selectorsmultiple selector(s)
nakomelingdescendant
onderstreping ('_')underscore
opmaaklayout
overervinginheritance
schermlezerscreenreader
specificiteitspecificity
standaarddefault
standaard stijlbestand browserdefault stylesheet, browser styles
stijlstyle
stijlbestandstylesheet
stijlbestand van gebruikeruser stylesheet
stijlblokinternal style
stijlregelstyle rule
universele selector ('*')universal selector
verbindingsstreepje ('-')hyphen

Wijzigingen

Alleen grotere wijzigingen worden hier vermeld, geen dingen als een link die is geüpdatet.

:

Eerste versie.

24 januari 2026: