Uitleg verticaal centreren van pagina of blok-element met bekende hoogte

Skip links en inhoudsopgave

Laatst aangepast: .

Afbeelding 1: verticaal gecentreerde pagina en blok-elementen

Korte omschrijving

Verticaal centreren van pagina of blok-element met bekende, vaste hoogte.

Gele blok

Pagina. Verticaal binnen het venster van de browser gecentreerd.

Roze blok

Binnen de pagina (gele blok) verticaal gecentreerde div.

Groene blok

Binnen de pagina (gele blok) verticaal gecentreerde div.

Blauwe blok

Binnen het groene blok horizontaal én verticaal gecentreerde div.

BELANGRIJK

Alles op deze site kan vrij worden gebruikt, met twee beperkingen:

* Je gebruikt het materiaal op deze site volledig op eigen risico. Het kan prima zijn dat er fouten in de hier verstrekte info zitten. Voor eventuele schade die door gebruik van materiaal van deze site ontstaat, in welke vorm dan ook, zijn www.css-voorbeelden.nl en medewerkers daarvan op geen enkele manier verantwoordelijk.

* Deze uitleg wordt regelmatig bijgewerkt. Het is daarom niet toegestaan deze uitleg op welke manier dan ook te verspreiden, zonder daarbij duidelijk te vermelden dat de uitleg afkomstig is van www.css-voorbeelden.nl en dat daar altijd de nieuwste versie is te vinden. Dit is om te voorkomen dat er verouderde versies worden verspreid.

Een link naar www.css-voorbeelden.nl wordt trouwens altijd op prijs gesteld.

Opmerkingen

Deze manier van verticaal centreren werkt alleen maar bij een vaste hoogte van pagina of blok-element. Voor het centreren van andere elementen zie positioneren.

In dit voorbeeld worden alleen divs verticaal gecentreerd, maar je kunt álle blok-elementen met een bekende hoogte op deze manier verticaal centreren.

Alles op deze site is gemaakt op een systeem met Linux (Kubuntu). Daarbij is vooral gebruik gemaakt van Komodo Edit, GIMP en Firefox met extensies. De pdf-bestanden zijn gemaakt met LibreOffice.

Links in deze uitleg, vooral links naar andere sites, kunnen verouderd zijn. Op de pagina met links vind je steeds de meest recente links.

Vragen of opmerkingen? Fout gevonden? Ga naar het forum.

Iets gevonden waar je wat aan hebt? Mooi. Als je je waardering wilt uiten, maak dan een donatie over aan War Child Nederland, een organisatie die kinderen uit oorlogsgebieden helpt hun trauma's te verwerken. Of - nog beter - wordt donateur:
War Child Nederland

Achterliggend idee

Met html en css kun je niet simpel de grootte van het venster van de browser meten, zoals bijvoorbeeld met JavaScript kan. Voor de breedte is dat geen probleem: tenzij je iets anders opgeeft wordt standaard het hele venster gebruikt. Als de regel vol is wordt gewoon naar de volgende regel gegaan, en als het venster vol is verschijnt er 'n scrollbalk en kun je naar beneden gaan.

Als je 'n vaste breedte aan de pagina geeft, kun je ook simpel horizontaal centreren.

Verticaal centreren is veel lastiger, want daar is geen simpele opdracht voor. Als de pagina of het blok een vaste hoogte heeft is er gelukkig 'n tamelijk simpele truc om toch verticaal te kunnen centreren.

Stel dat de hoogte 400 px is. Als ik dan de bovenkant van de pagina halverwege het venster van de browser zet, en dan de helft van de hoogte terug omhoog ga - in dit geval 200 px - staat de bovenkant dus 200 px boven de middellijn van het venster, en de onderkant dus daaronder: de pagina is verticaal gecentreerd.

Op dezelfde manier kan ik ook blokken verticaal centreren binnen andere blokken.

Er kleven wel wat nadelen aan deze methode. Om de bovenkant van pagina of blok halverwege het venster van de browser te zetten, móét de pagina of blok een absolute positie hebben. Anders kan ik immers niet de opdracht top: 50% gebruiken.

Bij de pagina is er eigenlijk geen enkel nadeel aan het gebruik van position: absolute; verbonden, mist je op lage schermen let, waarover verderop meer. Maar bij blokken betekent het dat het blok niet meedoet bij de normale opbouw van het scherm. Dat kan lastig zijn, en het is dan ook absoluut nodig de opbouw van de pagina in zoveel mogelijk verschillende browsers te controleren.

Soms kun je ook position: relative; gebruiken, maar ook dat heeft nadelen als je 't veel gebruikt. position: absolute; wordt bepaald ten opzichte van het ouder-element van het blok-element wat je absoluut wilt positioneren (op voorwaarde dat dit ouder-element zelf 'n relatieve, fixed of absolute positie heeft, anders wordt het daarboven liggende ouder-element gebruikt, enz. Als er geen enkel ouder-element is met 'n positie, wordt uiteindelijk het browservenster gebruikt.).

Bij position: relative; wordt de positie bepaald ten opzichte van de normale positie die het blok zou hebben gehad zonder positie. Dus bijvoorbeeld top: 10px betekent dat ten opzichte van de normale positie 10 px omlaag wordt gegaan. Maar de oorspronkelijke ruimte wordt nog steeds in beslag genomen. Andere elementen kijken dan ook niet naar de relatieve positie, maar naar de oorspronkelijke positie. Dat kan tot onverwachte problemen leiden: waarom staat die paragraaf nou opeens 30 px lager? Terwijl erboven 'n lege ruimte zit? Nou, misschien omdat 't element erboven 30 px relatief omhoog is verplaatst.

