Naar de inhoud

Kennisbank · Webdevelopment

Wat is CSS?

16 min leestijd
CSS

CSS is de taal waarin je vastlegt hoe een webpagina eruitziet. HTML zegt wat iets is, een kop, een alinea, een lijst, en CSS zegt hoe dat eruit hoort te zien: welke kleur, welk lettertype, hoeveel ruimte eromheen en waar het op het scherm terechtkomt.

Voluit heet het Cascading Style Sheets. Dat eerste woord, cascading, beschrijft hoe de browser conflicten oplost, en het is de bron van vrijwel elke frustratie van een beginner.

De taal is oud. Het eerste voorstel stamt uit 1994 en CSS1 werd eind 1996 een aanbeveling van het W3C. Wat je vandaag schrijft lijkt daar nog op, maar het gereedschap is de laatste tien jaar zo veranderd dat oude handleidingen je meer kosten dan opleveren.

Hoe een CSS-regel eruitziet

Een regel bestaat uit twee delen. Eerst een selector die aanwijst waarover je het hebt, dan tussen accolades de eigenschappen die je instelt.

Alle alinea's donkergrijs maken is één regel van drie woorden. Alleen de alinea's binnen een bepaald blok is een andere selector met dezelfde eigenschap. De taal zelf is dus klein. Het gedoe zit in de vraag welke regel wint als er meerdere op hetzelfde element van toepassing zijn.

CSS kan op drie plekken staan: in een apart bestand dat je vanuit je HTML aanroept, in een style-blok in de kop van de pagina, of als attribuut op het element zelf. Dat laatste vermijd je, want het is lastig te overschrijven.

Wil je weten hoe de markering eronder in elkaar zit, dan begint dat bij HTML. Voor gedrag en interactie kom je bij JavaScript uit. Die drie samen vormen de kant van een site die de bezoeker ziet, waarover meer staat bij front-end ontwikkeling.

Selectors en specificiteit

De soorten die je gebruikt

Op elementnaam selecteren pakt alles van dat type: alle koppen van niveau twee, alle links. Op class selecteren pakt alles waaraan jij dat label hebt gehangen, en dat is verreweg de meest gebruikte manier. Op id selecteren pakt precies één element, want een id mag maar één keer voorkomen op een pagina.

Daarnaast kun je selecteren op een attribuut, bijvoorbeeld alle links naar een pdf, en op een toestand: de link waar de muis boven staat, het veld dat fout is ingevuld, het derde item in een lijst.

Wie wint er bij een conflict

Zeggen twee regels iets tegenstrijdigs over hetzelfde element, dan telt de browser de specificiteit. Een id weegt zwaarder dan een class, een class zwaarder dan een elementnaam. Zijn ze gelijk, dan wint de regel die het laatst in het stijlbestand staat.

Daarnaast weegt een stijl die als attribuut op het element zelf staat zwaarder dan alles uit je stijlbestand. En dan is er nog het toverwoord dat alles overrulet en waar alleen een tweede exemplaar van zichzelf tegenop kan. Zo ontstaan stijlbestanden waarin driekwart van de regels dat woord draagt en niemand nog durft te schuiven.

Werkt een regel niet, open dan de ontwikkelaarshulpmiddelen in je browser en klik het element aan. Je ziet alle regels die erop staan, met de verliezers doorgestreept. Dat scheelt je een uur gokken.

Het doosmodel

Elk element op een pagina is een rechthoek met vier lagen: de inhoud in het midden, de binnenruimte daaromheen, dan de rand, en daarbuiten de marge naar de buren.

De verwarring zit in de vraag wat de opgegeven breedte betekent. Standaard telt die alleen de inhoud, dus een blok van 300 pixels breed met 20 pixels binnenruimte en een rand van 1 pixel neemt 342 pixels in. Twee van die blokken passen dan niet in een vak van 640 pixels, en dat is de klassieke reden dat een indeling omvalt.

De oplossing is één regel bovenin je stijlbestand die zegt dat de opgegeven breedte inclusief binnenruimte en rand geldt. Vrijwel elk thema zet die regel er tegenwoordig standaard in. Kom je een oude site tegen waar dat niet gebeurt, dan verklaart dat vaak de helft van de rekenfouten in de indeling.

Nog een eigenaardigheid: marges boven en onder elkaar klappen samen. Twee blokken met elk 30 pixels marge staan 30 pixels uit elkaar, niet 60. Dat verrast iedereen minstens één keer.

Flexbox voor één richting

Flexbox regelt dingen die op een rij of in een kolom staan. Een menu, een rij knoppen, een kaartje met een pictogram naast tekst.

