Tot nu toe heb je in CSS voornamelijk elementen gestijld die letterlijk in je HTML-structuur geschreven staan. Maar wat als je decoratieve lijntjes of ikoontjes wilt toevoegen zonder je HTML te bevuilen met nutteloze <div>-tags? Of wat als je een specifiek patroon van elementen wilt stylen, of de volledige achtergrond van een kaart wilt laten oplichten zodra een bezoeker in een invoerveld typt?
Hier komen geavanceerde pseudo-elementen en pseudo-klassen in beeld!
In deze les ontdek je hoe je met ::before, ::after, :nth-child() en :focus-within de controle over je lay-outs naar een professioneel niveau tilt.
Voordat we de diepte in duiken, is het belangrijk om het verschil tussen beide begrippen goed te onthouden:
:): Selecteert een element op basis van een bepaalde toestand of positie (bijv. :hover, :focus, :nth-child()).::): Maakt een virtueel nieuw element aan in de DOM of selecteert een specifiek onderdeel van een element (bijv. ::before, ::after, ::first-letter).::before en ::afterDe pseudo-elementen ::before en ::after laten je toe om content aan een element toe te voegen via CSS, zonder dat je daar extra HTML voor hoeft te schrijven.
::before voegt een virtueel element toe als eerste kind van het geselecteerde element.::after voegt een virtueel element toe als laatste kind van het geselecteerde element.┌─────────────────────────────────────────┐
│ <button class="btn"> │
│ ::before <─── (Wordt hier ingevoegd) │
│ "Klik hier" │
│ ::after <─── (Wordt hier ingevoegd) │
│ </button> │
└─────────────────────────────────────────┘
content is Verplicht!Een ::before of ::after verschijnt alleen op de pagina als je de CSS-eigenschap content opgeeft. Zelfs als je een leeg vakje wilt maken voor een decoratieve achtergrond, moet je content: ""; schrijven!
/* Voorbeeld: Een strakke decoratieve onderstreping bij een titel */
.section-title {
position: relative;
font-size: 2rem;
color: #0f172a;
}
.section-title::after {
content: ""; /* VERPLICHT! */
display: block;
width: 60px;
height: 4px;
background-color: #2563eb;
margin-top: 8px;
border-radius: 2px;
}
💡 Waarvoor gebruik je::beforeen::after?
perfect voor decoratieve accenten, gekleurde lijntjes onder titels, opvallende 'quotes' rond getuigenissen, badges ("Nieuw!"), of handige overlays over afbeeldingen.
:nth-child()Met de pseudo-klasse :nth-child() kun je elementen selecteren op basis van hun volgorde binnen hun ouder-container. Dit bespaart je het handmatig toevoegen van tientallen extra classes in je HTML.
/* Selecteert exact het 3e item */
li:nth-child(3) {
color: #2563eb;
}
/* Selecteert alle EVEN items (2, 4, 6, ...) - Ideaal voor tabelrijen! */
tr:nth-child(even) {
background-color: #f8fafc;
}
/* Selecteert alle ONEVEN items (1, 3, 5, ...) */
tr:nth-child(odd) {
background-color: #ffffff;
}
Door een formule te gebruiken waarin $n$ een teller is (die begint bij 0, 1, 2, ...), kun je complexe reeksen selecteren:
:nth-child(3n): Selecteert elk 3e element ($3, 6, 9, 12, \dots$).:nth-child(3n + 1): Selecteert het 1e, 4e, 7e, 10e element.:nth-child(-n + 3): Selecteert de eerste 3 elementen van een lijst!:nth-child(n + 4): Selecteert alles vanaf het 4e element tot het einde./* De eerste 3 kaarten in een webshop extra opvallend maken */
.product-card:nth-child(-n + 3) {
border-top: 4px solid #ef4444;
}
:focus-withinDe bekende pseudo-klasse :focus werkt enkel op het element waar de gebruiker op dat moment actief mee bezig is (bijvoorbeeld het tekstveld waarin getypt wordt).
De krachtige pseudo-klasse :focus-within reageert op de ouder-container zodra één van de kinderen de focus krijgt!
/* Zodra de gebruiker in het <input> veld typt, kleurt het hele OUDER-blok mee! */
.input-card {
background-color: #ffffff;
border: 2px solid #e2e8f0;
padding: 20px;
border-radius: 10px;
transition: all 0.3s ease;
}
/* Krijgt focus-within zodra het input-veld IN de .input-card focus krijgt */
.input-card:focus-within {
border-color: #2563eb;
box-shadow: 0 10px 25px rgba(37, 99, 235, 0.15);
background-color: #eff6ff;
}
Waarom :focus-within fantastisch is voor UX:
Je kunt een compleet formulierblok, een hele zoekbalk-groep, of een navigatiemenu geavanceerd laten oplichten en transformeren zodra de bezoeker erin navigeert met muis of toetsenbord, wat de toegankelijkheid (accessibility) enorm verhoogt!
| Selector | Type | Wat doet het? | Veelgebruikte toepassing |
|---|---|---|---|
::before | Pseudo-element | Voegt virtuele content toe aan het begin van een element. | Decoratieve iconen, vlaggetjes, quotes. |
::after | Pseudo-element | Voegt virtuele content toe aan het einde van een element. | Decoratieve onderlijnen, pijl-iconen, clears. |
:nth-child() | Pseudo-klasse | Selecteert elementen op basis van hun index/positie. | Zebra-tabellen, speciale grids, patronen. |
:focus-within | Pseudo-klasse | Activeert op de parent als een kind-element focus heeft. | Actieve formulieren, toegankelijke menu's. |
In dit praktijkvoorbeeld combineren we al deze geavanceerde technieken in een interactief formulier met een dynamische lijst.
index.html)<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Geavanceerde Pseudo Selectors</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="container">
<h1 class="title">Inschrijven Workshop</h1>
<!-- Formuliergroep met :focus-within -->
<form class="form-card">
<div class="form-group">
<label for="naam">Volledige Naam</label>
<input type="text" id="naam" placeholder="bijv. Alex Peeters">
</div>
<div class="form-group">
<label for="email">E-mailadres</label>
<input type="email" id="email" placeholder="alex@voorbeeld.be">
</div>
</form>
<!-- Lijst met :nth-child en ::before -->
<section class="info-section">
<h2>Belangrijke Regels</h2>
<ul class="styled-list">
<li>Breng je eigen laptop en lader mee.</li>
<li>Zorg dat je Visual Studio Code vooraf geïnstalleerd is.</li>
<li>Meld je 15 minuten voor aanvang aan bij de receptie.</li>
<li>Lunch en verfrissingen worden voorzien door de school.</li>
</ul>
</section>
</main>
</body>
</html>
style.css)/* Reset & Basis */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Inter', system-ui, sans-serif;
background-color: #f1f5f9;
color: #0f172a;
padding: 40px 20px;
}
.container {
max-width: 600px;
margin: 0 auto;
}
/* 1. TITEL MET ::after (DECORATIEVE LIJN) */
.title {
position: relative;
font-size: 2.25rem;
margin-bottom: 32px;
}
.title::after {
content: "";
display: block;
width: 80px;
height: 5px;
background-color: #2563eb;
margin-top: 8px;
border-radius: 3px;
}
/* 2. FORMULIER MET :focus-within */
.form-card {
background-color: #ffffff;
padding: 24px;
border-radius: 12px;
border: 2px solid #cbd5e1;
margin-bottom: 40px;
transition: all 0.3s ease;
}
/* Als een input binnen het formulier focus krijgt, licht de hele kaart op! */
.form-card:focus-within {
border-color: #2563eb;
box-shadow: 0 12px 24px rgba(37, 99, 235, 0.12);
transform: translateY(-2px);
}
.form-group {
margin-bottom: 16px;
}
.form-group:last-child {
margin-bottom: 0;
}
label {
display: block;
font-weight: 600;
margin-bottom: 6px;
font-size: 0.9rem;
}
input {
width: 100%;
padding: 12px;
border: 1px solid #94a3b8;
border-radius: 6px;
outline: none;
transition: border-color 0.2s;
}
input:focus {
border-color: #2563eb;
}
/* 3. LIJST STYLING MET ::before EN :nth-child() */
.info-section h2 {
font-size: 1.5rem;
margin-bottom: 16px;
}
.styled-list {
list-style: none;
}
.styled-list li {
position: relative;
padding: 14px 16px 14px 44px;
margin-bottom: 8px;
border-radius: 8px;
background-color: #ffffff;
}
/* Custom opsommingsteken maken met ::before */
.styled-list li::before {
content: "✓";
position: absolute;
left: 16px;
top: 50%;
transform: translateY(-50%);
font-weight: bold;
color: #2563eb;
}
/* :nth-child(): Even en Oneven rijen een subtiele achtergrondafwijking geven */
.styled-list li:nth-child(even) {
background-color: #f8fafc;
}
/* :nth-child(): Het allereerste lijstitem een speciale accentkleur geven */
.styled-list li:nth-child(1) {
border-left: 4px solid #2563eb;
}
::before & ::after creëren virtuele elementen in CSS. Onthoud dat de eigenschap content: ""; verplicht is.:nth-child() laat je elementen selecteren op basis van patronen zoals even, odd of wiskundige formules als 3n en -n + 3.:focus-within geef styling aan een ouder-element zodra een van de kinderen focus krijgt (geweldig voor formulieren en toegankelijkheid).