Ook hier geldt dus dat je zeer goed moet controleren in verschillende browsers.

Uiteindelijk is het gebruik van relative of absolute vaak 'n kwestie van voorkeur.

Bij het verticaal centreren van de buitenste div, waarbinnen de hele pagina staat, kan zich een apart probleem voordoen. De div, en daarmee de pagina, komt half boven en half onder het midden van het browservenster te staan. Als de div aan de onderkant lager dan dat venster komt, verschijnt gewoon een verticale scrollbalk. Maar als de div boven de bovenkant van het browservenster uitkomt, verschijnt geen scrollbalk. Wat aan de bovenkant 'uitsteekt', is volledig onzichtbaar.

Daarom wordt de buitenste div pas verticaal gecentreerd, als met behulp van de nieuwe css3-regel @media is gecontroleerd op voldoende hoogte.

Beschrijving van code en css

De code die te maken heeft met de basis van dit voorbeeld is blauw gekleurd. Alle voor dit voorbeeld niet-essentiële code is bruin.

Deze uitleg hoort bij het voorbeeld dat in de download zit. Het voorbeeld uit de download verschilt iets van het voorbeeld hier op de site. In de download ontbreken bijvoorbeeld de navigatie voor de site. Ook in de kopregels zit vaak wat verschil. Daarnaast kunnen er nog andere (meestal kleine) verschillen zijn.

Als je deze uitleg leest naast de broncode van het voorbeeld op de site, kan het dus bijvoorbeeld zijn dat 'n <h1> uit de css bij 'n <h2> uit de html hoort. Maar het gaat niet om hele grote, fundamentele afwijkingen.

Als je dit lastig vindt, downloadt dan de hele handel (ga terug naar het voorbeeld en kies daar voor downloaden). In de download zit 'n voorbeeld dat wel naadloos aansluit op de uitleg in de download.

<!DOCTYPE html>

<html lang="nl">

Een document moet met een doctype beginnen om weergaveverschillen tussen browsers te voorkomen. Zonder doctype is de kans op verschillende (en soms volkomen verkeerde) weergave tussen verschillende browsers heel erg groot.

Geldige doctypes vind je op www.w3.org/QA/2002/04/valid-dtd-list.

Gebruik het volledige doctype, inclusief de eventuele url, anders werkt het niet goed.

Het hier gebruikte doctype is dat van html5.

<meta charset="utf-8">

Zorgt dat de browser letters met accenten en dergelijke goed kan weergeven.

utf-8 is de beste charset (tekenset), omdat deze alle talen van de wereld (en nog heel veel andere extra tekens) bestrijkt, maar toch niet meer ruimte inneemt voor de code, dan nodig is. Als je utf-8 gebruikt, hoef je veel minder entiteiten (&auml; en dergelijke) te gebruiken, maar kun je bijvoorbeeld gewoon ä gebruiken.

Deze regel moet zo hoog mogelijk komen te staan, als eerste regel binnen de head, omdat hij anders door sommige browsers niet wordt gelezen.

In html5 hoeft deze regel niet langer te zijn, dan wat hier staat.

<meta name="viewport" content="width=device-width, initial-scale=1">

Mobiele apparaten variëren enorm in breedte. En dat is een probleem. Sites waren, in ieder geval tot voor kort, gemaakt voor desktopbrowsers. En die hebben, in vergelijking met bijvoorbeeld een smartphone, heel brede vensters. Hoe moet je op 'n smartphone een pagina weergeven, die is gemaakt voor de breedte van een desktop? Je kunt natuurlijk wachten tot álle sites zijn omgebouwd voor smartphones, tablets, enz., maar dan moet je waarschijnlijk heel erg lang wachten.

Mobiele browsers gokken erop dat een pagina een bepaalde breedte heeft. Safari voor mobiel bijvoorbeeld gaat ervan uit dat een pagina 980 px breed is. De pagina wordt vervolgens zoveel versmald, dat hij binnen het venster van het apparaat past. Op een iPhone wordt de pagina dus veel smaller dan op een iPad. Vervolgens kan de gebruiker inzoomen op het deel van de pagina dat hij of zij wil zien.

Dit betekent ook dat bij het openen van de pagina de tekst meestal heel erg klein wordt weergegeven. (Meestal, want niet alle browsers en apparaten doen het op dezelfde manier.) Niet erg fraai, maar bedenk maar 'ns 'n betere oplossing voor bestaande sites.

Nieuwe sites of pagina's kunnen echter wel rekening houden met de veel kleinere vensters van mobiele apparaten. Deze pagina bijvoorbeeld past zich aan de breedte van het venster aan, ook bij heel smalle vensters. Maar die stomme mobiele browser weet dat niet, dus die gaat ervan uit dat ook de aangepaste pagina 980 px breed is, en verkleint die dan. Dat is ongeveer even behulpzaam als de gedienstige kelner die behulpzaam de stoel naar achteren trekt, net als jij wilt gaan zitten.

Om de door de browser aangeboden hulp vriendelijk maar beslist te weigeren, wordt deze tag gebruikt. Hiermee geef je aan dat de pagina is geoptimaliseerd voor mobiele apparaten.

Een iPad in portretstand bijvoorbeeld is 768 px breed. De kreet width=device-width zegt tegen de mobiele browser dat de breedte van de weer te geven pagina gelijk is aan de breedte van het apparaat. Voor een iPad in portretstand dus 768 px. En dat klopt, want de weer te geven pagina past zich automatisch aan de breedte van het apparaat aan, omdat de pagina maximaal 100% breed is. Als het apparaat 300 px breed is, is de pagina ook 300 px breed, maar nog altijd 100%.