Je zet het aan op het omhullende blok en de kinderen erin verdelen de ruimte. Je bepaalt hoe ze uitlijnen in de lengterichting en in de dwarsrichting, of ze mogen afbreken naar een volgende regel, en hoeveel ruimte er tussen zit.

Verticaal centreren, ooit het onderwerp van eindeloze grappen onder webbouwers, is hiermee twee regels. Sinds 2021 werkt de eigenschap voor tussenruimte ook in flexbox in Safari, dus je hoeft niet meer te goochelen met marges op de kinderen die je bij de eerste en de laatste weer moet weghalen.

Flexbox was rond 2015 in genoeg browsers bruikbaar. Vind je online nog een uitleg met zwevende blokken en een blok dat de zweving opheft, dan lees je iets van ruim tien jaar oud.

Grid voor twee richtingen

Grid deelt een vlak op in rijen en kolommen tegelijk. Het landde in het voorjaar van 2017 vrijwel gelijktijdig in Chrome, Firefox en Safari, en dat was voor de opmaak van webpagina's de grootste verandering in jaren.

Eén patroon wil ik uitlichten, omdat het veel werk scheelt. Je kunt een raster opdragen om zoveel kolommen te maken als er passen, met een minimum en een maximum per kolom. Een rij van zes productblokken wordt dan vanzelf twee rijen van drie op een tablet en één kolom op een telefoon, zonder dat je er een enkel breekpunt voor schrijft. Daar leunt responsive webdesign tegenwoordig op.

De vuistregel die ik aanhoud: één richting is flexbox, rijen en kolommen die op elkaar uitlijnen is grid. Ze bijten elkaar niet.

Aangepaste eigenschappen

Aangepaste eigenschappen zijn variabelen die in de browser leven. Je legt je huisstijlkleur, je afstandsmaten en je lettergroottes op één plek vast en verwijst er overal naar.

Ze werken sinds 2016, en vanaf 2017 in alle grote browsers. Het verschil met de variabelen uit Sass is dat die laatste tijdens het bouwen worden vervangen en daarna niet meer bestaan. Een aangepaste eigenschap kun je later nog overschrijven: per onderdeel, per breekpunt, of afhankelijk van de kleurvoorkeur van de bezoeker.

Dat maakt een huisstijlwijziging klein. Bij een site die met een handvol variabelen is opgezet is de accentkleur veranderen één regel. Is dat kleurtje driehonderd keer met de hand ingetikt, dan ben je een middag zoek en mis je er altijd een paar.

Media queries en containerqueries

Een media query is een blok regels dat alleen geldt onder een bepaalde voorwaarde. Meestal een schermbreedte: vanaf 900 pixels staan deze drie blokken naast elkaar, daaronder onder elkaar.

Het probleem met schermbreedte is dat een onderdeel er niets aan heeft. Een kaartje wil weten hoeveel ruimte het zelf krijgt, en dat verschilt als het de ene keer in een brede kolom staat en de andere keer in een smalle zijbalk. Met alleen media queries los je dat met extra labels op.

Containerqueries lossen dat op. Je wijst een blok aan als container en de kinderen erin reageren op de breedte van dat blok. Chrome en Safari kregen dit in de tweede helft van 2022, Firefox begin 2023, dus sindsdien kun je het zonder terugvaloptie gebruiken. Voor wie in onderdelen bouwt en niet in pagina's is dit de belangrijkste toevoeging van de afgelopen jaren.

Media queries verdwijnen daarmee niet. Je houdt ze voor de grote indeling van de pagina, voor afdrukken en voor de voorkeuren uit het besturingssysteem.

Eenheden en vloeiende maten

Pixels zijn absoluut. Rem is relatief aan de basislettergrootte van de browser, em aan die van het element eromheen. Voor lettergroottes gebruik je rem, want dan blijft de instelling werken van iemand die zijn browser op een grotere basisletter heeft gezet. Die heeft daar een reden voor.

Sinds 2020 kent CSS een functie waarmee je een minimum, een gewenste waarde en een maximum in één regel opgeeft. Daarmee schaalt een kop vloeiend mee met de schermbreedte tussen twee grenzen, zonder dat je er vier breekpunten voor nodig hebt. Dat scheelt in een typografieblok tientallen regels.

Let op met de eenheid die honderd procent van de vensterhoogte betekent. Op een telefoon rekent die de adresbalk mee die tijdens het scrollen wegschuift, waardoor een blok van een volledig scherm hoog net te hoog wordt en er onderaan iets wegvalt. Daarvoor bestaan sinds eind 2022 aparte eenheden voor de kleine, de grote en de dynamische vensterhoogte. Dat is een kleine wijziging die een hardnekkig mobiel probleem wegneemt.

