Voor je met CSS-positionering werkt, moet je eerst begrijpen hoe elementen zich standaard gedragen in een webpagina. Browsers plaatsen HTML-elementen namelijk volgens de normale document flow.
Pas wanneer je die standaardflow begrijpt, wordt duidelijk wat
position: relative, absolute, fixed en
sticky precies veranderen.
De document flow is de gewone volgorde waarin de browser HTML-elementen op de pagina zet. Block-level elementen worden onder elkaar geplaatst. Inline elementen staan op dezelfde regel, zolang er voldoende plaats is.
Elementen zoals <div>, <p>,
<section> en <h1> zijn block-level elementen.
Ze starten normaal op een nieuwe regel en nemen standaard de volledige breedte in van hun parent element.
<div>Eerste div-element</div>
<div>Tweede div-element</div>
Inline elementen zoals <span> en <a> blijven
standaard op dezelfde regel staan en nemen enkel de ruimte in die ze nodig hebben.
<span>Inline element</span>
<span>Nog een inline element</span>
Inline element
Nog een inline element
Opgelet: inline elementen reageren standaard niet zoals block-level elementen op
width en height.
HTML-elementen kunnen ook in elkaar genest worden. Een parent element kan één of meerdere child-elementen bevatten.
<div class="flow-nested">
<p>Dit is een paragraaf binnen een div.</p>
</div>
Dit is een paragraaf binnen een div.
Zodra je elementen gaat positioneren met CSS, kan je ze visueel verplaatsen of zelfs volledig uit de normale document flow halen. Daardoor kunnen elementen elkaar overlappen of onverwacht reageren.
Wie document flow niet begrijpt, begrijpt meestal ook niet waarom een element plots “verkeerd” staat.
position
Met de CSS-eigenschap position bepaal je hoe een element zich gedraagt
ten opzichte van de normale document flow en ten opzichte van andere elementen.
De belangrijkste waarden zijn:
staticrelativeabsolutefixedstickyOpgelet: zodra een element uit de normale document flow wordt gehaald, reageren andere elementen daar niet meer op. Dat is vaak de oorzaak van overlap of onverwachte layoutproblemen.
position: static
static is de standaardwaarde. Een element met
position: static volgt gewoon de normale document flow.
De eigenschappen top, right, bottom,
left en z-index hebben bij een statisch element geen effect.
.element {
position: static;
top: 20px; /* heeft geen effect */
}
In echte projecten schrijf je zelden expliciet position: static,
omdat dit al de standaardinstelling is.
position: relativeEen relatief gepositioneerd element blijft deel uitmaken van de normale document flow, maar kan visueel verschoven worden ten opzichte van zijn oorspronkelijke plaats.
Dat betekent:
De eigenschappen top, right, bottom en
left verplaatsen het element ten opzichte van zijn oorspronkelijke positie.
<div class="relative-demo">Ik ben relatief gepositioneerd</div>
.relative-demo {
position: relative;
top: 10px;
left: 20px;
background-color: lightblue;
padding: 0.75rem;
}
Een relatief gepositioneerd element is ook belangrijk omdat het vaak dient als referentiepunt voor een absoluut gepositioneerd child-element.
position: absoluteEen absoluut gepositioneerd element wordt volledig uit de normale document flow gehaald. Andere elementen doen dus alsof het er niet meer is.
Een absoluut element positioneert zich ten opzichte van het dichtstbijzijnde parent element
dat zelf een position heeft anders dan static.
In de praktijk is dat vaak een parent met position: relative.
Als er geen gepositioneerde parent bestaat, positioneert het element zich ten opzichte van de viewport.
<div class="absolute-stage">
Parent element
<div class="absolute-demo">Absolute</div>
</div>
.absolute-stage {
position: relative;
height: 160px;
border: 1px solid #ccc;
padding: 1rem;
}
.absolute-demo {
position: absolute;
top: 20px;
right: 20px;
background-color: lightgreen;
padding: 0.75rem;
}
Dit gebruik je bijvoorbeeld voor:
position: fixedEen fixed element wordt gepositioneerd ten opzichte van de viewport. Dat betekent dat het op dezelfde plaats blijft staan, ook wanneer je scrollt.
<div class="fixed-demo">Ik blijf staan</div>
.fixed-demo {
position: fixed;
bottom: 10px;
left: 10px;
background-color: lightcoral;
padding: 0.5rem 0.75rem;
}
Veelgebruikte toepassingen zijn:
Omdat een fixed element boven de rest kan zweven, gebruik je deze techniek best doordacht.
position: sticky
Sticky is een combinatie van relative en fixed.
Het element gedraagt zich eerst alsof het gewoon in de flow zit, maar blijft “plakken”
zodra een bepaalde drempel bereikt wordt.
In dit voorbeeld staat het sticky element niet meteen bovenaan. Tijdens het scrollen schuift het eerst mee omhoog, en zodra het de ingestelde grens bereikt, blijft het staan.
<div class="sticky-scrollbox">
<p>Scroll naar beneden…</p>
<p>Nog meer content…</p>
<div class="sticky-demo">Ik ben sticky</div>
<p>Nog meer content…</p>
<p>Nog meer content…</p>
<p>Nog meer content…</p>
<p>Nog meer content…</p>
<p>Nog meer content…</p>
</div>
.sticky-scrollbox {
height: 260px;
overflow: auto;
border: 1px solid #ccc;
padding: 1rem;
}
.sticky-demo {
position: sticky;
top: 1rem;
background-color: lightpink;
padding: 0.75rem;
}
Scroll naar beneden…
Nog meer content…
Nog meer content…
Nog meer content…
Nog meer content…
Nog meer content…
Nog meer content…
Nog meer content…
Nog meer content…
Sticky werkt alleen als:
top: 1rem,top, right, bottom en left
Deze eigenschappen bepalen de afstand tot een rand. Ze werken niet bij
position: static, maar wel bij andere positioneringsmethodes.
top: afstand tot de bovenkantright: afstand tot de rechterkantbottom: afstand tot de onderkantleft: afstand tot de linkerkant
Bij relative verschuiven ze het element ten opzichte van zijn oude plaats.
Bij absolute, fixed en sticky bepalen ze waar het element komt te staan.
position
Met position bepaal je of een element:
static),relative),absolute),fixed),sticky).z-index
Zodra elementen elkaar overlappen, wordt het belangrijk om te bepalen welk element
visueel bovenaan ligt. Daarvoor gebruik je z-index.
Je kan z-index zien als de volgorde op de denkbeeldige Z-as:
niet van links naar rechts, niet van boven naar onder, maar van voor naar achter.
Belangrijk: z-index werkt alleen op elementen met
een positionering anders dan static.
In dit voorbeeld overlappen twee absoluut gepositioneerde elementen.
Het element met de hoogste z-index ligt bovenaan.
<div class="z-stage">
<div class="z-box z-behind">z-index: 1</div>
<div class="z-box z-front">z-index: 2</div>
</div>
.z-stage {
position: relative;
width: 240px;
height: 180px;
border: 1px solid #ccc;
}
.z-box {
position: absolute;
width: 130px;
height: 130px;
}
.z-behind {
z-index: 1;
}
.z-front {
z-index: 2;
top: 30px;
left: 50px;
}
Een stacking context is een soort “groep” of “laag” waarin elementen met elkaar vergeleken worden.
Alleen elementen binnen dezelfde stacking context kunnen rechtstreeks met elkaar vergeleken worden via z-index.
Met andere woorden: stacking contexts bepalen welke z-index waarden met elkaar vergeleken worden.
Een element met z-index: 999 kan niet zomaar boven een element uit een andere stacking context springen.
Een stacking context ontstaat onder andere door:
z-index,opacity kleiner dan 1,transform,z-indexz-index gebruiken op een element zonder positionering,
Tip: probeer z-index-problemen eerst te begrijpen via structuur en positionering,
niet door zomaar 9999 te gebruiken.
z-index soms “niet werkt”
Soms lijkt het alsof z-index geen enkel effect heeft, zelfs wanneer je
een heel hoge waarde gebruikt. In de meeste gevallen ligt dat niet
aan z-index zelf, maar aan het feit dat elementen zich in
verschillende stacking contexts bevinden.
Alleen elementen die zich binnen dezelfde stacking context bevinden,
kunnen met elkaar vergeleken worden via z-index.
Zodra een parent element een nieuwe stacking context creëert, begint de stapelvolgorde daar opnieuw.
<div class="stacking-demo">
<div class="stacking-col">
<h3 class="h6">Context A (normaal)</h3>
<div class="stacking-stage">
<div class="stacking-bg">Achtergrond</div>
<div class="stacking-label">LABEL (z-index: 999)</div>
</div>
</div>
<div class="stacking-col stacking-context">
<h3 class="h6">Context B (nieuwe stacking context)</h3>
<div class="stacking-stage">
<div class="stacking-card">Kaart</div>
<div class="stacking-label">LABEL (z-index: 999)</div>
</div>
</div>
</div>
.stacking-context {
/* Deze eigenschap creëert een nieuwe stacking context */
transform: translateY(0);
}
transform
Samengevat: z-index werkt altijd correct, maar alleen binnen dezelfde
stacking context. Eigenschappen zoals transform kunnen onzichtbaar
een nieuwe context creëren en zo de verwachte volgorde doorbreken.
z-index
z-index bepaalt welke elementen boven of onder elkaar liggen,
maar werkt enkel in combinatie met positionering en binnen dezelfde stacking context.
Wie begrijpt hoe stacking contexts werken, zal veel sneller begrijpen waarom een element soms niet bovenaan komt, zelfs met een hoge z-index.
Gebruik dit schema als snelle geheugensteun bij oefeningen.
position: relative<body> gebruikttransform, opacity, filterposition: relativetop ingesteldoverflow: hidden of autoposition: relative?