Simpeler gezegd: je zegt tegen het mobiele apparaat dat de pagina geen vaste breedte heeft, en dat het dus niet nodig is om de weergave aan te passen.

Steeds meer mobiele apparaten krijgen een hogere resolutiedichtheid: er staan meer pixels in een inch dan bij een monitor voor de desktop het geval is. Als een lijn 4 px breed is, en de pixels staan vier keer zo dicht op elkaar als op de desktop, zou de lijn maar 1 px breed zijn op een mobiel apparaat. Het is wel een supermooie en strakke lijn, omdat je met vier dicht bij elkaar staande pixels fantastisch scherp kunt weergeven. Alleen is de lijn helaas nauwelijks te zien, omdat hij in al z'n pracht maar 1 px breed is.

Ook niet echt geweldig. Daarom geven ook deze apparaten de breedte weer, alsof de resolutie een standaarddichtheid heeft. Een retina-scherm (een scherm met een hoge resolutiedichtheid) jokt een beetje. Ook een venster van 2048 of 4096 px breed beweert 1024 px breed te zijn. Hierdoor ziet een lijn van 4 px breed er ook op zo'n scherm als 4 px breed uit, en niet als 1 of 2 px breed.

Die hoge resolutiedichtheid heeft wel zin, maar dan op een andere manier. Letters bijvoorbeeld worden al jaren getekend aan de hand van wiskundige formules, het zijn allang geen statische afbeeldingen meer. Die formules kunnen prima met die hoge resolutiedichtheid uit de voeten: een ronding in een letter is veel fijner dan op de desktop. Ook voor hoge kwaliteit afbeeldingen is een hoge resolutiedichtheid zinvol. Het enige waar het niet zinvol is, is bij het aangeven van een maat. Een lijn van 4 px breed moet 4 px breed zijn, en niet 1 px breed in superkwaliteit.

Er staat nog een tweede deel in de tag: initial-scale=1. Sommige mobiele apparaten zoomen een pagina gelijk in of uit. Ook weer in een poging behulpzaam te zijn. Ook dat is hier niet nodig, want de pagina past zich aan het apparaat aan. Er is ook een instructie om zoomen helemaal onmogelijk te maken, maar die gebruik ik niet. De bezoeker kan zelf nog gewoon zoomen, wat belangrijk is voor mensen die wat slechter zien.

<link rel="stylesheet" href="../../css/naam-van-stylesheet.css">

Deze regel heeft in dit voorbeeldbestand geen enkel nut. Normaal genomen is het een verwijzing naar een extern stylesheet, waarin de style staat. In dit voorbeeld verwijst de href naar een niet bestaand bestand. In html5 is de toevoeging type="text/css" niet meer nodig, omdat dit standaard al zo staat ingesteld.

De bedoeling is dat je bovenstaande regels aanpast voor je eigen bestand. De hele style, die onder deze regels in de <head> staat, wordt dan in het externe bestand geplaatst waar de href naar verwijst. In dat bestand komt de style precies zo te staan zoals die nu in de <head> staat. Het bestand moet eindigen op .css.

Voordeel van een externe stylesheet is onder andere, dat deze geldig is voor alle pagina's waaraan deze is gelinkt. 'n Verandering in de lay-out hoef je dan maar op één enkele centrale plek te aan te brengen.

In die externe stylesheet zet je alles wat in dit voorbeeld tussen <style> en </style> staat (zonder deze begin- en eindregel).

Deze regel is gewoon 'n link die naar 'n bestand elders verwijst, waar de css in staat. Op de plaats van "../../css/naam-van-stylesheet.css" moet je pad naar en naam van jouw stylesheet invullen.

<style>

Voor de duidelijkheid staat de style hier in het bestand zelf, maar het is beter deze in een apart stylesheet te zetten, zoals hierboven beschreven. In dat stylesheet komt alles wat tussen bovenstaande regel en </style> staat.

Technisch gezien is er geen enkel bezwaar om het in die stylesheet te zetten met dezelfde vreselijke lay-out als die ik in dit voorbeeld gebruik. Maar als je dat doet, garandeer ik je hele grote problemen omdat het volstrekt onoverzichtelijk is. Ik gebruik alleen deze lay-out omdat het anders veel te veel regels worden.

Voorbeeld van 'n goede lay-out in je css>:


	div#header-buiten
	{
	    position: absolute;
	    right: 16px;
	    width: 100%;
	    height: 120px;
	    background: yellow;
	}

	div#header-binnen
	{
	    margin-left: 16px;
	    height: 120px;
	    text-align: center;
	}

body

Het element waarbinnen de hele pagina staat. Veel instellingen die hier worden opgegeven, worden geërfd door de kinderen van <body>. Ze gelden voor de hele pagina, tenzij ze later worden gewijzigd. Dit geldt bijvoorbeeld voor de lettersoort, de lettergrootte en de voorgrondkleur.

margin: 0; padding: 0;

Slim om te doen, is soms wat afwijkend in verschillende browsers.

font-family: Arial, Helvetica, sans-serif;

Lettersoort. Als er geen Arial is, wordt gezocht naar Helvetica. Als dat er ook niet is in ieder geval 'n lettersoort zonder schreef (dwarsstreepjes).

font-size: 0.8em

Vrij kleine letter, zodat deze ook nog op kleine schermen past. Bij @media screen and (min-height: 450px) wordt deze letter weer vergroot.

Alleen een kleine letter is bepaald niet voldoende om een pagina goed weer te geven in een klein venster, zoals van een smartphone. Een woord als 'gecentreerde' bijvoorbeeld zal in een klein venster buiten z'n div komen te staan, omdat het gewoon te lang is.