Wat de bezoeker zelf heeft ingesteld

Twee voorkeuren uit het besturingssysteem komen in je CSS binnen, en je hoort er allebei iets mee te doen.

Donkere modus

Sinds 2019 kun je in CSS opvragen of iemand zijn apparaat op donker heeft staan. Een groeiend deel van de telefoons staat permanent zo. Heb je je kleuren in aangepaste eigenschappen staan, dan is een donkere variant een blokje van tien regels waarin je diezelfde variabelen anders invult.

Doe je niets, dan is dat een keuze die je mag maken. Controleer dan wel wat er gebeurt met je formulieren, want browsers kleuren invoervelden soms zelf om. Witte tekst in een wit veld is de klassieke uitkomst. Er bestaat een eigenschap waarmee je de browser vertelt welke schema's je site aankan, en die zet dat gedrag recht. Let ook op een logo in png met witte letters en een doorzichtige achtergrond, want dat verdwijnt in de ene of juist in de andere modus.

Verminderde beweging

Wie last heeft van bewegingsziekte of van duizeligheid kan in Windows, macOS, iOS en Android aangeven dat hij minder animatie wil. Die voorkeur komt bij je CSS binnen en je kunt er in één blokje op reageren door je overgangen vrijwel stil te zetten.

Dit is geen theoretisch geval. Voor een deel van de mensen is een pagina met grote schuivende blokken letterlijk misselijkmakend. Het kost je vier regels.

Toegankelijkheid zit voor een groot deel in je CSS

Het contrast tussen tekst en achtergrond is een CSS-keuze. De richtlijn WCAG 2.1 vraagt op niveau AA een verhouding van minimaal 4,5 staat tot 1 voor gewone tekst en 3 staat tot 1 voor grote tekst. Lichtgrijs op wit oogt verfijnd in een ontwerp en valt daar ruim onder.

Het focusrandje is ook CSS: het kadertje dat verschijnt als iemand met de tabtoets door je pagina loopt. Wie dat weghaalt omdat het lelijk staat, maakt zijn site onbruikbaar voor iedereen die geen muis gebruikt. Er bestaat een variant die het randje alleen bij toetsenbordgebruik toont, dus dat argument is vervallen.

Pas verder op met de volgorde van blokken omdraaien in flexbox of grid. Wat je op het scherm ziet verandert dan wel, maar de volgorde waarin de tabtoets of een schermlezer erdoorheen gaat niet. Je houdt een pagina over die er goed uitziet en met een toetsenbord onlogisch springt.

Voor bedrijven die aan consumenten leveren is dit sinds 28 juni 2025 ook een juridische kwestie. Vanaf die datum geldt de Europese toegankelijkheidsrichtlijn voor onder meer webshops, bankieren, vervoer en e-books. Micro-ondernemingen die diensten leveren zijn uitgezonderd: minder dan tien medewerkers in combinatie met een jaaromzet onder twee miljoen euro.

Wat CSS met je laadtijd doet

Een browser toont niets voordat hij je CSS heeft opgehaald en verwerkt, want anders zou je eerst ongestileerde tekst zien. Elk stijlbestand vertraagt dus het moment waarop de bezoeker iets ziet.

Bij de meeste WordPress-sites komt het merendeel van de CSS van het thema, de paginabouwer en een stuk of tien plugins die elk hun eigen bestand meesturen. Daarvan gebruikt een pagina een fractie. De rest is gewicht dat elke bezoeker meekrijgt.

Dit kun je zonder kennis van code controleren. Kijk in de netwerktab van je browser hoeveel losse stijlbestanden er binnenkomen. Staan er vijftien, dan valt er iets op te ruimen, meestal een plugin die zijn opmaak op elke pagina laadt terwijl hij alleen op het contactformulier nodig is.

CSS is bovendien lastig op te ruimen omdat niemand durft te verwijderen wat hij niet kan overzien. Vandaar dat stijlbestanden alleen maar groeien. Werk daarom met aangepaste eigenschappen, houd je selectors ondiep en verzin geen eigen systeem voor iets wat de browser al kan.

CSS in WordPress

In WordPress komt je opmaak uit drie of vier lagen tegelijk, en dat verklaart waarom een wijziging soms niet aanslaat.

Onderop ligt het stijlbestand van je thema. Bewerk dat nooit rechtstreeks, want bij de eerstvolgende update is je wijziging weg; daarvoor bestaat een kindthema. Daarboven ligt wat je in de aanpasser onder Extra CSS zet. En daarbovenop schrijft je paginabouwer per pagina zijn eigen bestand of een blok in de kop.