Daar kun je wel wat aan doen, maar omdat het hier gaat om verticaal centreren, pas ik dit verder niet aan.

Als eenheid gebruik ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

div#content

De div met id="content". Binnen deze div staat de hele pagina.

Deze pagina is grotendeels leeg, maar dat maakt natuurlijk niets uit. Een pagina met tekst of afbeeldingen of kolommen gedraagt zich precies hetzelfde.

position: relative;

Binnen div#content komen andere elementen te staan, die gepositioneerd moeten worden ten opzichte van deze div. Die elementen kunnen alleen maar ten opzichte van div#content gepositioneerd worden, als div#contentzelf absoluut, fixed of relatief is gepositioneerd.

Omdat er verder niets wordt opgegeven voor top of zo, heeft dit verder geen enkele invloed op div#content zelf.

width: 750px;

De div is 750 px breed. En omdat alles binnen deze div staat, is daardoor ook de pagina 750 px breed. De breedte maakt niets uit voor het verticaal centreren.

max-width: 100%;

Hierboven is een breedte van 750 px opgegeven. Op kleine schermen kan dat te breed zijn. Daarom wordt hier opgeven dat de breedte nooit meer mag zijn, dan in het venster van de browser past. Hierdoor wordt voorkomen dat op bijvoorbeeld een smartphone horizontaal gescrold moet worden.

Normaal genomen is dit absoluut onvoldoende om problemen in smallere vensters te voorkomen. In heel smalle vensters komen bijvoorbeeld lange woorden buiten hun div te staan, waardoor ze over elkaar heen kunnen komen te staan. Dat voorkom je niet met alleen een maximumbreedte.

Maar omdat het hier om verticaal centreren gaat, doe ik hier verder niets aan. 'In het echt' zou je in smalle vensters bijvoorbeeld ook moeten voorkomen dat divs naast elkaar komen te staan.

height: 400px;

De hoogte. Omdat kinderen van deze div verticaal binnen deze div gecentreerd moeten worden, moet de div een hoogte krijgen. Je kunt nou eenmaal moeilijk iets centreren binnen een div die geen hoogte heeft.

Bij @media screen and (min-height: 450px) wordt deze div zelf ook verticaal gecentreerd, en ook daarvoor is een hoogte nodig.

color: black;

Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. Sommige mensen hebben zelf de voorgrond- en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als ik nu de achtergrondkleur verander, maar niet de voorgrondkleur, loop ik het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.

Door beide op te geven, weet ik redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important heeft gebruikt, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.

background: yellow;

Om de pagina zichtbaar te maken in dit voorbeeld.

div#rood

Het rode blok dat verticaal gecentreerd op de pagina staat.

position: absolute;

Om de div op een bepaalde plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een fixed, relatieve of absolute positie, dat is hier div#content.

top: 50%;

Bovenkant van het blok halverwege div#content zetten.

left: 11%;

Een positie in procenten wordt altijd ten opzichte van de ouder genomen. Dat is hier div#content. Als div#content smaller wordt, zoals in een smal browservenster het geval is, verandert de positie hierdoor gewoon mee en blijft div#rood op 11% van de linkerkant van div#content staan.

margin-top: -50px;

Hierboven is deze div halverwege het venster van de browser neergezet. De div krijgt hieronder een hoogte van 100 px. Als ik de div de helft hiervan, 50 px, terug naar boven zet, staat de div precies verticaal gecentreerd binnen div#content.

width: 26%;

Een breedte in procenten wordt altijd ten opzichte van de ouder genomen. Dat is hier div#content. Als div#content smaller wordt, zoals in een smal browservenster, wordt hierdoor div#rood ook smaller. En blijft dus altijd binnen div#content passen.

height: 100px;

De hoogte.

color: black;

Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. Sommige mensen hebben zelf de voorgrond- en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als ik nu de achtergrondkleur verander, maar niet de voorgrondkleur, loop ik het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.

Door beide op te geven, weet ik redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important heeft gebruikt, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.

background: #f6c;

Kleurtje om de div zichtbaar te kunnen maken.

div#groen

Het grote groene blok dat verticaal gecentreerd staat binnen de pagina.

position: absolute;

Om de div op een bepaalde plaats in het venster van de browser neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een fixed, relatieve of absolute positie, dat is hier div#content.

top: 50%;

Bovenkant van het blok halverwege div#content zetten.

left: 53%;

Een positie in procenten wordt altijd ten opzichte van de ouder genomen. Dat is hier div#content. Als div#content smaller wordt, zoals in een smal browservenster het geval is, verandert de positie hierdoor gewoon mee en blijft div#groen op 53% van de linkerkant van div#content staan.

margin-top: -150px;

Hierboven is deze div halverwege het venster van de browser neergezet. De div krijgt hieronder een hoogte van 300 px. Als ik de div de helft hiervan, 150 px, terug naar boven zet, staat de div precies verticaal gecentreerd binnen div#content.

width: 40%;

Een breedte in procenten wordt altijd ten opzichte van de ouder genomen. Dat is hier div#content. Als div#content smaller wordt, zoals in een smal browservenster, wordt hierdoor div#groen ook smaller. En blijft dus altijd binnen div#content passen.

height: 300px;

De hoogte.

color: black;

Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. Sommige mensen hebben zelf de voorgrond- en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als ik nu de achtergrondkleur verander, maar niet de voorgrondkleur, loop ik het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.

Door beide op te geven, weet ik redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important heeft gebruikt, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.

background: green;

Kleurtje om de div zichtbaar te kunnen maken.

div#blauw

Het kleine blauwe blok dat verticaal en horizontaal gecentreerd staat binnen het groene blok.

position: absolute;

Om de div op een bepaalde plaats te kunnen neerzetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een fixed ,relatieve of absolute positie, dat is hier div#groen.

top: 50%;

Bovenkant van het de div halverwege div#groen zetten.

left: 24%;

De simpelste manier om een blok-element met een bepaalde breedte, zoals deze div, horizontaal te centreren, is het gebruik van margin: 0 auto;: boven en onder geen marge, links en rechts auto wat hier evenveel betekent. Oftewel: horizontaal gecentreerd.

Maar helaas, dat werkt hier niet, omdat de div absoluut is gepositioneerd. Dan moet het maar op 'n andere manier.

Een positie in procenten wordt altijd ten opzichte van de ouder genomen. Dat is hier div#groen. Als div#groen smaller wordt, zoals in een smal browservenster het geval is, verandert de positie hierdoor gewoon mee en blijft div#blauw op 24% van de linkerkant van div#groen staan.

Hieronder geef ik een breedte van 52% op. Die breedte is samen met deze positie 24 + 52 = 76%. Daarmee blijft er rechts 24% lege ruimte. Dat is precies evenveel als links, waardoor deze div ook horizontaal altijd is gecentreerd. En omdat procenten zijn gebruikt, is dit bij elke breedte het geval.

margin-top: -75px;

Hierboven is deze div halverwege div#groen neergezet. De div krijgt hieronder een hoogte van 150 px. Als ik de div de helft hiervan, 75 px, terug naar boven zet, staat de div precies verticaal gecentreerd binnen div#groen.

width: 52%;

Een breedte in procenten wordt altijd ten opzichte van de ouder genomen. Dat is hier div#groen. Als div#groen smaller wordt, zoals in een smal browservenster, wordt hierdoor div#blauw ook smaller. En blijft dus altijd binnen div#groen passen.

height: 150px;

De hoogte.

color: black;

Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. Sommige mensen hebben zelf de voorgrond- en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als ik nu de achtergrondkleur verander, maar niet de voorgrondkleur, loop ik het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.

Door beide op te geven, weet ik redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important heeft gebruikt, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.

background: #0ff;

Kleurtje om de div zichtbaar te kunnen maken.

h1

Titel van de pagina.

font-size: 1.3em;

Kleinere letter dan standaard, anders past het niet goed. Ik gebruik toch een <h1>, omdat zoekmachines meer gewicht geven aan tekst in een <h1>. En dit voorbeeld gaat over centreren, dus in dit geval is een <h1> terecht en geen misleiding van de zoekmachine.

Ook voor screenreaders en dergelijke is een juist gebruik van kopregels belangrijk.

Ik gebruik em als eenheid zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

Bij body is een lettergrootte opgegeven van 0,8 em. Die lettergrootte geldt voor de hele pagina. De grootte van 1,3 em die hier wordt opgegeven, is dan ook ten opzichte van de eerder opgegeven 0,8 em: 1,3 x 0,8 em.Ik gebruik em als eenheid zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

text-align: center;

Tekst horizontaal in het midden zetten.

h2, h3

Andere <h>'s. Ik ga deze ook fors aanpassen, maar ook hier geldt: deze pagina gaat over centreren, en deze <h>'s geven de diverse onderdelen aan. En omdat een zoekmachine meer gewicht geeft aan tekst in een <h>, zijn ook hier <h>'s terecht en geen misleiding van de zoekmachine. Hoewel de opmaak de tekst er (vrijwel) als gewone tekst uit laat zien.

Ook voor screenreaders en dergelijke zijn deze kopregels weer van belang.

font-weight: normal;

<h>'s zijn van zichzelf vet, en dat wil ik hier niet.

margin: 0;

Ook de standaard-marge boven en onder een <h> kan ik hier niet gebruiken.

text-align: center;

Tekst horizontaal in het midden zetten.

h2#links, h3

De <h2> met id='links' en alle <h3>'s.

font-size: 1em;

Normaal genomen geven deze <h>'s een grotere letter, hier wil ik de normale grootte. Ik gebruik em als eenheid zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

Bij body is een lettergrootte opgegeven van 0,8 em. Die lettergrootte geldt voor de hele pagina. De grootte van 1,3 em die hier wordt opgegeven, is dan ook ten opzichte van de eerder opgegeven 0,8 em: 1 x 0,8 em.

h2#rechts

De <h2> met id='rechts'.

font-size: 1.3em;

Aangepaste lettergrootte. De standaard-grootte is te groot. Ik gebruik em als eenheid zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

Bij body is een lettergrootte opgegeven van 0,8 em. Die lettergrootte geldt voor de hele pagina. De grootte van 1,3 em die hier wordt opgegeven, is dan ook ten opzichte van de eerder opgegeven 0,8 em: 1,3 keer 0,8 em.

div#content p

Alle paragrafen binnen de div met id="content".

margin: 0;

Een <p> heeft van zichzelf een marge aan boven- en onderkant. Die kan ik hier niet gebruiken.

text-align: center;

Tekst in het midden zetten.

css voor vensters hoger dan 450 px

@media screen and (min-height: 450px)

De css die hier tot nu toe staat, geldt voor alle browservensters, ook voor vensters lager dan 450 px. De css die hieronder staat, geldt alleen voor browservensters hoger dan 450 px. Voor een deel is dit nieuwe css, voor een deel wordt hierboven staande css aangepast.

@media: geeft aan dat het om css gaat, die alleen van toepassing is, als aan bepaalde voorwaarden wordt voldaan. Al langer bestond de mogelijkheid om met behulp van zo'n regel css voor bijvoorbeeld printers op te geven. css3 heeft dat uitgebreid tot bepaalde fysieke eigenschappen, zoals de breedte en hoogte van het venster van de browser.