Dat laatste is ook waar de mobiele problemen ontstaan. Zet je in een paginabouwer de breedte van een kolom of een blok in pixels in plaats van in procenten, dan blijft dat blok op een telefoon precies zo breed. De pagina wordt daarmee breder dan het scherm, je krijgt een horizontale schuifbalk en de rest van de inhoud lijkt ingezoomd. Op je eigen brede monitor zie je er niets van.

Zoek je zo'n blok, geef dan tijdelijk in je Extra CSS elk element een dun randje. Wat buiten het scherm steekt zie je meteen. De oplossing is bijna altijd de vaste breedte vervangen door een maximale breedte, zodat het blok wel mag krimpen. Dezelfde fout zit in een negatieve marge, in een tabel uit Word en in een achtergrondafbeelding met een vaste afmeting. De valkuilen zijn gelijk bij Beaver Builder en bij Elementor.

Frameworks en preprocessors

Bootstrap en Tailwind geven je een set kant-en-klare keuzes voor kleuren, afstanden en onderdelen. Handig als je snel iets werkends wilt neerzetten of met meerdere mensen aan hetzelfde project werkt. Je sleept er wel veel mee dat je niet gebruikt, en een site gebouwd met standaardonderdelen ziet er ook uit als een site gebouwd met standaardonderdelen.

Sass en Less voegden ooit toe wat CSS zelf niet had: variabelen, nesting, functies, bestanden opsplitsen. Variabelen zitten nu in de browser en nesting kwam er in 2023 bij, dus de reden om een preprocessor te draaien is kleiner geworden.

Voor een bedrijfssite van tien tot dertig pagina's kun je dit alles overslaan. Een eigen stijlbestand van een paar honderd regels bovenop een fatsoenlijk thema is sneller en over twee jaar nog te begrijpen. Wat een bibliotheek precies is en wanneer je hem wel wilt, staat bij webontwikkelingsbibliotheken.

Hoe je het leert

Begin bij HTML, want zonder begrip van de structuur is CSS gokwerk. Leer daarna eerst flexbox en grid. Die twee lossen het grootste deel van je indelingsproblemen op en de rest is detailwerk.

MDN Web Docs is het naslagwerk waar ik zelf dagelijks in kijk. Werkt iets in alle browsers? Dat zoek je op caniuse.com op. Sinds Microsoft in juni 2022 de ondersteuning van Internet Explorer 11 beëindigde is die vraag trouwens zelden nog spannend. De verschillen die overblijven zitten in details, waarover meer staat bij cross-browser compatibiliteit.

Wees voorzichtig met oude tutorials. Alles wat zwevende blokken gebruikt voor de indeling of een raster van twaalf kolommen namaakt met procentbreedtes, kun je overslaan.

Veelgestelde vragen over CSS

Waar staat CSS voor?

CSS staat voor Cascading Style Sheets, in het Nederlands trapsgewijze stijlbladen. Het woord cascading verwijst naar de manier waarop de browser bepaalt welke regel wint als er meerdere regels op hetzelfde element van toepassing zijn.

Wat is het verschil tussen HTML en CSS?

HTML beschrijft wat iets is: dit is een kop, dit is een alinea, dit is een link. CSS beschrijft hoe dat eruitziet: welke kleur, welk lettertype, hoeveel ruimte, waar op het scherm. Een pagina met alleen HTML werkt gewoon, hij ziet er alleen uit als een document uit 1995.

Moet ik CSS kunnen schrijven voor mijn eigen website?

Nee. Met WordPress en een paginabouwer stel je vrijwel alles in via schermpjes. Wat wel helpt is de begrippen kennen: binnenruimte, marge, breekpunt, maximale breedte. Dan begrijp je wat je instelt en waarom het op een telefoon anders uitpakt. Een handvol regels eigen CSS levert de meeste ondernemers al genoeg op: een lettergrootte bijstellen, een knop opvallender maken, iets verbergen dat je thema meelevert en jij niet wilt.

Waar zet ik eigen CSS in WordPress?

Voor losse regels gebruik je Extra CSS in de aanpasser, of het gelijknamige veld in je paginabouwer. Dat overleeft updates en je kunt het terugdraaien. Gaat het om meer dan een scherm vol regels, maak dan een kindthema. Bewerk in geen geval het stijlbestand van je thema zelf, want dat wordt bij de eerstvolgende update overschreven.

Waarom werkt mijn CSS-regel niet?

Meestal omdat een andere regel wint. Klik het element aan in de ontwikkelaarshulpmiddelen van je browser: de verliezers staan doorgestreept, dus je ziet meteen wie je in de weg zit.