screen: deze regel geldt alleen voor schermweergave. Als je wilt printen, is het beter een stylesheet daarvoor te baseren op de algemene css die hierboven staat.

and: er komt nog een voorwaarde, waar aan moet worden voldaan.

(min-height: 450px): het browservenster moet minstens 450 px hoog zijn. Is het venster lager, dan wordt de css die binnen deze media-regel staat genegeerd.

Gelijk na deze regel komt een { te staan, en aan het einde van de css die binnen deze regel valt een bijbehorende afsluitende }. Die zijn in de regel hierboven weggevallen, maar het geheel ziet er zo uit:

@media screen and (min-height: 450px) { body {color: silver;} (...) rest van de css voor deze @media-regel (...) footer {color: gold;} }

Voor de eerste css binnen deze media-regel staat dus een extra {, en aan het eind staat een extra }.

body

Het element waarbinnen de hele pagina staat. Veel instellingen die hier worden opgegeven, worden geërfd door de kinderen van <body>. Ze gelden voor de hele pagina, tenzij ze later worden gewijzigd. Dit geldt bijvoorbeeld voor de lettersoort, de lettergrootte en de voorgrondkleur.

font-size: 1.1em;

Bij body is een lettergrootte van 0.8 em opgegeven. Dat is nogal klein, omdat de tekst in een klein venster moet passen. Hier verander ik de lettergrootte terug naar een wat normalere maat.

Ik neem 1,1 em, dat is iets groter dan de standaardgrootte van 1 em. Het zal de leeftijd zijn, maar ik vind die wat aan de kleine kant. Als eenheid gebruik ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

Een bij <body> in em opgegeven lettergrootte geldt voor de hele pagina geldt. Hierdoor wordt ook de bij de kopregels opgegeven lettergrootte in em nu berekend op basis van deze nieuwe bij <body> opgegeven lettergrootte.

Zoals ik het hier heb gedaan, is hartstikke verkeerd. Ik kijk bij @media screen and (min-height: 450px) alleen naar de hoogte van het venster, niet naar de breedte. Terwijl die breedte veel belangrijker is. Een venster van 450 px hoog kan nog steeds een breedte van maar 320 px of zo hebben. En dan passen langere woorden nog steeds niet binnen hun div.

Normaal genomen zou je voor deze grotere letter op de breedte van het venster moeten controleren. Maar omdat het hier om een voorbeeld over verticaal centreren gaat, houd ik het wat simpel en gok erop dat vensters van minimaal 450 px hoog ook wel iets breder zullen zijn. Wat je dus 'in het echt' beter niet kunt doen.

div#content

De div met id="content". Binnen deze div staat de hele pagina.

Deze pagina is grotendeels leeg, maar dat maakt natuurlijk niets uit. Een pagina met tekst of afbeeldingen of kolommen gedraagt zich precies hetzelfde.

Deze div, en daarmee de hele pagina, wordt hier verticaal gecentreerd. Waarom je dat niet in te lage vensters moet doen, staat hieronder bij margin-top: -200px;.

position: absolute;

Om div#content, dus de pagina, op 'n bepaalde plaats neer te kunnen zetten.

Er wordt gepositioneerd ten opzichte van de eerste ouder met 'n positie. Omdat die er hier niet is, wordt gepositioneerd ten opzichte van het venster van de browser. Precies wat we willen.

top: 50%;

De bovenkant van de div en dus de hele pagina halverwege de hoogte van het venster van de browser zetten. Omdat dit in procenten is uitgedrukt, maakt de hoogte van het venster van de browser, en dus het scherm, niet uit. De pagina zal altijd in het midden worden gezet.

margin-top: -200px;

Bij div#content heeft deze div een hoogte van 400 px gekregen. Hier gelijk boven is de div halverwege het venster van de browser neergezet. Als ik nu weer de helft van de hoogte omhoog ga, zal de helft van de hoogte boven het midden komen te staan. En dus de andere helft onder het midden. Oftewel: de pagina is verticaal gecentreerd.

Deze methode kan dus alleen maar werken bij een pagina (of blok) met een vaste, bekende hoogte, want anders weet je niet hoeveel je terug om hoog moet.

In te lage vensters mag de pagina niet verticaal worden gecentreerd, omdat er dan inhoud kan verdwijnen. Daarom wordt deze div standaard niet gecentreerd, maar pas als het venster van de browser minstens 450 px hoog is.

De div wordt verticaal halverwege het venster gezet en daarna weer 200 px naar boven verplaatst, de helft van de hoogte van de div.

Stel dat het venster maar 300 px hoog is, 100 px minder dan de hoogte van de div. De div wordt halverwege het venster gezet, dat is op een hoogte van 150 px. Aan boven- en onderkant is maar 150 px ruimte, maar de bovenste en onderste helft van de div zijn elk 200 px.

Aan de onderkant is dat geen probleem: er verschijnt gewoon een verticale scrollbalk, zodat aan de onderkant alles te zien is. Maar aan de bovenkant verschijnt geen scrollbalk. De 50 px die daar niet passen, zijn gewoon helemaal weg en alleen te zien, als je de de css helemaal uitzet.

Om dat te voorkomen wordt deze div en daarmee de hele pagina alleen maar verticaal gecentreerd, als het venster minstens 450 px hoog is. Dan is er boven en onder het midden 225 px. Eigenlijk is maar 200 px nodig, de helft van de hoogte van de div, maar browsers geven soms wat afwijkende maten. Dus ik neem wat speling om aan de veilige kant te blijven.

In lagere vensters wordt de div niet absoluut gepositioneerd, waardoor hij gewoon bovenaan het venster wordt neergezet. Mocht de div te hoog zijn, dan verschijnt gewoon een verticale scrollbalk.

Voor de andere divs die verticaal worden gecentreerd, speelt dit probleem niet, want die worden gecentreerd ten opzichte van deze div. Zolang deze div volledig zichtbaar is, zijn de andere divs dat ook.

Media queries en Internet Explorer 8

In css3 zijn de @media-regels fors uitgebreid. Met behulp van @media kunnen nu dingen als de breedte en hoogte van het browservenster worden opgevraagd. Afhankelijk van het resultaat kan dan bepaalde css juist wel of juist niet worden gebruikt.

Helaas kan Internet Explorer 8 hier niet mee overweg, en omdat Microsoft bestaande browsers nooit update (op veiligheidsupdates na), zal dit ook niet veranderen. Wat Microsoft kennelijk niet kan, heeft een aantal programmeurs zelf dan maar geprobeerd voor elkaar te krijgen. Met behulp van JavaScript kunnen ook deze browsers gebruik maken van media queries.

Helemaal probleemloos werkt dit bepaald niet. Omdat de code van deze browsers geheim is en er bergen afwijkingen en bugs in zitten, werkt dit JavaScript ook niet altijd, of soms zelfs helemaal niet.

Er zijn twee veel gebruikte JavaScripts om media queries te kunnen gebruiken: css3-mediaqueries-js en respond.js. Op deze pagina gebruik ik css3-mediaqueries.js.

In de <head> staat het volgende stukje code:

<!--[if IE 8]> <script src="006-files-dl/css3-mediaqueries.js"></script> <![endif]-->

Dit eigenaardige stukje code heet een 'conditional comment' en wordt door alle browsers gezien als commentaar, omdat het tussen <!-- en --> staat. Maar Internet Explorer herkent het, door de extra toevoegingen, als speciaal voor Internet Explorer bedoeld en zal het dus uitvoeren. Het is veiliger dan een zogenaamde 'hack', waarbij vaak gebruik wordt gemaakt van 'n fout (bug) in de browser. Dit is opzettelijk aangebracht door Microsoft en zal dus blijven bestaan, terwijl 'n bug gerepareerd kan worden.

Het is belangrijk dat de spaties in <!--[if IE 8]> en <![endif]--> precies zo worden overgenomen zoals ze hier staan. IE 8 geeft aan dat dit alleen voor Internet Explorer versie 8 is bedoeld.

De toevoeging type="text/javascript" bij <script> is in html5 niet meer nodig, omdat dit de standaardinstelling is.

css3-mediaqueries.js is het in de download bijgesloten JavaScript, dat ervoor zorgt dat Internet Explorer 8 met media queries uit de voeten kan.

Omdat dit soort scripts regelmatig wordt bijgewerkt, is het uitermate belangrijk dat je zelf dit script ophaalt van css3-mediaqueries-js en niet gewoon het script uit de download gebruikt.

Het gebruik van dit soort scripts kan tot de wildste problemen lijden, zie voor een voorbeeld bij Bekende problemen.

De code aanpassen aan je eigen ontwerp

Toegankelijkheid en zoekmachines

Het eerste deel van deze tekst is voor alle voorbeelden hetzelfde. Eventueel specifiek voor dit voorbeeld geldende dingen staan verderop onder het kopje Specifiek voor dit voorbeeld.

Toegankelijkheid (accessibility in het Engels) is belangrijk voor bijvoorbeeld blinden die een spraakbrowser gebruiken, of voor motorisch gehandicapte mensen die moeite hebben met het bedienen van een muis. Een spider van een zoekmachine (dat is het programmaatje wat de site indexeert voor de zoekmachine) is te vergelijken met een blinde. Als je je site goed toegankelijk maakt voor gehandicapten, is dat dus gelijk goed voor een hogere plaats in een zoekmachine. Dus als je 't niet uit sociale motieven wilt doen, kun je 't uit egoïstische motieven doen.

(Op die plaats in de zoekmachine heb je maar beperkt invloed. De toegankelijkheid van je site is maar één van de factoren, maar zeker niet onbelangrijk.)

Als je bij het maken van je site al rekening houdt met toegankelijkheid, is dat nauwelijks extra werk. 't Is ongeveer te vergelijken met inbraakbescherming: doe dat bij 'n nieuw huis en 't is nauwelijks extra werk, doe 't bij 'n bestaand huis en 't is al snel 'n enorme klus.

Enkele tips die helpen bij toegankelijkheid:

Specifiek voor dit voorbeeld

Deze constructie heeft geen enkele invloed op de toegankelijkheid.

Getest in

Laatst gecontroleerd op 7 december 2012.

Onder dit kopje staat alleen maar, hoe en waarin is getest. Eventuele problemen, ook die met betrekking tot zoomen en lettergroottes, staan hieronder bij Bekende problemen. Het is belangrijk dat te lezen, want uit een test kan ook prima blijken dat iets totaal niet werkt!

Eventuele opmerkingen over de toegankelijkheid specifiek voor dit voorbeeld staan onderaan Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.

Dit voorbeeld is getest op de volgende systemen:

Er is steeds getest met de laatste versie van de browsers op de hierboven genoemde controledatum, omdat ik geen zin heb om rekening te houden met mensen die met zwaar verouderde browsers surfen. Dat is trouwens vragen om ellende, want updates van browsers hebben heel vaak met beveiligingsproblemen te maken.

In resoluties groter dan 800x600 is ook in- en uitzoomen en - voor zover de browser dat kan - een kleinere en grotere letter getest. Er is ingezoomd en vergroot tot zover de browser kan, maar niet verder dan tot 200%.

Er is getest met behulp van muis en toetsenbord, behalve op de iPad en Android, waar een touchscreen is gebruikt.