De tweede reden is caching. Bij WordPress met een cacheplugin of met Cloudflare ervoor krijg je vaak nog de oude versie te zien. Leeg de cache voordat je gaat zoeken naar een fout die er niet is.

Wat doet !important en mag ik het gebruiken?

Het zet een regel boven alle andere regels, ongeacht specificiteit. Het is bedoeld als noodrem, bijvoorbeeld om iets van een plugin te overrulen waar je verder niet bij kunt. Gebruik het spaarzaam: zodra twee regels het allebei hebben ben je terug bij af, en stijlbestanden waarin het overal staat zijn niet meer te onderhouden.

Wat is het verschil tussen padding en margin?

Padding is de ruimte binnen een blok, tussen de rand en de inhoud. Margin is de ruimte buiten een blok, tussen dat blok en zijn buren.

Een achtergrondkleur loopt wel door de padding en niet door de margin. Dat is de snelste manier om te zien welke van de twee je nodig hebt.

Wanneer gebruik ik flexbox en wanneer grid?

Flexbox als je één richting hebt: een rij knoppen, een menu, een pictogram naast tekst. Grid als je rijen en kolommen tegelijk hebt die op elkaar moeten uitlijnen, zoals een overzicht van kaartjes of de hoofdindeling van een pagina. In de praktijk gebruik je ze door elkaar in hetzelfde ontwerp: grid voor de pagina, flexbox voor wat er binnen de blokken gebeurt.

Wat is het verschil tussen px, em en rem?

Px is een vaste maat. Em is relatief aan de lettergrootte van het element eromheen, wat bij geneste elementen tot opstapeling leidt. Rem is relatief aan de basislettergrootte van de browser en stapelt niet op.

Gebruik rem voor lettergroottes, zodat de instelling van iemand die grotere letters heeft ingesteld blijft werken. Voor randen en kleine details is px prima.

Hoe maak ik mijn website geschikt voor de donkere modus?

Met een media query die opvraagt of de bezoeker een donker kleurschema heeft ingesteld. Daarbinnen geef je je kleurvariabelen andere waarden. Staat je huisstijl netjes in aangepaste eigenschappen, dan is dat een blokje van tien regels.

Kies je ervoor niets te doen, controleer dan in elk geval je formulieren en je e-mails. Daar ontstaan de onleesbare combinaties, zoals witte tekst in een wit invoerveld.

Heb ik Bootstrap of Tailwind nodig?

Voor een gewone bedrijfswebsite niet. Grid en flexbox doen het werk waar Bootstrap ooit voor werd gehaald, en je site wordt er lichter van. Werk je met meerdere ontwikkelaars aan een grotere toepassing, dan is een framework wel nuttig, omdat iedereen dan dezelfde afspraken volgt.

Hoe kom ik van ongebruikte CSS af?

Het meeste ongebruikte gewicht komt niet uit jouw eigen regels maar uit plugins en thema's die op elke pagina hun opmaak laden. Kijk eerst welke plugins meesturen wat ze niet nodig hebben en zet die per pagina uit met een prestatieplugin die dat kan.

Automatisch verwijderen van ongebruikte selectors kan, en het gaat regelmatig mis bij onderdelen die pas na een klik verschijnen. Test dus je menu, je formulieren en je pop-ups voordat je het aanzet.

Vertraagt CSS mijn website?

Ja, want de browser toont niets voordat de CSS binnen en verwerkt is. Hoeveel dat scheelt hangt af van het aantal losse bestanden en de totale omvang. De grootste winst zit meestal in minder verzoeken en in lettertypen beperken tot de gewichten die je echt gebruikt, want elk gewicht is een apart bestand.

Waar leer ik CSS?

MDN Web Docs is het beste naslagwerk en is gratis. Leer in deze volgorde: HTML, het doosmodel, flexbox, grid, aangepaste eigenschappen. Sla alles over wat zwevende blokken gebruikt om een indeling te maken.

Dit artikel hoort bij Webdevelopment. Daar vind je meer uitleg over hetzelfde onderwerp.

Een vraag over dit onderwerp?

Vertel waar je tegenaan loopt.

Maurits denkt met je mee en geeft je een praktisch antwoord.

reactie dezelfde werkdag
Maurits van Platform Pro

Vertel kort waar je aan denkt

Nu gesloten, ik reageer de volgende werkdag

Maurits leest je bericht en neemt persoonlijk contact met je op.

Dit veld is bedoeld voor validatiedoeleinden en moet niet worden gewijzigd.
Dit veld is verborgen bij het bekijken van het formulier