Naast deze 'gewone' browsers is ook getest in Lynx, WebbIE, NVDA en Fangs Screen Reader Emulator. Lynx is een browser die alleen tekst laat zien en geen css gebruikt. WebbIE is een browser die gericht is op mensen met een handicap. NVDA is een screenreader, zoals die door blinden wordt gebruikt. Fangs Screen Reader Emulator is een extensie bij Firefox, die de pagina laat zien, zoals een screenreader hem ziet.

Als het voorbeeld in deze vier programma's toegankelijk is, zou het in principe toegankelijk moeten zijn in alle aangepaste browsers en dergelijke. En dus ook voor zoekmachines, want een zoekmachine is redelijk vergelijkbaar met een blinde. Eventuele opmerkingen over de toegankelijkheid specifiek voor dit voorbeeld staan onderaan Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.

Alleen op de hierboven genoemde systemen en browsers is getest. Er is dus niet getest op bijvoorbeeld 'n Blackberry. De kans is (heel erg) groot dat dit voorbeeld niet (volledig) werkt op niet-geteste systemen en apparaten. Om het wel (volledig) werkend te krijgen, zul je vaak (kleine) wijzigingen en/of (kleine) aanvullingen moeten aanbrengen, bijvoorbeeld met JavaScript.

Er is ook geen enkele garantie dat iets werkt in een andere tablet of smartphone dan hierboven genoemd, omdat fabrikanten in principe de software kunnen veranderen. Dit is anders dan op de desktop, waar browsers altijd (vrijwel) hetzelfde werken, zelfs op verschillende besturingssystemen. Iets wat in Android browser werkt, zal in de regel overal werken in die browser, maar een garantie is er niet. De enige garantie is het daadwerkelijk testen op een fysiek apparaat. En aangezien er duizenden mobiele apparaten zijn, is daar eigenlijk geen beginnen aan.

De html is gevalideerd met de validator van w3c, de css ook. Als om een of andere reden niet volledig gevalideerd kon worden, wordt dat bij Bekende problemen vermeld.

Nieuwe browsers test ik pas, als ze uit het bèta-stadium zijn, omdat er anders 'n redelijke kans is dat ik 'n bug zit te omzeilen, die voor de uiteindelijke versie nog gerepareerd wordt. Dit voorbeeld is alleen getest in de hierboven met name genoemde browsers. Vragen over niet-geteste browsers kan ik niet beantwoorden, en het melden van fouten in niet-geteste browsers heeft ook geen enkel nut. (Melden van fouten, problemen, enz. in wel geteste browsers: graag!)

Bekende problemen

Waarop en hoe is getest, kun je gelijk hierboven vinden bij Getest in.

Als je hieronder geen oplossing vindt voor een probleem dat met dit voorbeeld te maken heeft, kun je op het forum proberen een oplossing te vinden voor je probleem. Om forumspam te voorkomen, moet je je helaas wel registreren, voordat je op het forum een probleem kunt aankaarten.

Internet Explorer 8

In dit voorbeeld wordt voor Internet Explorer 8 het JavaScript css3-mediaqueries gebruikt, omdat deze browser anders de css binnen de @media-regel niet kan lezen. Dit soort scripts is fantastisch, maar werkt niet altijd feilloos. Dat komt niet doordat het script zo slecht in elkaar zit, maar doordat de broncode van Internet Explorer geheim is, zodat je nooit zeker kunt weten dat iets in elke situatie goed werkt.

Daarnaast stelt Microsoft er een eer in de grootste bugfabriek ter wereld te hebben, waardoor er een compleet rijksmuseum aan bugs, onderbroekenlol en morele verloedering in Internet Explorer terecht is gekomen.

Op de site zijn de voorbeelden voorzien van navigatieknoppen. Door het gebruik van css3-mediaqueries.js valt de inhoud van de linkerknop weg. Pas als ik erop klik, of als ik het venster van de browser van grootte verander, worden de links binnen de knop zichtbaar.

Die knop heeft een breedte van 11 em. Als ik die breedte weghaal, is alles gewoon zichtbaar. En ook als ik de links in de knop bijvoorbeeld absoluut of fixed positioneer. Maar dat levert weer andere problemen op.

De inhoud wordt echter ook zichtbaar als ik in plaats van simpel width: 11em; de volgende complete onzin in de css zet:

min-width: 10.999999em; max-width: 11em;

Deze krankzinnige css heeft natuurlijk geen enkel nut en werkt precies hetzelfde als gewoon simpel width: 11em;. Met één verschil: nu geeft dit door de Vereniging Van Kalmerende Middelenproducenten gesubsidieerde wanproduct, pardon, ik bedoel de fantastische Internet Explorer 8, de inhoud wel goed weer.

Moraal van het verhaal: als je dit soort scripts in Internet Explorer 8 gebruikt, moet je heel goed testen.

Grotere lettergrootte

Als de tekst, in de browsers waarin dat kan, tot meer dan zo'n 150% wordt vergroot, komt de tekst gedeeltelijk buiten de bijbehorende div te staan. De bovenste kop kan (gedeeltelijk) onder de divs komen te staan.

Wijzigingen

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

:

Nieuw opgenomen.

10 augustus 2008:

Bij Bekende problemen stukje over zoomen in Internet Explorer 7 toegevoegd.

6 april 2009:

Tekst aangepast aan de nieuw verschenen Internet Explorer 8. De code is hetzelfde gebleven.

30 juni 2011:

Op diverse plaatsen color: black; toegevoegd vanwege toegankelijkheid. Het waarom staat op de betreffende plaatsen in de Beschrijving van code en css.

7 december 2012: