Skip links en inhoudsopgave

Pop-up met externe link en tekst op achtergrond-afbeelding - uitleg

Laatst aangepast: .

Afbeelding 1: de pop-up met de achtergrond-afbeelding en tekst

Korte omschrijving

Bij aanraken of -klikken van, hoveren over of tabben naar het vraagteken opent een pop-up met link en tekst over een achtergrond-afbeelding.

BELANGRIJK

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 ontbreekt 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.

Alles op deze site kan vrij worden gebruikt, met drie 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.

* Het kan zijn dat materiaal is gebruikt dat van anderen afkomstig is. Dat materiaal kan onder een bepaalde licentie vallen, waardoor het mogelijk niet onbeperkt gebruikt mag worden. Als dat zo is, wordt dat vermeld onder Inhoud van de download en licenties.

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

Alle code is geschreven in een afwijkende lettersoort en -kleur. De code die te maken heeft met de basis van dit voorbeeld (essentiële code), is in de hele uitleg blauw gekleurd. Alle niet-essentiële code is bruin. (In de inhoudsopgave staat alles vanwege de leesbaarheid in een gewone letter.)

Opmerkingen

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

Dit voorbeeld 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.

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:
Naar site van War Child Nederland

Achterliggend idee

Sinds de eerste versie van dit voorbeeld is er nogal wat veranderd. Schermlezers en dergelijke zijn sterk verbeterd, waardoor het makkelijker wordt dingen toegankelijk te maken. Touchscreens zijn alledaagse voorwerpen geworden, terwijl dit bij de vorige versie nog redelijk exotische apparaten waren.

Toen er nog geen touchscreens waren, was een pop-up simpel te maken (even los van de 666 aanpassingen die voor de door een reïncarnatie van Beëlzebub zelve ontworpen Internet Explorer 6 nodig waren). Als je ergens met de muis over hoverde, opende een pop-up. Vervolgens een klik en hoppa, de link werd gevolgd. Ook voor gebruikers van de Tab-toets was een pop-up relatief simpel toegankelijk te maken.

Op alle systemen is hoveren op een of andere manier te simuleren. Dat moest ook wel, want vele miljoenen bestaande sites gebruikten deze techniek. Helaas is de manier waarop dit gebeurt verschillend bij Android, Windows en Apple. (Dat geldt trouwens ook als je JavaScript gebruikt om hoveren te simuleren.)

Voor touchscreens moesten dus aanpassingen worden aangebracht, waardoor de pop-up ook door aanraking sluit of opent. En met – als dat enigszins kon – gebruikmaking van alleen css. En als het dan toch wordt herschreven, is dat een mooie gelegenheid ook de toegankelijkheid te verbeteren.

Eerst een bekentenis: de pop-up is helemaal geen pop-up. Het gaat om iets wat altijd op het scherm staat, maar verstopt. Door bepaalde handelingen wordt dat 'iets' vergroot en zichtbaar. Maar omdat dit er net zo uitziet als een 'echte' JavaScript-pop-up, wordt ook dit soort constructies meestal gewoon 'pop-up' of 'css-pop-up' genoemd.

Deze pop-up valt eigenlijk in twee delen uiteen. Bij hoveren over of aanraken of -klikken van het vraagteken moet de pop-up openen. Als daarna de pop-up wordt aangeraakt of -geklikt, moet de link worden gevolgd. Sluiten gebeurt door het scherm buiten de pop-up aan te raken of -klikken of, bij hoveren, door de cursor weer buiten het vraagteken te plaatsen.

Voor gebruikers van de Tab-toets werkt het op een soortgelijke manier. De Tab-toets opent en sluit de pop-up, als de pop-up is geopend laat een Enter de link volgen.

De hele constructie bestaat in feite maar uit vier onderdelen. Een <input type="checkbox">, twee bij die <input> behorende <label>'s en de <a> met de eigenlijke pop-up.

De <input> is eigenlijk niet nodig, maar de <label>'s hebben die nodig, omdat ze anders niet overal goed werken. De specificatie is wat vaag over hoe <label>'s zonder <input> of iets soortgelijks horen te werken met dingen als 'op de voor het systeem gebruikelijke manier'. Daarom is het zekere voor het onzekere genomen en gewoon een <input> gebruikt, die dus feitelijk alleen maar de dienstdoende Jan Joker loopt te spelen.

De drie belangrijke elementen zijn de eerste <label>, de daaropvolgende <a>, en de daarop weer volgende tweede <label>.

In de eerste <label> staat het vraagteken in een wit vierkant.

De <a> met de pop-up is normaal genomen heel klein en wordt verborgen onder de <label> met het vraagteken, waardoor deze onzichtbaar is. Verbergen met display: none; kan niet, want dan zien schermlezers de link niet.

Normaal genomen verberg je iets door het links buiten het scherm te positioneren. Schermlezers kunnen het dan gewoon lezen. Hier kan dat niet, want in TalkBack op Android blijkt de link alleen te werken, als deze op het scherm staat. Het simpelste zou dan zijn om de link 0 x 0 px te maken met overflow: hidden; en nog wat van dat soort dingen. De link blijkt echter ook minstens 1 x 1 px groot te moeten zijn.

Daarom is de link normaal genomen 1 x 1 px en wordt verborgen onder het vraagteken. Pas als de pop-up moet worden getoond, wordt de link vergroot en worden achtergrond-afbeelding en tekst zichtbaar.

Eerst het hoveren, dat is simpel. Bij hoveren over de <label> met het vraagteken wordt de <a> met de pop-up vergroot en daardoor zichtbaar. Als op de <a> met de pop-up wordt geklikt, wordt de link gevolgd. Als dat niet gebeurt en de cursor buiten het vraagteken wordt geplaatst, verdwijnt de pop-up weer onder het vraagteken. Hiermee is de hele pop-up wat betreft de muis afgehandeld.

Ook voor gebruikers van de Tab-toets is het niet al te ingewikkeld. Normaal genomen wordt bij indrukken van de Tab-toets ook de <input> bezocht, maar dat is hier overbodig en wordt voorkomen door de <input> het attribuut tabindex"-1" te geven. De <a> met de pop-up wordt wel gewoon bezocht. Als de <a> focus krijgt, wordt deze vergroot en daardoor wordt de erin zittende pop-up zichtbaar. Door het indrukken van Enter wordt de link gevolgd, net zoals dat normaal het geval is. Als dat niet gebeurt, verliest de <a> weer de focus door het nogmaals indrukken van de Tab-toets, waardoor de <a> weer klein wordt en onder het vraagteken verdwijnt.

Het lastige deel wordt gevormd door de touchscreens.

Een <label> die op een touchscreen wordt aangeraakt, reageert net alsof erop wordt geklikt: het bijhorende aankruisvakje (de <input>) wordt uit- of aangevinkt. Omdat die <input> hier verder niet wordt gebruikt, is dat niet van belang.

De <label> met het vraagteken reageert ook op een touchscreen op hoveren. Dat werkt op een touchscreen ongeveer hetzelfde als een klik, alleen net even anders en – uiteraard – op elk systeem op een net iets andere manier.

Op alle systemen volgt een aantal browsers altijd gelijk de link, zonder de pop-up te tonen, als het vraagteken wordt aangeraakt. Door de <a> pas na een kleine vertraging te tonen, wordt dit in vrijwel alle browsers voorkomen.

Op Windows gaat het meestal goed. Je raakt het vraagteken aan en de <a> wordt vergroot en daardoor zichtbaar. Als je de pop-up nogmaals aanraakt, wordt de link gevolgd. Als je het scherm buiten de <a> met de pop-up aanraakt, wordt de <a> weer klein en verdwijnt weer onder het vraagteken.

'Meestal' stond er dus. In Internet Explorer 11 en Edge op touchscreens opent de pop-up bij aanraking niet. Of hij opent pas na een hele tijd. Of het contextuele menu wordt geopend. 'n Soort loterij. Er zal vast enige logica in zijn te ontdekken, maar die heb ik niet kunnen ontdekken. Als je echter aan de <label> met het vraagteken de WAI-ARIA-code aria-haspopup="true" toevoegt, werkt het goed.

Op Android opent de pop-up bij aanraking van het vraagteken. Als je de pop-up aanraakt, wordt de link gevolgd. Als het scherm buiten de pop-up wordt aangeraakt, wordt de <a> weer klein en verdwijnt onder het vraagteken. (Nog niet gaan juichen over Android, want de schermlezer TalkBack had hier behoorlijke kuren, waarover later meer.)

Op iOS wordt de <a> met de pop-up bij aanraking van het vraagteken vergroot en daardoor zichtbaar. Bij nogmaals aanraken van de pop-up wordt de link gevolgd. Hoveren wordt op iOS omgezet in 'n soort focus: zolang het vraagteken focus heeft, blijft de <a> en daarmee de pop-up zichtbaar. Pas door het aanraken van een knop, tekstveld, link, of ander element dat focus kan krijgen, verliest de <label> met het vraagteken de focus en wordt de <a> weer klein genoeg om onder het vraagteken te verdwijnen. Gewoon het scherm aanraken ergens buiten de pop-up werkt niet, je moet echt 'n element aanraken dat focus kan krijgen.

Daarvoor wordt de tweede <label> gebruikt. Op het moment dat de eerste <label> met het vraagteken wordt aangeraakt, wordt de tweede <label> even groot gemaakt als het venster van de browser, zodat het hele scherm wordt afgedekt (behalve de <a> met de pop-up). Als je deze tweede <label> aanraakt, verliest de eerste <label> met het vraagteken de focus, en verdwijnt de <a> met de pop-up weer onder het vraagteken.

De reden om <label>'s te gebruiken en geen gewone <span>'s of <p>'s of zo, heeft ook met iOS te maken. Als je op iOS een <span> of zoiets gebruikt, moet je de <span> twee keer aanraken, voordat de pop-up opent. Dat kan alleen worden voorkomen door JavaScript te gebruiken. Bij gebruik van een <label> hoeft dit niet.

(In Firefox op iOS verdwijnt de <a> trouwens wel weer onder het vraagteken, als het scherm buiten de pop-up wordt aangeraakt, ook zonder deze extra <label>.)

De schermlezer TalkBack op Android heeft ook nog wat kuren. Oorspronkelijk stond de <a. met de pop-up links buiten het scherm, als deze onzichtbaar moest zijn. Het blijkt echter onmogelijk om in TalkBack een link te volgen, als die buiten het scherm staat. Vandaar de constructie met de <a> die onder het vraagteken wordt verborgen.

De <a> werd dus onder het vraagteken gezet en onzichtbaar gemaakt door deze een breedte en hoogte van 0 px te geven. Dat kon echter ook niet, want om in TalkBack te werken blijkt de link minstens 1 x 1 px groot te moeten zijn.

De tekst in de link is voor schermlezers iets minder handig: 'Klik of raak plaatje aan om naar site van wpclipart.com te gaan'. Deze tekst was dan ook eerst verborgen voor schermlezers en vervangen door het attribuut aria-labelledby="Naar site van wpclipart.com". Ook dit had echter als resultaat dat de link in TalkBack niet gevolgd kon worden. Hij wordt netjes voorgelezen, maar kan niet worden gevolgd.

Waarom TalkBack zo weerzinwekkend kieskeurig is, is onbekend. Normaal genomen zou een link in een schermlezer gewoon moeten werken, ook al staat die buiten het scherm. In de andere geteste schermlezers is dat ook het geval, alleen TalkBack gedraagt zich zo tegendraads.

Om alles helemaal goed werkend te krijgen, was er ook nog enig gegoochel met z-index, WAI-ARIA-codes, en dergelijke nodig. Dat wordt op de betreffende plaatsen verder besproken.

De voorvoegsels -moz-, -ms- en -webkit-

Voordat een nieuwe css-eigenschap wordt ingevoerd, is er in de regel een experimentele fase. Browsers passen het dan al toe, maar met een aangepaste naam. Tijdens deze fase kunnen problemen worden opgelost en worden veldslagen uitgevochten, over hoe de standaard precies moet worden toegepast.

Als iedereen het overal over eens is en alle problemen zijn opgelost, wordt de officiële naam uit de standaard gebruikt.

De belangrijkste browsers hebben elk een eigen voorvoegsel:

Firefox: -moz-, naar de maker: Mozilla.

Op webkit gebaseerde browsers, zoals Google Chrome, Opera, Safari en Android browser: -webkit-.

(Google Chrome is van webkit overgestapt op een eigen weergave-machine: Blink. Blink gaat geen voorvoegsels gebruiken. Het is echter een aftakking van webkit, dus het zal nog wel even duren voor -webkit- hier helemaal uit is verdwenen. Ook Opera gebruikt Blink.)

Internet Explorer: -ms-, naar de maker: Microsoft. (Edge gebruikt geen voorvoegsels, maar vanwege compatibiliteit met oudere sites kunnen er nog wat aanwezig zijn.)

Zodra de experimentele fase voorbij is, wordt het voorvoegsel weggelaten. Omdat dat moment niet bij alle browsers hetzelfde is, zet je nu ook al de officiële naam erbij. Deze wordt als laatste opgegeven. Bijvoorbeeld Android browser herkent -webkit-linear-gradient. Zodra Android browser linear-gradient gaat herkennen, zal dit -webkit-linear-gradient overrulen, omdat het er later in staat. Dat ze er beide in staan, is dus geen enkel probleem.

In dit voorbeeld worden -ms-user-select en transition-delay gebruikt.

ms-user-select

Vanwege het voorvoegsel -ms- werkt dit alleen in Internet Explorer en Edge. Normaal genomen zou je de vormen met de voorvoegsels voor andere browsers gebruiken, en als laatste user-select zonder voorvoegsel. Hier is dit echter niet nodig, omdat user-select wordt gebruikt voor een probleem dat alleen in Internet Explorer en Edge speelt. Maar normaal genomen is het een absoluut slecht idee om een eigenschap te gebruiken, die niet in alle browsers werkt.

Meer over dit probleem is te vinden bij -ms-user-select: none;.

transition-delay

Op dit moment moet je nog het volgende schrijven:

{-webkit-transition-delay: ...; transition-delay: ...;}

In de toekomst kun je volstaan met:

{transition-delay: ...;}

Inmiddels is de algemene mening dat 'vendor prefixes', zoals deze voorvoegsels in het Engels heten, geen groot succes zijn. Eén van de grootste problemen: veel sitemakers gebruiken alleen de -webkit-variant. Daar kwamen ze in het verleden nog mee weg, omdat Apple op mobiel zo'n beetje 'n monopolie had. Inmiddels is dat niet meer zo, maar deze gewoonte bestaat nog steeds. Waardoor 'n site alleen in op webkit georiënteerde browsers goed is te bekijken.

Dit is zo'n groot probleem dat andere browsers soms de variant met -webkit- ook maar zijn gaan implementeren, naast de standaard. Want als 'n site het niet goed doet in 'n bepaalde browser, krijgt in de regel niet de site maar de browser de schuld.

Vanwege alle problemen met 'vendor prefixes' worden deze door steeds meer browsers niet meer gebruikt. Nieuwe, experimentele css-eigenschappen zitten inmiddels in bijvoorbeeld Firefox, Google Chrome en Safari achter een zogenaamde vlag: de gebruiker moet iets veranderen in de instellingen, waarna de eigenschap gebruikt (en getest) kan worden. Als alles werkt, zoals het hoort te werken, schakelt de browsermaker de vlag standaard in.

Voorlopig zijn we echter nog niet van deze voorvoegsels af. Als je ze gebruikt, gebruik dan álle varianten, en eindig met de variant zonder voorvoegsel, zoals die uiteindelijk ooit gebruikt gaat worden. Als je alleen de -webkit-variant gebruikt, ben je in feite 'n onbetaalde reclamemaker voor Apple. (Dit geldt dus niet voor het hierboven genoemde -ms-user-select, want dit wordt alleen gebruikt om een probleem in Internet Explorer en Edge op te lossen.)

Semantische elementen en WAI-ARIA

Deze twee onderwerpen zijn samengevoegd, omdat ze veel met elkaar te maken hebben.

Semantische elementen

De meeste elementen die in html worden gebruikt, hebben een semantische betekenis. Dat wil zeggen dat je aan de gebruikte tag al (enigszins) kunt zien, wat voor soort inhoud er in het element staat. In een <h1> staat een belangrijke kop. In een <h2> staat een iets minder belangrijke kop. In een <p> staat een alinea. In een <table> staat een tabel (en geen lay-out, als het goed is!). Enzovoort.

Door het op de goede manier gebruiken van semantische elementen, kunnen zoekmachines, schermlezers, enzovoort de structuur van een pagina begrijpen. De spider van een zoekmachine is redelijk te vergelijken met een blinde. Het is dus ook in je eigen belang om semantische elementen zo goed mogelijk te gebruiken. Een site die toegankelijk is voor mensen met een handicap, is in de regel ook goed te verwerken door een zoekmachine en maakt dus een grotere kans gevonden en bezocht te worden.

Als het goed is, wordt het uiterlijk van de pagina bepaald met behulp van css. Het uiterlijk staat hierdoor (vrijwel) los van de semantische inhoud van de pagina. Met behulp van css kun je een <h1> heel klein weergeven en een <h6> heel groot, terwijl schermlezers, zoekmachines, en dergelijke nog steeds weten dat de <h1> een belangrijke kop is.

Slechts enkele elementen, zoals <div> en <span>, hebben geen semantische betekenis. Daardoor zijn deze elementen uitstekend geschikt om met behulp van css het uiterlijk van de pagina aan te passen: de semantische betekenis verandert niet, maar het uiterlijk wel. Voor een schermlezer of zoekmachine verandert er (vrijwel) niets, voor de gemiddelde bezoeker krijgt het door de css een heel ander uiterlijk.

(De derde laag, naast html voor de inhoud en css voor het uiterlijk, is JavaScript. Die zorgt voor de interactie tussen site en bezoeker. De min of meer strikte scheiding tussen css en html aan de ene kant en JavaScript aan de andere kant is met de komst van css3 en html5 veel vager geworden. Je kunt nu bijvoorbeeld ook met css dingen langzaam verplaatsen en met html deels de invoer in formulieren controleren.)

Html5 heeft een aantal nieuwe elementen, die speciaal zijn bedoeld om de opbouw van een pagina aan te geven. In dit voorbeeld wordt hiervan alleen <main> gebruikt. <main> gedraagt zich als een gewone <div>, maar dan een <div> met een semantische betekenis. Hierdoor kunnen schermlezers, zoekmachines, en dergelijke beter zien, hoe de pagina is samengesteld.

<main>

Hierbinnen staat de belangrijkste inhoud van de pagina (in dit voorbeeld is dat voornamelijk de pop-up met toebehoren).

Met behulp van dit soort nieuwe semantische elementen kan bijvoorbeeld een schermlezer in één keer een heel menu passeren en gelijk naar de echte inhoud gaan. Alleen hadden deze nieuwe elementen tot voor kort één probleem: ze hadden in de praktijk nog weinig nut, omdat schermlezers en dergelijke ze nog niet herkenden. Daarom werd een zogenaamde WAI-ARIA-code toegevoegd aan deze elementen. Dat is een al veel langer bestaande code, die schermlezers en dergelijke wel herkennen. Voor <main> ziet dat er zo uit:

<main role="main">

Inmiddels is dit behoorlijk veranderd. Het advies is nu om deze speciale toevoeging niet meer te gebruiken, omdat de meeste schermlezers en dergelijke dit soort nieuwe elementen inmiddels herkennen.

WAI-ARIA-codes

WAI-ARIA wordt vaak ingekort tot ARIA. Voluit betekent het Web Accessibility Initiative – Accessible Rich Internet Applications.

Er worden in dit voorbeeld twee WAI-ARIA-codes gebruikt: aria-hidden en aria-haspopup.

aria-hidden

De <input> en de twee bijbehorende <label>'s hebben geen enkel nut voor schermlezers, maar zijn alleen verwarrend. Daarom worden deze met behulp van het attribuut aria-hidden="true" voor schermlezers verborgen:

<input id="open" type="checkbox" tabindex="-1" aria-hidden="true">

<label id="vraagteken" for="open" aria-haspopup="true" aria-hidden="true">?</label>

<label id="sluit" for="open" aria-hidden="true"></label>

aria-haspopup

In de <label> met het vraagteken staat nog een andere WAI-ARIA-code, aria-haspopup:

<label id="vraagteken" for="open" aria-haspopup="true" aria-hidden="true">?</label>

In Internet Explorer 11 en Edge op touchscreens opent de pop-up bij aanraking niet. Of hij opent pas na een hele tijd. Of het contextuele menu wordt geopend. 'n Soort loterij. Kortom: enorme kommer en kwel. Door het toevoegen van aria-haspopup="true" opent de pop-up gewoon.

Volgens de WAI-ARIA-specificatie 1.0 kan met aria-haspopup="true" worden aangegeven dat het element een contextueel menu of een submenu heeft. Microsoft gebruikt dit attribuut dus voor iets, waar het niet voor is bedoeld.

In de ontwerp-specificatie versie 1.1 is de waarde 'true' bij aria-haspopup vervallen, maar wordt vanwege terugwaartse compatibiliteit met versie 1.0 nog wel gedefinieerd op eenzelfde wijze als in versie 1.0. Hiermee lijken mogelijke toekomstige problemen voor dit oneigenlijke gebruik te worden voorkomen.

Tabindex en Tab-toets

Links, invoervelden in formulieren, en dergelijke kunnen met behulp van de Tab-toets (of een soortgelijke toets) één voor één worden bezocht, in de volgorde waarin ze in de html voorkomen. Shift+Tab-toets keert de volgorde van de Tab-toets om. Dit is een belangrijk hulpmiddel voor mensen die om een of andere reden de muis niet kunnen of willen gebruiken. (En het is vaak ook veel sneller dan de muis, vooral in formulieren.)

In sommige browsers en/of besturingssystemen is dit vreemd genoeg standaard uitgeschakeld en is een zoektocht in de instellingen nodig om dit aan te zetten. Maar gebruikers van de Tab-toets zullen dit al hebben gedaan.

Als je met behulp van de Tab-toets een element hebt bereikt, heeft dit 'focus': als het een link is en je drukt op Enter, wordt de link gevolgd. Bij een tekstveld kun je tekst gaan invoeren. Enzovoort.

De Tab-toets volgt normaal genomen de volgorde van de elementen in de html. Het maakt niet uit, in welke volgorde ze op het scherm staan. Als je met behulp van css de elementen van plaats verwisselt op het scherm, wordt toch gewoon de volgorde in de html gevolgd.

De volgorde van de Tab-toets kan worden veranderd met behulp van het tabindex-attribuut: <div tabindex="3">. Deze <div> zal nu als derde worden bezocht, ook al krijgt een simpele <div> normaal genomen nooit bezoek van de Tab-toets.

Normaal genomen is het gebruik van een tabindex niet nodig. Het is zeker niet bedoeld om de bezoeker als een kangoeroe op een hindernisbaan van onder via links over rechts naar boven te laten springen. Maar soms kan het handig zijn voor kleinere correcties, als de normale volgorde in de html niet optimaal is. Of om een element bereikbaar te maken voor de Tab-toets, zoals de hierboven genoemde <div>.

Schermlezers blijven altijd de volgorde van de html volgen, dus als de tabindex sterk afwijkt van de volgorde in de html, kan dat behoorlijk verwarrend zijn.

De tabindex kan drie verschillende waarden hebben: -1, 0 of een positief getal.

In principe is de volgorde bij gebruik van de Tab-toets als volgt: eerst worden alle positieve getallen in volgorde afgewerkt. Als twee tabindexen dezelfde waarde hebben, wordt de volgorde in de html aangehouden. Een waarde van '0' wordt, afhankelijk van browser en besturingssysteem, verschillend behandeld, waarover iets hieronder bij Tabindex="0" meer.

tabindex="-1"

Een negatieve waarde van -1 zorgt ervoor dat het element volledig wordt genegeerd door de Tab-toets. Zelfs een link met een negatieve tabindex wordt volledig genegeerd. Normaal genomen heeft een tabindex="-1" maar één nut: je kunt dan met behulp van JavaScript toch focus aan het element geven, zonder dat gebruikers van de Tab-toets erdoor worden gehinderd.

In dit voorbeeld wordt tabindex="-1" voor iets anders gebruikt. Als de Tab-toets wordt gebruikt en a#linkje met de pop-up de focus krijgt, wordt a#linkje vergroot, waardoor de pop-up zichtbaar wordt. Omdat de <a> focus heeft, wordt de link gevolgd als op Enter wordt gedrukt. Als nogmaals op de Tab-toets wordt gedrukt, verliest de <a> de focus weer en wordt de <a> met de pop-up weer verkleind en verborgen onder het vraagteken.

De hele constructie met <input> en <label>'s is daarom niet nodig voor gebruikers van de Tab-toets, omdat de <a> rechtstreeks wordt aangedaan door de Tab-toets. In dit geval werken <input> en <label>'s alleen maar verwarrend voor gebruikers van de Tab-toets. Daarom krijgt de <input> een negatieve tabindex, waardoor <input> (en <label>'s) worden genegeerd bij gebruik van de Tab-toets:

<input id="open" type="checkbox" tabindex="-1" aria-hidden="true">

Verder blijkt de schermlezer VoiceOver op iOS, als je van element naar element gaat, de <a> met de pop-up wel te tonen, als deze wordt voorgelezen, maar niet meer te verbergen, als naar het vorige of volgende element wordt gegaan. Door het geven van een negatieve tabindex aan het element gelijk voor de <input> (dat is p#uitleg) en het element gelijk na de tweede <label> (dat is de <div> met de Latijnse opvultekst), wordt de <a> wel weer verborgen:

<p id="uitleg" tabindex="-1">Als je met de cursor (...) op wpclipart.com.</p>

<div tabindex="-1">

tabindex="0"

Volgens de specificatie van html 4.01 moest een tabindex="0" pas worden bezocht, nadat tabindexen met een positief nummer waren bezocht. Sommige browsers hielden zich hier echter niet aan: een tabindex="0" werd gewoon tussen de positieve tabindexen gezet.

In html5 is de situatie nog fijner. Nu staat er alleen dat, wat betreft de volgorde, de gewoonte van het platform wordt gevolgd. Oftewel: doe maar raak. Maar hoe dan ook: als je tabindex="0" gebruikt, kan een element focus krijgen met behulp van de Tab-toets. Ook als dat element normaal genomen geen focus kan krijgen.

Deze waarde wordt in dit voorbeeld niet gebruikt.

tabindex="..."

Op de plaats van de puntjes moet een positief getal worden ingevuld: het volgnummer. Positieve tabindexen worden in dit voorbeeld niet gebruikt.

Muis, toetsenbord, touchpad en touchscreen

Vroeger, toen het leven nog mooi was en alles beter, waren er alleen monitors. Omdat kinderen daar niet af konden blijven met hun tengels, besloten fabrikanten dan maar touchscreens te gaan maken, omdat je die mag aanraken. Het bleek makkelijker te zijn om volwassenen ook te leren hoe je 'n scherm vies maakt, dan om kinderen te leren met hun vingers van de monitor af te blijven.

Zo ontstonden touchscreens en kreeg het begrip ellende een geheel nieuwe lading. In de perfecte wereld van vroeger, waarin alleen desktops bestonden, werkten dingen als hoveren, klikken en slepen gewoon. Zonder dat je eerst 'n cursus hogere magie op Zweinstein hoefde te volgen. Zelfs in JavaScript was het nog wel te behappen, ook voor mensen zoals ik die toevallig niet Einstein heten.

Op dit moment kun je computerschermen ruwweg in twee soorten indelen: schermen die worden aangeraakt, en schermen die worden bediend met hulpmiddelen als een toetsenbord, muis of touchpad. Omdat ook computerschermen zich kennelijk vermengen, bestaan er inmiddels ook schermen die zowel van aanraken als van muizen houden.

Hieronder staat een lijstje met dingen die zijn aangepast voor de verschillende soorten schermen, zodat dit voorbeeld overal werkt.

:hover

Omdat :hover mogelijk niet werkt, als css uitstaat, ontbreekt of onvolledig is geïmplementeerd, moet je nooit belangrijke informatie alleen met behulp van :hover tonen.

In dit voorbeeld wordt tegen deze regel gezondigd. Op forums werd soms gevraagd om 'n pop-up met 'n link. Als je zo'n constructie wilt maken, dan kan het het best op deze manier. In een aantal browsers wordt echter niet eerst de pop-up geopend, maar wordt gelijk de link gevolgd. Deze browsers tonen dus niet de tekst en de afbeelding uit de pop-up. Ook niet alle schermlezers tonen de pop-up altijd. De informatie uit de pop-up is dus niet voor iedereen bereikbaar. Meer hierover is te vinden bij Bekende problemen (en oplossingen).

Je hovert over een element, als je met behulp van muis of touchpad de cursor boven dat element brengt. Hoveren kan over álle elementen. Het wordt veel gebruikt om iets van uiterlijk te laten veranderen, een pop-up te laten verschijnen, en dergelijke.

Bij gebruik van een muis zit er een verschil tussen hoveren en klikken, maar op een touchscreen is dat verschil er niet: je raakt een touchscreen aan of niet. Dit levert problemen op in iOS en in Edge op een touchscreen.

Internet Explorer en Edge op een touchscreen hebben problemen met het openen van de pop-up. Om dat op te lossen, is aan label#vraagteken het attribuut aria-haspopup="true" toegevoegd. Meer hierover is te vinden bij WAI-ARIA-codes.

Op iOS opent de pop-up wel goed, maar is juist het sluiten een probleem. Na aanraken van de <label> met het vraagteken, gedraagt dit <label> zich, alsof het focus heeft. Pas na aanraking van een ander element dat focus kan krijgen, zoals een link, tekstveld of knop, wordt de focus weer weggehaald bij de <label> met het vraagteken. Pas dan verdwijnt de <a> met de pop-up weer.

Daarom is na de <a> nog een <label id="sluit: > toegevoegd. Zodra de pop-up wordt geopend, bedekt label#sluit het volledige venster van de browser. Oftewel: waar je het scherm ook aanraakt, je raakt label#sluit aan. En omdat een <label> op aanraking reageert, sluit de pop-up nu. Normaal genomen is label#sluit verborgen, het dekt het scherm pas af, als de pop-up zichtbaar is. Zodra de pop-up weg is, verdwijnt label#sluit ook weer.

:focus

Omdat :focus mogelijk niet werkt, als css uitstaat, ontbreekt of onvolledig is geïmplementeerd, moet je nooit belangrijke informatie alleen met behulp van :focus tonen.

In dit voorbeeld wordt tegen deze regel gezondigd. Op forums werd soms gevraagd om 'n pop-up met 'n link. Als je zo'n constructie wilt maken, dan kan het het best op deze manier. In een aantal browsers wordt echter niet eerst de pop-up geopend, maar wordt gelijk de link gevolgd. Deze browsers tonen dus niet de tekst en de afbeelding uit de pop-up. Ook niet alle schermlezers tonen de pop-up altijd. De informatie uit de pop-up is dus niet voor iedereen bereikbaar. Meer hierover is te vinden bij Bekende problemen (en oplossingen).

De meeste mensen gaan met een muis naar een link, invoerveld, en dergelijke. Waarna ze vervolgens klikken om de link te volgen, tekst in te voeren, of wat ze ook maar willen doen.

Er is echter 'n tweede manier om naar links, invoervelden, en dergelijke te gaan: met behulp van de Tab-toets (sommige browsers gebruiken andere toetsen, maar het principe is hetzelfde). Met behulp van de Tab-toets kun je naar links, invoervelden, en dergelijke 'springen'.

Waar je staat, wordt door alle browsers aangegeven met een of ander kadertje. De link en dergelijke met het kadertje eromheen 'heeft focus'. Dat wil zeggen dat je die link volgt, als je op de Enter-toets drukt, of dat je in dat veld tekst kunt gaan invoeren, enzovoort.

Het kadertje dat de focus aangeeft, moet nooit zonder meer worden weggehaald. Gebruikers van de Tab-toets hebben dan geen idee meer, waar ze zijn.

De pop-up zit in een gewone <a> en kan dus door het gebruiken van de Tab-toets focus krijgen. Zodra de <a> door gebruik van de Tab-toets focus heeft gekregen, wordt de pop-up vergroot en daarmee zichtbaar.

Op iOS kan het wat ingewikkeld worden als een element selectors met :focus én :hover heeft. Dat is hier niet het geval, want alleen de a#linkje heeft :focus in de selector.

:active

Omdat :active mogelijk niet werkt, als css uitstaat, ontbreekt of onvolledig is geïmplementeerd, moet je nooit belangrijke informatie alleen met behulp van :active tonen.

Een element is actief, als de muis wordt ingedrukt boven dat element. Op sommige touchscreens is het element actief, als het wordt aangeraakt. In dit voorbeeld wordt :active niet gebruikt.

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 (in het Engels 'accessibility') is belangrijk voor bijvoorbeeld blinden die een schermlezer gebruiken, of voor motorisch gehandicapte mensen die moeite hebben met het bedienen van een muis. Een spider van een zoekmachine (dat is het programmaatje dat de site indexeert voor de zoekmachine) is te vergelijken met een blinde. Als je je site goed toegankelijk maakt voor gehandicapten, is dat 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

JavaScript

Er wordt geen JavaScript gebruikt, dus het aan- of uitstaan van JavaScript heeft geen invloed.

CSS

Zonder css zie je de tekst uit de uitleg bovenin, een (overbodig) aankruisvakje, het vraagteken, de link en ten slotte de Latijnse tekst.

In de link staat de tekst die op de achtergrond-afbeelding in de pop-up is te zien, want dat is gewoon de tekst uit de link. Maar de achtergrond-afbeelding zelf ontbreekt.

Afbeeldingen

Zonder afbeeldingen werkt alles gewoon, alleen – je zult het niet geloven – mist de achtergrond-afbeelding.

Gebruikers Tab-toets

Omdat de pop-up in een gewone <a> staat, kan de pop-up worden getoond als de <a> focus krijgt. De <a> werkt verder zoals elke gewone <a>: een Enter laat de link volgen, het indrukken van de Tab-toets laat de <a> de focus weer verliezen (en laat daarmee de pop-up weer verdwijnen).

Tekstbrowsers

Lynx toont de pagina op dezelfde manier als iets hierboven bij CSS is beschreven. Voor WebbIE geldt hetzelfde, maar die laat aankruisvakje en vraagteken niet zien.

Schermlezers

De link wordt in alle schermlezers aangekondigd, kan worden gevolgd en de tekst uit de link wordt voorgelezen. De pop-up wordt niet in alle schermlezers getoond. Een vollediger overzicht van problemen staat bij Schermlezers.

Voor VoiceOver op iOS is bij label#uitleg en main div een negatieve tabindex aangebracht, omdat de pop-up anders moeilijk is te sluiten. Meer daarover is te vinden bij Verder blijkt de schermlezer...

input#open, label#vraagteken en label#sluit zijn met behulp van de WAI-ARIA-code aria-hidden="true" verborgen voor schermlezers.

TalkBack op Android is nogal kieskeurig. De link moet op het scherm staan, minstens 1 x 1 px groot zijn, en nog wat dingen. Het hele verhaal staat bij De schermlezer TalkBack...

Getest in

Laatst gecontroleerd op 31 juli 2017.

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 (en oplossingen). Het is belangrijk dat deel 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 hierboven bij Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.

Dit voorbeeld is getest op de volgende systemen:

Desktopcomputers

Windows 7 (1280 x 1024 px, resolution: 96 dpi):
Firefox, UC Browser, Google Chrome en Internet Explorer 11, in grotere en kleinere browservensters.

OS X 10.11.6 ('El Capitan') (1680 x 1050 px, resolution: 96: dpi, device-pixel-ratio: 1):
Firefox, Safari en Google Chrome, in grotere en kleinere browservensters.

Linux (Kubuntu 14.04 LTS, 'Trusty Tahr') (1280 x 1024 px, resolution: 96 dpi):
Firefox en Google Chrome, in grotere en kleinere browservensters.

Laptops

Windows 8.1 (1366 x 768 px, resolution: 96 dpi):
Bureaublad-versie: Firefox, UC Browser, Google Chrome en Internet Explorer 11, in grotere en kleinere browservensters.
Startscherm-versie: Internet Explorer 11.

Windows 10 (1600 x 900 px, resolution: 96 dpi):
Firefox, UC Browser, Google Chrome, Internet Explorer 11, Edge, in grotere en kleinere browservensters.

Tabletten

iPad met iOS 9.3.5 (1024 x768 px, device-pixel-ratio: 1):
Safari, Chrome for iOS, UC Browser, Firefox (alle portret en landschap).
Opera Mini (Opera Turbo) portret en landschap.

iPad met iOS 10.3.3 (2048 x 1536 px, device-pixel-ratio: 2 ('retina'):
Safari, Chrome for iOS, UC browser, Firefox (alle portret en landschap).
Opera Mini (Opera Turbo) portret en landschap.

Android 4.4.2 ('Kitkat') (1280 x 800 px, resolution: 96 dpi):
Android browser, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.

Android 4.4.2 ('Kitkat') (2560 x 1600 px, resolution: 192 dpi):
Android browser, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.

Android 6 ('Marshmallow') (1920 x 1200 px, resolution: 144 dpi):
Dolphin, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.

Android 7.0 ('Nougat') (1920 x 1200 px, resolution: 144 dpi):
Dolphin, Samsung Internet, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.

Smartphones

Windows Phone 8.1 (800 x 480 px, resolution: 136 dpi):
Internet Explorer en UC browser (portret en landschap).

Windows 10 Mobile (1280 x 720 px, resolution: 192 dpi):
Edge en UC browser (portret en landschap).

Android 4.1.2 ('Jelly Bean') (800 x 480 px, resolution: 144 dpi):
Chrome, Android browser, UC Browser en Firefox (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.

Android 7.0 ('Nougat') (1280 x 720 px, resolution: 192 dpi):
Dolphin, Samsung Internet, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.

Er is op de aan het begin van dit hoofdstukje genoemde controledatum getest in de meest recente versie van de browser, die op het betreffende besturingssysteem kon draaien. Het aantal geteste browsers en systemen is al tamelijk fors, en als ook nog rekening gehouden moet worden met (zwaar) verouderde browsers, is het gewoon niet meer te doen. Surfen met een verouderde browser is trouwens vragen om ellende, want updates van browsers hebben heel vaak met beveiligingsproblemen te maken.

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

Er is getest met behulp van muis en toetsenbord, behalve op de iPad, Android, Windows Phone en Windows 10 Mobile, waar een touchscreen is gebruikt. Op Windows 8.1 en 10 is getest met een touchscreen, met een combinatie van toetsenbord en touchpad, en met een combinatie van toetsenbord en muis.

Als dat relevant is, is op de desktop ook getest, als JavaScript uitstaat. Eventuele problemen staan hierboven bij Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld. (Op iOS, Android, Windows Phone en Windows 10 Mobile is niet getest zonder JavaScript, omdat je JavaScript in een toenemend aantal mobiele browsers niet uit kunt zetten. Bovendien is een mobiel apparaat zonder JavaScript niet veel meer dan een duur en groot uitgevallen horloge.)

Schermlezers en dergelijke

Naast deze 'gewone' browsers is ook getest in Lynx, WebbIE, NVDA, TalkBack, VoiceOver en ChromeVox.

Lynx is een browser die alleen tekst laat zien en geen css gebruikt. Er is getest op Linux.

WebbIE is een browser die gericht is op mensen met een handicap. Er is getest op Windows 7.

NVDA is een schermlezer, zoals die door blinden wordt gebruikt. Er is getest op Windows 7 in combinatie met Firefox, Google Chrome en Internet Explorer, en op Windows 10 in combinatie met Firefox, Google Chrome en Edge.

TalkBack is een in Android ingebouwde schermlezer. Er is getest in combinatie met Chrome op Android 4.4,2, 5.0.1 en 7.0.

VoiceOver is een in iOS en OS X ingebouwde schermlezer. Er is getest in combinatie met Safari op iOS (9.3.5 en 10.3.2) en OS X 10.11.6.

ChromeVox is een schermlezer in de vorm van een extensie bij Google Chrome. Er is getest op een systeem met Kubuntu Linux 14.04.

Als het voorbeeld in deze 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 hierboven bij 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 (en oplossingen) vermeld.

Nieuwe browsers worden pas getest, als ze uit het bèta-stadium zijn, omdat er anders 'n redelijke kans is dat je tegen 'n bug zit te vechten, 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 kunnen niet worden beantwoord, en het melden van fouten in niet-geteste browsers heeft ook geen enkel nut. (Melden van fouten, problemen, enzovoort in wel geteste browsers: graag!)

Bekende problemen (en oplossingen)

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.

Opera Mini op iOS, Dolphin op Android voor versie 6, Opera Mini en sommige versies van Android Browser op Android 4

De link wordt gelijk gevolgd, waardoor de pop-up niet of heel kort is te zien.

(De 'sommige versies' van Android browser op Android 4: op de tablet met 96 dpi werkt het niet goed, op de tablet met 192 dpi werkt het wel goed.)

Als het vraagteken wordt aangeraakt, komt de link met de pop-up boven het vraagteken te staan. In een aantal browsers wordt deze link gelijk gevolgd. Kennelijk wordt op een of andere manier de aanraking van de <p> met het vraagteken doorgegeven aan de gelijk daarna op dezelfde plek verschijnende <a> met de pop-up.

Met behulp van transition-delay: 0.25s; opent de link met de pop-up met een vertraging van 'n kwart seconde. Dat is zo kort, dat je het nauwelijks merkt. Voor de meeste browsers is deze vertraging voldoende. (Voor Edge bijvoorbeeld is zelfs 'n vertraging van 0,01 seconde al genoeg).

Voor de hierboven genoemde browsers is deze vertraging niet voldoende. Voor Opera Mini op iOS is 'n vertraging van 'n halve seconde nodig, en voor de andere browsers zelfs 0,7 seconde. Dat is te lang, want dat levert echt 'n hinderlijk lange vertraging op.

De enige oplossing zou zijn de <a> met de pop-up niet over de <p> met het vraagteken te openen, maar eronder of ernaast. In dat geval werkt het in alle browsers, zelfs als er helemaal geen vertraging zou zijn.

(Overigens opent de pop-up wel, als je het vraagteken langer aanraakt. Maar dat is natuurlijk geen echte oplossing, want alleen telepathisch hoogbegaafden weten dat.)

Dit illustreert ook weer, waarom je geen belangrijke informatie in een pop-up moet verstoppen.

Schermlezers

Op welke combinaties van browsers en schermlezers precies is getest, is iets hierboven te vinden bij Getest in.

In alle schermlezers wordt de link aangekondigd en wordt de tekst uit de link voorgelezen.

ChromeVox

Alles werkt, zoals het is bedoeld, zowel bij het lezen van de hele pagina als bij het van element naar element gaan. De pop-up wordt gesloten en geopend en de link kan worden gevolgd.

NVDA

Als de hele pagina wordt gelezen, opent de pop-up niet. De link kan wel worden gevolgd, met uitzondering van NVDA in combinatie met Edge (de sneltoetsen om naar een link te gaan werken wel). Als element voor element wordt gelezen, wordt de pop-up getoond en verborgen en kan de link worden gevolgd.

TalkBack

In TalkBack kan de link altijd worden gevolgd, maar de pop-up wordt nooit getoond.

VoiceOver op iOS

Bij het lezen van de hele pagina wordt de pop-up niet getoond en kan de link niet worden gevolgd. De pop-up wordt wel getoond en de link kan wel worden gevolgd, als je van element naar element gaat.

VoiceOver op OS X

Als van element naar element wordt gegaan, werkt alles, zoals het is bedoeld. De pop-up wordt gesloten en geopend en de link kan worden gevolgd.

Bij lezen van de hele pagina wordt de pop-up geopend en kan de link worden gevolgd, maar de pop-up wordt niet gesloten. Als Enter wordt ingedrukt, wordt de link gevolgd, ook als de Latijnse tekst al wordt voorgelezen. Door het indrukken van de Tab-toets wordt de pop-up gesloten en wordt de link niet meer gevolgd.

Wijzigingen

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

:

Nieuw opgenomen.

31 juli 2017:

Omdat de code en de uitleg volledig zijn herschreven, zijn eerdere wijzigingen weggehaald. De wijzigingen zijn zelf ook weer overherverwijzigd, waardoor de lijst met wijzigingen vrij nutteloos is geworden.

Inhoud van de download en licenties

De inhoud van deze download kan vrij worden gebruikt, met drie beperkingen:

* Sommige onderdelen die van 'n andere site of zo afkomstig zijn, vallen mogelijk onder een of andere licentie. Dat is hieronder bij het betreffende onderdeel te vinden.

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

* Dit voorbeeld (en de bijbehorende uitleg en dergelijke) wordt regelmatig bijgewerkt. Het is daarom niet toegestaan dit voorbeeld (en de bijbehorende uitleg en dergelijke) op welke manier dan ook te verspreiden, zonder daarbij duidelijk te vermelden dat voorbeeld, uitleg, en dergelijke afkomstig zijn 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.

pop-up-026-dl.html: de pagina met het voorbeeld.

pop-up-026.pdf: deze uitleg (aangepast aan de inhoud van de download).

pop-up-026-inhoud-download-en-licenties.txt: een kopie van de tekst onder dit kopje (Inhoud van de download en licenties).

026-css-dl:

pop-up-026-dl.css: stylesheet voor pop-up-026-dl.html.

026-pics:

026-pics: rapunzel.jpg: de gebruikte achtergrond-afbeelding. De afbeelding is afkomstig van wpclipart.com en mag zonder beperking worden gebruikt.

HTML

De code is geschreven in een afwijkende lettersoort. De code die te maken heeft met de basis van dit voorbeeld (essentiële code), is in de hele uitleg blauw gekleurd. Alle niet-essentiële code is bruin. (In de inhoudsopgave staat alles in een gewone letter vanwege de leesbaarheid.)

In de html hieronder wordt alleen de html besproken, waarover iets meer is te vertellen. Een <h1> bijvoorbeeld wordt in de regel niet genoemd, omdat daarover weinig interessants valt te melden. (Als bijvoorbeeld het uiterlijk van de <h1> wordt aangepast met behulp van css, staat dat verderop bij de bespreking van de css.)

Zaken als een doctype en charset hebben soms wat voor veel mensen onbekende effecten, dus daarover wordt hieronder wel een en ander geschreven.

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 ontbreekt 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>

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. Dit kan zonder enig probleem worden gebruikt: het werkt zelfs in Internet Explorer 6.

<html lang="nl">

De toevoeging lang="nl" bij <html> geeft aan dat de pagina in het Nederlands is. De taal is van belang voor schermlezers, automatisch afbreken, automatisch genereren van aanhalingstekens, juist gebruik van decimale punt of komma, en dergelijke.

<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 browservensters. 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, enzovoort, 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. In dit voorbeeld wordt de tekst nooit breder dan het venster. Maar die stomme mobiele browser weet dat niet, dus die gaat ervan uit dat ook deze 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.

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. 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.

<p id="uitleg" tabindex="-1">Als je met de cursor boven het vraagteken gaat hangen, het vraagteken aanraakt, of de Tab-toets gebruikt, verschijnt een link naar en voorbeeld van een afbeelding op wpclipart.com.</p>

Dit is de <p> bovenaan de pagina, waarin een kleine uitleg staat.

Als je in de schermlezer VoiceOver op iOS van element naar element gaat, opent de pop-up als a#linkje wordt bereikt. Als je dan echter weer naar het vorige element gaat, sluit de pop-up niet meer.

Het eerste element boven a#linkje is p#uitleg, want de tussenliggende input#open en label#vraagteken zijn met behulp van de WAI-ARIA-code aria-hidden="true" voor schermlezers verborgen. Als aan p#uitleg een negatieve tabindex wordt gegeven, blijkt hierdoor a#linkje met de pop-up ook in VoiceOver op iOS weer te sluiten, als je naar het vorige element gaat.

<input id="open" type="checkbox" tabindex="-1" aria-hidden="true">

Dit is de <input> die bij de twee <label>'s hoort, waarmee de pop-up wordt geopend en gesloten.

Deze <input> is eigenlijk niet echt nodig. Zichtbaar is hij niet, want hij wordt verborgen onder het vraagteken en wordt uit- en aangevinkt via de bijbehorende twee <label>'s. Van dat uit- en aanvinken (:checked) wordt geen enkel gebruikt gemaakt, vandaar dat de <input> eigenlijk overbodig is.

<label>'s zonder bijbehorende <input> of iets soortgelijks kunnen zich echter wat onvoorspelbaar gedragen. De specificatie is er wat vaag over. Om problemen te voorkomen, is daarom voor de zekerheid gewoon een <input> gebruikt.

Deze <input> heeft geen enkel nut voor schermlezers en is daarom met behulp van de WAI-ARIA-code aria-hidden="true" voor schermlezers verborgen.

Ook voor gebruikers van de Tab-toets heeft deze <input> geen nut, daarom is deze voor de Tab-toets verborgen met behulp van het attribuut tabindex="-1". Dit verbergt tevens de bij deze <input> horende label#vraagteken en label#sluit voor de Tab-toets.

<label id="vraagteken" for="open" aria-haspopup="true" aria-hidden="true">?</label>

De <label> waarin het vraagteken zit. Door aanraken of -klikken van of hoveren over deze <label> opent de pop-up. Met behulp van for="open" is de <label> gekoppeld aan input#open.

Aan deze <p> is aria-haspopup="true" toegevoegd, omdat de pop-up anders niet goed opent in Internet Explorer en Edge op touchscreens. Meer hierover bij WAI-ARIA-codes.

Deze <label> heeft geen enkel nut voor schermlezers en is daarom met behulp van de WAI-ARIA-code aria-hidden="true" voor schermlezers verborgen.

<label id="sluit"></label>

Met behulp van for="open" is de <label> gekoppeld aan input#open. Deze <label> is helemaal leeg en normaal genomen onzichtbaar. De <label> is nodig om de pop-up in Safari, UC browser en Chrome op iOS te kunnen sluiten. Er is meer over te vinden bij :hover.

<div tabindex="-1">

De <div> waarin de <p>'s met de Latijnse tekst zitten.

Als je in de schermlezer VoiceOver op iOS van element naar element gaat, opent de pop-up als a#linkje wordt bereikt. Als je dan echter verder naar het volgende element gaat, sluit de pop-up niet meer.

Het eerste element na a#linkje is deze <div>, want de tussenliggende label#sluit is met behulp van de WAI-ARIA-code aria-hidden="true" voor schermlezers verborgen. Als aan deze <div> een negatieve tabindex wordt gegeven, blijkt hierdoor a#linkje met de pop-up ook in VoiceOver op iOS weer te sluiten, als je naar het volgende element gaat.

<p lang="la">Lorem ipsum dolor (...) Aenean massa.</p>

Als opvultekst is Latijnse tekst gebruikt. De taal is van belang voor schermlezers, automatisch afbreken, automatisch genereren van aanhalingstekens, juist gebruik van decimale punt of komma, en dergelijke. Daarom wordt met lang="la" aangegeven dat de tekst binnen deze <p> Latijn is. (En tot mijn niet geringe verbazing blijkt een schermlezer als NVDA dat dan, voor zover ik dat kan beoordelen, op de juiste manier voor te lezen.)

CSS

De code is geschreven in een afwijkende lettersoort. De code die te maken heeft met de basis van dit voorbeeld (essentiële code) is in de hele uitleg blauw gekleurd. Alle niet-essentiële code is bruin. (In de inhoudsopgave staat alles in een gewone letter vanwege de leesbaarheid.)

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 ontbreekt 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.

Technisch gezien is er geen enkel bezwaar om de css in de stylesheet allemaal achter elkaar op één regel te zetten:

div#header-buiten {position: absolute; right: 16px; width: 100%; height: 120px; background: yellow;} div p {margin-left 16px; height: 120px; text-align: center;}

Maar als je dat doet, garandeer ik je hele grote problemen, omdat het volstrekt onoverzichtelijk is. Beter is het om de css netjes in te laten springen:

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

        div p {
            margin-left: 16px;
            height: 120px;
            text-align: center;
        }

Hiernaast is het heel belangrijk voldoende commentaar (uitleg) in de stylesheet te schrijven. Op dit moment weet je waarschijnlijk (hopelijk...), waarom je iets doet. Maar over vijf jaar kan dat volstrekt onduidelijk zijn. Op deze site vind je nauwelijks commentaar in de stylesheets, maar dat heeft een simpele reden: deze uitleg is in feite één groot commentaar.

Op internet zelf is het goed, als de stylesheet juist zo klein mogelijk is. Dus voor het uploaden kun je normaal genomen het beste het commentaar weer verwijderen. Veel mensen halen zelfs alles wat overbodig is weg, voordat ze de stylesheet uploaden. Inspringingen bijvoorbeeld zijn voor mensen handig, een computer heeft ze niet nodig.

Je hebt dan eigenlijk twee stylesheets. De uitgebreide versie waarin je dingen uitprobeert, verandert, enzovoort, met commentaar, inspringingen, en dergelijke. Dat is de mensvriendelijke versie. Daarnaast is er dan een stylesheet die je op de echte site gebruikt: een gecomprimeerde versie.

Dat comprimeren kun je met de hand doen, maar er bestaan ook hulpmiddelen voor. Op de pagina met links kun je onder Gereedschap → Snelheid, testen, gzip, comprimeren links naar sites vinden, waar je bestanden kunt comprimeren.

(Stylesheets op deze site zijn niet gecomprimeerd. Omdat het vaak juist om de css gaat, wil ik dat mensen zonder al te veel moeite de css kunnen bekijken.)

css voor alle vensters

/* pop-up-026-dl.css */

Om vergissingen te voorkomen is het een goede gewoonte bovenaan het stijlbestand even de naam neer te zetten. Voor je het weet, zit je anders in het verkeerde bestand te werken.

body

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

background: #ff9;

Achtergrondkleurtje.

color: black;

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

Hoewel dit de standaardkleur is, wordt deze toch specifiek opgegeven. Hierboven is een achtergrondkleur opgegeven. Sommige mensen hebben zelf de voorgrond‑ en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als nu de achtergrondkleur wordt veranderd, maar niet de voorgrondkleur, loop je het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.

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

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

Als Arial is geïnstalleerd op de machine van de bezoeker, wordt deze gebruikt, anders Helvetica. Als die ook niet wordt gevonden, wordt in ieder geval een schreefloze letter (zonder dwarsstreepjes) gebruikt.

margin: 0; padding: 0;

Slim om te doen vanwege verschillen tussen browsers.

#uitleg

Het element met id="uitleg". Dit is de <p>, waarbinnen de korte uitleg bovenaan de pagina zit.

background: white;

Witte achtergrond.

color: black;

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

Hoewel dit de standaardkleur is, wordt deze toch specifiek opgegeven. Hierboven is een achtergrondkleur opgegeven. Sommige mensen hebben zelf de voorgrond‑ en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als nu de achtergrondkleur wordt veranderd, maar niet de voorgrondkleur, loop je het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.

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

Dit is ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.

width: 300px;

300 px breed. Dit past in zo'n beetje elk browservenster, of het moet echt absurd smal zijn. Hierdoor hoeven er geen aanpassingen voor bredere en smallere vensters gemaakt te worden.

Omdat de <p> een blok-element is, wordt de hoogte automatisch hoog genoeg om de erin zittende tekst weer te geven.

text-align: center;

Tekst horizontaal centreren.

margin: 10px auto 0;

Omdat voor links geen waarde is ingevuld, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 10px auto 0 auto in de volgorde boven – rechts – onder – links.

Kleine afstand tussen de bovenkant van het browservenster en de bovenkant van de <p>. Links en rechts auto, wat hier hetzelfde betekent als evenveel. Hierdoor staat de <p> altijd horizontaal gecentreerd binnen z'n ouder <main>. <main> is een blok-element en wordt daarom normaal genomen even breed als z'n ouder <body>, ook een blok-element. Dat dus normaal genomen weer even breed wordt als z'n ouder <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster.

Uiteindelijk wordt <main> dus ook even breed als het venster van de browser en staat de <p> horizontaal gecentreerd binnen het venster, ongeacht de breedte van het venster.

Deze manier van horizontaal centreren van een blok-element werkt alleen, als het te centreren element een breedte heeft.

border: black solid 1px;

Zwart randje.

padding: 3px;

Kleine afstand tussen rand van en tekst in <p>.

#open

Het element met id="open". De <input> die hoort bij de twee <label>'s die openen en sluiten van de pop-up regelen.

display: block;

Een <input> is van zichzelf een inline-element. Daardoor werkt de hier gelijk onder gebruikte marge niet. Door van de <input> een blok-element te maken, kan de marge wel worden gebruikt.

margin: 20px auto 0;

Omdat voor links geen marge is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 20px auto 0 auto in de volgorde boven – rechts – onder – links.

Aan de bovenkant een kleine marge voor wat afstand tot p#uitleg erboven. Bij #vraagteken wordt de <label> met het vraagteken met een negatieve marge 20 px omhoog gezet, waardoor de <input> onder het vraagteken verdwijnt.

Aan de onderkant geen marge.

Links en rechts auto, wat hier hetzelfde betekent als evenveel. Hierdoor staat de <input> altijd horizontaal gecentreerd binnen z'n ouder, ongeacht de breedte van die ouder.

De ouder van deze <input> is <main>, een blok-element. Een blok-element wordt normaal genomen even breed als z'n ouder, dat is het blok-element <body>. Ook <body> wordt normaal genomen even breed als z'n ouder <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster van de browser. Hierdoor staat uiteindelijk de <input> altijd horizontaal gecentreerd binnen het venster, ongeacht de breedte van het venster. Dat komt goed uit, want hierdoor kan hij makkelijk onder de ook horizontaal gecentreerde label#vraagteken met het vraagteken worden verborgen.

Normaal genomen kan een blok-element alleen op deze manier horizontaal worden gecentreerd, als het een breedte heeft. Een <input type="checkbox">, zoals hier is gebruikt, is echter een zogenaamd 'replaced element', en die hebben een soort ingebouwde impliciete breedte. Die breedte verschilt iets in de verschillende browsers, maar dat maakt voor het centreren niets uit. (Een bekendere vorm van een 'replaced element' is een <img>.)

#vraagteken

Het element met id="vraagteken". De <label> waar het vraagteken in zit. Deze <label> zorgt voor het tonen van de pop-up (behalve voor gebruikers van de Tab-toets, want die hebben een eigen manier.)

background: white;

Achtergrond wit.

color: black;

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

Hoewel dit de standaardkleur is, wordt deze toch specifiek opgegeven. Hierboven is een achtergrondkleur opgegeven. Sommige mensen hebben zelf de voorgrond‑ en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als nu de achtergrondkleur wordt veranderd, maar niet de voorgrondkleur, loop je het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.

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

Dit is ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.

cursor: pointer;

Als, bij gebruik van een muis, over de <p> met het vraagteken wordt gehoverd, houdt de cursor z'n standaardvorm. Als de pop-up wordt geopend, verandert de cursor in een handje, omdat de pop-up in een <a>, een link, zit.

In sommige browsers duurt het heel even, voordat de cursor bij hoveren over de <a> in een handje verandert. Daardoor zie je de cursor met een kleine vertraging verspringen van de standaardvorm naar het handje. Door de cursor al in een handje te veranderen bij hoveren over de <p>, voorkom je dit verspringen. 'n Kleinigheidje, maar het staat wat netter.

display: block;

Van zichzelf is een <label> een inline-element. Daardoor kunnen eigenschappen als breedte en hoogte niet worden gebruikt. Door de <label> te veranderen in een blok-element, kan dat wel.

width: 3rem;

Breedte.

De <p> met het vraagteken moet een vierkante vorm krijgen. Iets hieronder wordt de regelhoogte ook 3 rem. Omdat er geen gewone hoogte is, wordt de regelhoogte ook de hoogte van de <p>. Waardoor de <p> 3 x 3 rem is.

De eenheid rem is vrijwel hetzelfde als de eenheid em. Alleen is de rem, de 'root em', gebaseerd op de lettergrootte van het <html>-element. Daardoor is de rem altijd even groot. Ongeacht de lettergrootte van het element, een rem is altijd even groot. De grootte van de em varieert, want deze is afhankelijk van de lettergrootte van het element, waarin de em wordt gebruikt.

Als de gebruiker de lettergrootte van de browser aanpast, wordt feitelijk de grootte van de rem veranderd. Maar ook in dat geval is de rem nog steeds overal even groot, want de verandering is overal hetzelfde.

Hier gelijk onder wordt een lettergrootte van 3 rem aan het vraagteken gegeven. Breedte, hoogte en lettergrootte gebruiken dus alle drie de rem als eenheid. Als de lettergrootte van de browser door de gebruiker wordt veranderd, veranderen breedte, hoogte en lettergrootte hierdoor evenveel.

Maar datzelfde gebeurt ook bij gebruik van de meer gangbare em als eenheid. Toch is de rem hier beter.

#linkje, de <a> met de pop-up, wordt gelijk gezet met de bovenkant van de <p> met het vraagteken. Daarvoor krijgt #linkje bij #linkje aan de bovenkant een negatieve marge van 3 rem. Omdat de rem altijd even groot is, is dat precies de hoogte van label#vraagteken.

Afbeelding 2: bij gebruik van de eenheid em staat de pop-up te laag

Als je de <p> een hoogte en een lettergrootte van 3 em zou geven en #linkje een negatieve marge aan de bovenkant van 3 em, zouden dat twee totaal verschillende groottes zijn. label#vraagteken heeft een lettergrootte van 3 em, en #linkje heeft een lettergrootte van 1 em. De em van label#vraagteken is drie keer zo groot als de em van #linkje. Omdat de rem altijd even groot is, ongeacht de lettergrootte van het element, speelt dit probleem bij een rem niet.

Op de afbeelding is de css helemaal hetzelfde, alleen is als eenheid bij de breedte, regelhoogte en lettergrootte van label#vraagteken en bij de negatieve marge aan de bovenkant van #linkje niet de eenheid rem, maar de eenheid em gebruikt. Omdat de lettergrootte in label#vraagteken 3 em is en in #linkje slechts 1 em, is de em in label#vraagteken drie keer zo groot als in #linkje.

Op de afbeelding is de achtergrond-afbeelding in #linkje is doorzichtig gemaakt, waardoor beter is te zien dat #linkje inderdaad maar een derde van de hoogte van label#vraagteken terug naar boven wordt gezet.

font-size: 3rem;

Lettergrootte.

Als eenheid wordt de relatieve eenheid rem gebruikt, omdat bij gebruik van een absolute eenheid zoals px niet alle browsers de lettergrootte kunnen veranderen. Zoomen kan wel altijd, ongeacht welke eenheid voor de lettergrootte wordt gebruikt.

De rem lijkt erg op de meer bekende em. Waarom hier rem wordt gebruikt, staat hier gelijk boven bij width: 3rem;.

line-height: 3rem;

Regelhoogte.

Omdat geen aparte hoogte aan de <p> is gegeven, is dit tevens de hoogte van de <p>. Tekst wordt normaal genomen automatisch halverwege de regelhoogte geplaatst. Hierdoor staat het vraagteken netjes verticaal gecentreerd.

Als eenheid wordt de relatieve eenheid rem gebruikt, omdat bij gebruik van een absolute eenheid zoals px de regelhoogte niet mee verandert met de lettergrootte.

De rem lijkt erg op de meer bekende em. Waarom hier rem wordt gebruikt, staat iets hierboven bij width: 3rem;.

text-align: center;

Vraagteken horizontaal centreren.

margin: -20px auto 0;

Omdat voor links geen waarde is ingevuld, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 10px auto 0 auto in de volgorde boven – rechts – onder – links.

Kleine afstand tussen de uitleg aan de bovenkant van het browservenster en de bovenkant van de <p>. Links en rechts auto, wat hier hetzelfde betekent als evenveel. Hierdoor staat de <p> altijd horizontaal gecentreerd binnen z'n ouder <main>. <main> is een blok-element en wordt daarom normaal genomen even breed als z'n ouder <body>, ook een blok-element. Dat dus normaal genomen weer even breed wordt als z'n ouder blok-element <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster.

Uiteindelijk wordt <main> dus ook even breed als het venster van de browser en staat de <p> horizontaal gecentreerd binnen het venster, ongeacht de breedte van het venster.

Deze manier van horizontaal centreren van een blok-element werkt alleen, als het te centreren element een breedte heeft.

border: black solid 1px;

Zwart randje.

position: relative;

Dit is alleen nodig, omdat hier gelijk onder een z-index aan de <p> wordt gegeven. Omdat verder niets wordt opgegeven bij top e, heeft dit verder geen invloed op de <p>.

z-index: 10;

Om een of andere reden opent de pop-up niet in Edge op een touchscreen, als label#vraagteken geen z-index heeft. Dat is het enige nut van deze z-index.

Als #linkje met de pop-up wordt geopend, komt deze boven het vraagteken te staan. Door deze z-index zou het vraagteken zichtbaar blijven boven de pop-up. Daarom krijgt #linkje bij #linkje een hogere z-index, zodat het vraagteken toch onder de pop-up verdwijnt.

Een z-index werkt alleen in bepaalde omstandigheden. Eén van die omstandigheden is een relatieve positie. Die is gelijk hierboven gegeven, dus dat is geregeld.

-ms-user-select: none;

user-select staat nog niet in een standaard, daarom is nog een vorm nodig met het voorvoegsel -ms-. Normaal genomen zouden ook de vormen voor andere browsers (en het uiteindelijke user-select) worden opgenomen, maar in dit geval wordt het alleen gebruikt om een probleem in Internet Explorer en Edge op te lossen en zijn de vormen voor andere browsers niet nodig. Meer over hoe dit werkt is te vinden bij De voorvoegsels -moz-, -ms- en -webkit-.

Als in Internet Explorer en Edge op een touchscreen het vraagteken wordt aangeraakt, selecteren deze browsers gelijk het vraagteken. Hoe kort je het vraagteken ook aanraakt. Deze eigenschap schakelt het selecteren van tekst uit, waardoor dit wordt voorkomen.

Nadeel is dat je de tekst nu ook niet meer kunt kopiëren. Maar totdat Microsoft dit eindelijk heeft opgelost, zit er weinig anders op dan deze eigenschap te gebruiken. (Overigens staat hier alleen een vraagteken, dus dat je dat niet kunt kopiëren zal waarschijnlijk niet tot grootscheepse opstanden en revoluties leiden.)

#linkje

Het element met id="linkje". Dit is de <a>, waarbinnen de link en de pop-up zitten.

Normaal genomen zou a#linkje, en daarmee de erin zittende pop-up, links buiten het scherm worden geparkeerd en pas op het scherm worden gezet, als de link zichtbaar moet worden. Voor schermlezers en dergelijke is de link dan bereikbaar, terwijl de lay-out niet wordt verstoord.

Maar in de schermlezer TalkBack op Android blijkt de link niet te werken, als deze buiten het scherm staat. Bovendien moet de link voor TalkBack minimaal 1 x 1 px groot zijn, anders werkt hij ook niet.

Normaal genomen zou a#linkje hier al helemaal worden opgemaakt, maar dat kan dus niet. Breedte, hoogte, linkermarge, border en z-index kunnen vanwege bovenstaande redenen pas worden opgemaakt, als de pop-up wordt getoond.

background: url(../026-pics/rapunzel.jpg);

Achtergrond-afbeelding.

color: black;

Voorgrondkleur zwart. Dit is ook de kleur van de tekst.

Om aan te geven dat het een link is, heeft de tekst in een link normaal genomen een afwijkende kleur. Hier wordt uit de tekst al duidelijk dat het een link is, dus de tekst mag hier gewoon zwart zijn.

width: 1px; height: 1px;

Breedte en hoogte.

Als de link niet minimaal 1 x 1 px groot is, blijkt deze niet te werken in TalkBack op Android. Met deze kleine breedte en hoogte is de link prima te verbergen onder het vraagteken. Pas als de pop-up getoond moet worden, worden breedte en hoogte groot genoeg gemaakt voor de achtergrond-afbeelding.

text-align: center;

Tekst horizontaal centreren.

text-decoration: none;

Normaal genomen wordt tekst in een link onderstreept. Dat is hier niet nodig, omdat uit de tekst al duidelijk wordt dat dit een link is.

margin-top: -3rem;

Hier gelijk onder staat deze marge nogmaals op een iets andere manier: bij de marge aan de bovenkant wordt daar calc() gebruikt. Sommige oudere browsers ondersteunen dat niet en negeren daarom de hier gelijk onder opgegeven marge. Die oudere browsers gebruiken deze regel.

De pop-up staat onder label#vraagteken en zou normaal genomen daaronder komen te staan. label#vraagteken heeft bij #vraagteken een hoogte van 3 rem gekregen. Door de pop-up 3 rem terug naar boven te zetten, komt de bovenkant van de pop-up gelijk te staan met de bovenkant van de <label> met het vraagteken. Niet helemaal, want #linkje en #label#vraagteken hebben beide een border van 1 px breedte aan de bovenkant. Daardoor komt de pop-up 2 px lager dan label#vraagteken te staan. (Om dat te corrigeren wordt gelijk hieronder calc() gebruikt, maar die 2 px is niet het einde van de wereld. Er zal wel vaker iets afwijken in die oudere browsers.)

Als eenheid wordt rem gebruikt, wat vrijwel hetzelfde werkt als het bekendere em. In dit geval is rem geschikter, omdat de pop-up nu ook op de juiste hoogte staat, als de gebruiker de lettergrootte verandert. Een uitgebreider verhaal over waarom de eenheid rem hier beter is dan de eenheid em is te vinden bij width: 3rem;.

margin-top: calc(-3rem - 2px);

Deze marge werkt vrijwel hetzelfde als die gelijk hierboven. De uitleg is ook vrijwel hetzelfde. Het enige verschil: hier wordt bij de marge aan de bovenkant calc() gebruikt. Oudere browsers die dat niet ondersteunen negeren deze regel en gebruiken de gelijk hierboven opgegeven marge zonder calc(). Voor nieuwere browsers overrulet deze regel de eerdere, omdat hij later in de css staat.

Afbeelding 3: pop-up staat 2 pixel te laag

Met behulp van calc() kunnen berekeningen worden gemaakt. De marge aan de bovenkant is hier calc(-3rem – 2px). Die 3 rem werkt precies hetzelfde als bij de marge hier gelijk boven: zet de pop-up 3 rem naar boven terug, zodat de bovenkant van de pop-up op dezelfde hoogte staat als label#vraagteken. Maar eigenlijk moet de pop-up nog 2 px meer naar boven worden gezet, omdat zowel de pop-up als label#vraagteken aan de bovenkant een border van 1 px breed hebben. Op de afbeelding is de pop-up 3 rem naar boven teruggezet. Omdat dat eigenlijk 2 px te weinig is, zie je in het midden nog een klein stukje van label#vraagteken boven de pop-up uitsteken.

Met behulp van calc() kun je verschillende eenheden combineren. De pop-up wordt met behulp van calc() niet 3 rem, maar 3 rem en nog 2 px terug naar boven gezet. Nu staat de pop-up precies op de juiste hoogte.

position: absolute;

Om de <a> met de pop-up op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Als die er niet is, zoals hier het geval is, wordt gepositioneerd ten opzichte van het venster van de browser.

Een <a> is van zichzelf een inline-element. Daardoor zijn eigenschappen als breedte en hoogte niet te gebruiken. Door de <a> absoluut te positioneren, verandert deze in een soort blok-element, waardoor deze eigenschappen wel zijn te gebruiken.

Nog een ander voordeel: een absoluut gepositioneerd element trekt zich niets aan van andere elementen. Als de pop-up wordt getoond, komt deze gewoon over de Latijnse tekst heen te staan. Bij bijvoorbeeld een relatieve positie zou de Latijnse tekst een eind omlaag schuiven, als de pop-up wordt getoond.

left: 50%;

De linkerkant van a#linkje, en daarmee van de daarin zittende pop-up, horizontaal halverwege het browservenster zetten, ongeacht de breedte van het venster.

-webkit-transition-delay: 0.001s; transition-delay: 0.001s;

Hier staat in feite twee keer hetzelfde: transition-delay: 0.001s;. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.

Als op een touchscreen het vraagteken wordt aangeraakt, wordt de pop-up getoond. Pas als de pop-up wordt aangeraakt, moet de link worden gevolgd. In een aantal browsers wordt echter bij aanraking van het vraagteken gelijk de link gevolgd. Het touchscreen 'onthoudt' de aanraking even en geeft die vervolgens ook nog door aan de <a> met de pop-up. Door de pop-up met een kleine vertraging te openen, wordt dit voorkomen.

De pop-up kan op twee manieren worden geopend: met :hover en met :focus.

Een link zoals a#linkje kan alleen focus krijgen door de link aan te raken of aan te klikken, of door de Tab-toets te gebruiken. Omdat de link wordt afgedekt door label#vraagteken, is klikken of aanraken onmogelijk. Alleen door de Tab-toets te gebruiken, kan de link focus krijgen. Daarom is deze vertraging niet nodig bij :focus, want dan speelt het probleem niet. Dat is de reden dat :focus apart, zonder vertraging, wordt afgehandeld bij #linkje:focus.

Bij :hover is de vertraging wel nodig. Bij #vraagteken:hover + #linkje, #linkje:hover wordt de pop-up zichtbaar gemaakt door breedte, hoogte, en dergelijke te veranderen. Normaal genomen zou deze verandering ogenblikkelijk plaatsvinden, maar omdat bij #vraagteken:hover + #linkje, #linkje:hover ook transition-delay: 0.25s; is opgegeven, vindt de verandering pas na 0,25 seconde plaats. Dat is een vertraging die nauwelijks merkbaar is, maar wel in vrijwel alle browsers het gelijk volgen van de link voorkomt.

(In Opera Mini op iOS, Dolphin op Android 6 en eerder, Opera Mini en Android Browser op Android 4 wordt de link toch gelijk gevolgd. Meer daarover bij Bekende problemen (en oplossingen).)

Als de pop-up weer moet worden verborgen, gebeurt dat normaal genomen met dezelfde vertraging, als waarmee de pop-up werd getoond. Bij het weer verdwijnen van de pop-up is de vertraging echter niet nodig. Als je transition-delay ook hier bij #linkje gebruikt en niet alleen bij #vraagteken:hover + #linkje, #linkje:hover, wordt de hier opgegeven waarde gebruikt om de pop-up weer te verbergen. Het tonen gebeurt dan met een vertraging van 0,25 seconde, het weer verbergen met een vertraging van 0,001 seconde.

Een vertraging van 0,001 seconde? Alleen Lucky Luke ziet dat, en die is vast lang geleden al overleden.

Eigenlijk zou de waarde hier 0s, 0 seconde, moeten zijn, maar dan blijkt de hele pop-up niet getoond te worden in Internet Explorer 11 en UC browser op Windows, Windows Phone 8.1 en Windows 10 Mobile. De flauwekul-waarde van 0,001 seconde lost deze kennelijke bug op.

transition-delay is een van de transition-eigenschappen. Met behulp van andere transition-eigenschappen kun je opgeven, bij welke eigenschappen er een vertraging moet optreden. Dat kan nodig zijn, als er meerdere eigenschappen veranderen bij :focus, :hover, en dergelijke, die met een verschillende (of geen) vertraging moeten beginnen. In dit geval is dat niet nodig, omdat de verandering bij alle bij het tonen te veranderen eigenschappen 0,25 seconde vertraagd moet worden.

#linkje span

De <span>'s binnen het element met id="linkje". De <span>'s binnen a#linkje. Dat is hier maar één <span>, waarin de boven de achtergrond-afbeelding staande tekst zit. Door de tekst in een aparte <span> te zetten, kan de tekst eigenschappen krijgen, zonder dat die voor de hele a#linkje gelden.

background: rgba(255, 255, 255, 0.7);

De tekst in de link staat boven een achtergrond-afbeelding, waardoor deze lastig leesbaar is. Door aan de <span> met de tekst een achtergrondkleur te geven, is de tekst toch goed leesbaar.

Vaak wordt voor 'n kleur de hexadecimale notatie gebruikt, iets als color: #33ab01;. Daarbij worden niet alleen cijfers, maar ook letters gebruikt. 0 tot en met 9 werken precies hetzelfde als altijd, maar na de 9 komen nog A, B, C, D, E en F.

Als je telt, is 't dus: 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12, enzovoort. Daarbij is A gelijk aan het tientallige 10, B aan 11, enzovoort. Op deze manier kun je met twee cijfers en/of letters 256 mogelijkheden aangeven: van 00 tot en met FF.

De eerste drie getallen bij rgba() geven de kleur aan. Deze lopen van 0 tot en met 255, dus ook hiermee kun je 256 mogelijkheden aangeven. En omdat er drie getallen zijn levert dat 256 x 256 x 256 = 16.777.216 mogelijke kleuren op, net iets meer dan het aantal kleurpotloden in de gemiddelde kleurdoos van 'n kind.

De notatie bij rgba() geeft dus precies evenveel mogelijkheden als de hexadecimale.

Het eerste getal staat voor rood, het tweede voor groen en het derde voor blauw (feitelijk de Engelse namen, maar de eerste letter is toevallig in het Nederlands hetzelfde). Uit deze drie kleuren zijn alle kleuren op een monitor opgebouwd.

255 wil zeggen volledig aanwezig, 0 wil zeggen helemaal ontbrekend.

255, 255, 255 levert wit op, 0 , 0 , 0 zwart.

In plaats van getallen mag je ook percentages gebruiken, bijvoorbeeld: rgba(10%, 20%, 100%, 0.3).

Omdat in dit voorbeeld drie keer 255 is opgegeven, levert dit een witte kleur op.

Het vierde getal staat voor het alfa-kanaal. Hiermee wordt de doorzichtigheid aangegeven. Dit getal loopt van 0 naar 1. Volledig doorzichtig is 0, volledig ondoorzichtig is 1.

Het getal voor het alfa-kanaal wordt als decimale breuk aangegeven, dus bijvoorbeeld 0.5 wil zeggen halfdoorzichtig. Let erop dat je 'n punt gebruikt, de Amerikaanse manier om breuken aan te geven. Als je 'n komma gebruikt, denkt de browser dat er twee verschillende getallen staan.

In dit voorbeeld is deze achtergrondkleur enigszins doorzichtig: 0.7. Hierdoor zie je de achtergrond-afbeelding van a#linkje nog enigszins door de achtergrondkleur van de <span> heen, maar is de tekst toch goed te lezen.

margin-left: -20000px;

De tekst boven de achtergrond-afbeelding zit binnen a#linkje. Normaal genomen zou je a#linkje links buiten het scherm parkeren, totdat deze zichtbaar moet worden. Maar dan blijkt de link niet te werken in TalkBack op Android. Daarom is bij #linkje de link met de pop-up 1 x 1 px groot gemaakt, zodat deze verborgen kan worden onder het vraagteken.

Afbeelding 4: alleen de tekst uit de pop-up is te zien

De tekst binnen deze <span> is 'Klik of raak plaatje aan om naar site van wpclipart.com te gaan.'. Dit past uiteraard niet binnen een ruimte van 1 x 1 px. Daarom moet deze tekst worden verborgen, totdat de pop-up zichtbaar moet worden.

Op de afbeelding hiernaast is te zien, wat er gebeurt, als de tekst niet wordt verborgen. De pop-up zelf is verborgen onder het vraagteken, maar de tekst uit de pop-up is wel te zien. (Om de tekst duidelijker zichtbaar te maken, is de achtergrond even rood gemaakt.)

Je zou kunnen denken aan overflow: hidden; bij #linkje, Wat niet binnen de 1 x 1 px van #linkje past, wordt dan gewoon afgekapt. Maar helaas blijkt ook dan de link niet te werken in TalkBack op Android. De tekst moet dus op op een andere manier worden verborgen.

Voor het verbergen is display: none; niet bruikbaar. De pop-up wordt bij #vraagteken:hover + #linkje, #linkje:hover met een vertraging van 0,25 seconde getoond. display kan echter niet vertraagd worden. Hierdoor zou de tekst 0,25 seconde eerder zichtbaar zijn dan de rest van de pop-up. Dat lijkt heel weinig tijd, maar het ziet er echt niet uit.

visibility: hidden; kan wel worden vertraagd, maar de tekst blijft dan gewoon z'n ruimte innemen, ook al zie je geen tekst. Omdat #linkje, waar deze <span> in zit, absoluut is gepositioneerd, verplaatst dit andere elementen op de pagina niet, dus in principe zou dit kunnen. Maar het is niet helemaal duidelijk, hoe dit op een aanraking of klik zou moeten reageren. Er is dan een risico dat een argeloze ziel volkomen te goeder trouwe een lege plek in de buurt van het vraagteken aanraakt en gelijk naar de hartbewaking kan, omdat uit het niets een pop-up met ene Rapunzel opduikt.

Daarom wordt voor de tekst teruggevallen op het links buiten het scherm parkeren met een grote negatieve linkermarge. Ook TalkBack blijkt zowaar hiermee te kunnen leven. Nu is in ieder geval zeker dat in geen enkele browser of systeem een aanraking of klik in de buurt van het vraagteken de pop-up voortijdig doet openen.

-ms-user-select: none;

user-select staat nog niet in een standaard, daarom is nog een vorm nodig met het voorvoegsel -ms-. Normaal genomen zouden ook de vormen voor andere browsers (en het uiteindelijke user-select) worden opgenomen, maar in dit geval wordt het alleen gebruikt om een probleem in Internet Explorer en Edge op te lossen en zijn de vormen voor andere browsers niet nodig. Meer over hoe dit werkt, is te vinden bij De voorvoegsels -moz-, -ms- en -webkit-.

Als in Internet Explorer en Edge op een touchscreen het vraagteken wordt aangeraakt, wordt de <a> met de pop-up boven het vraagteken gezet. Als je niet met een onmenselijke snelheid je vinger terugtrekt na de aanraking, selecteren deze browsers de tekst in de pop-up. Deze eigenschap schakelt het selecteren van tekst uit, waardoor dit wordt voorkomen.

Nadeel is dat je de tekst nu ook niet meer kunt kopiëren. Omdat het hier maar om 'n heel kort tekstje gaat, zal dat niet zo'n probleem zijn.

#vraagteken:hover + #linkje, #linkje:hover

Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.

#linkje {background: url(../026-pics/rapunzel.jpg); color: black; width: 1px; height: 1px; text-align: center; text-decoration: none; margin-top: -3rem; margin-top: calc(-3rem – 2px); position: absolute; left: 50%; -webkit-transition-delay: 0.001s; transition-delay: 0.001s;}

Dit zijn twee selectors, gescheiden door een komma.

De selector voor de komma #vraagteken:hover + #linkje zorgt voor het openen van de pop-up:

#vraagteken:hover: als over label#vraagteken wordt gehoverd, of als deze wordt aangeraakt.

+: het element achter de + moet in de html direct volgen op het element voor de +. In dit geval gaat het om een element met id="linkje", dat gelijk op een element met id="vraagteken" volgt.

#linkje: het element met id="linkje". De <a> met de pop-up.

In gewone mensentaal: doe iets met a#linkje, als over label#vraagteken wordt gehoverd, of als dit wordt aangeraakt. In dit geval moet a#linkje met de pop-up worden vergroot, zodat de pop-up zichtbaar wordt.

De selector na de komma #linkje:hover zorgt voor het openblijven van de pop-up:

#linkje:hover: als over a#linkje met de pop-up wordt gehoverd. Bij de eerste selector gelijk hierboven is geregeld dat a#linkje met de pop-up zichtbaar wordt, als over label#vraagteken wordt gehoverd, of als deze wordt aangeraakt. Bij hoveren levert dat echter problemen op.

Op het moment dat de pop-up opent, wordt a#linkje boven label#vraagteken gezet. Daardoor wordt niet meer over label#vraagteken gehoverd, maar over a#linkje. En verdwijnt a#linkje met de pop-up dus weer. Nu wordt er weer over label#vraagteken gehoverd, waardoor a#linkje weer verschijnt. En label#vraagteken weer afdekt en dus weer verdwijnt. Oftewel: de pop-up verschijnt en verdwijnt in een razend tempo.

Door ook a#linkje zelf te laten reageren op hoveren, wordt dit voorkomen. Eerst wordt, door de eerste selector, hoveren over label#vraagteken geregeld. Zodra a#linkje verschijnt, neemt deze tweede selector het over.

Alles bij elkaar: doe iets met a#linkje als over label#vraagteken wordt gehoverd (of als die wordt aangeraakt), of als over a#linkje wordt gehoverd.

width: 186px; height: 254px;

Een achtergrond-afbeelding heeft van zichzelf geen breedte en hoogte, maar vult alleen de achtergrond van het element, waarin hij zit. Door de <a> even groot te maken als de afbeelding, wordt precies hele afbeelding getoond.

(Normaal genomen zou de <a> met de pop-up al bij #linkje deze afmetingen hebben gekregen en buiten het scherm zijn geparkeerd, tot de <a> zichtbaar moet worden. Dan geef je de hele opmaak op één plek. Omdat dat echter in TalkBack op Android problemen geeft, heeft a#linkje bij #linkje een breedte en hoogte van 1 px gekregen, zodat deze verborgen kan worden onder label#vraagteken. Pas hier kunnen de uiteindelijke breedte en hoogte worden weergegeven, want met deze breedte en hoogte kan de pop-up niet worden verborgen onder het vraagteken.)

In deze <a> staat ook tekst. Die tekst heeft geen lettergrootte gekregen, waardoor de lettergrootte wordt geërfd van de voorouders van de <a>. In browservensters smaller dan 760 px is geen lettergrootte opgegeven aan de voorouders, waardoor de standaardlettergrootte van 1 em wordt gebruikt. In bredere vensters is de lettergrootte 110%, wat hetzelfde is als 1,1 em.

Afbeelding 5: ook een grote letter past nog in de pop-up

Omdat em een relatieve eenheid is en geen absolute eenheid zoals px, kan de gebruiker de lettergrootte veranderen. Maar als de letters worden vergroot, veranderen de hier opgegeven breedte en hoogte niet mee, omdat deze wel in de absolute eenheid px zijn opgegeven.

Normaal genomen is dat geen goed idee, omdat de tekst hierdoor buiten het element kan komen te staan. In dit geval is dat geen probleem, omdat er maar heel weinig tekst is. Op de afbeelding is de tekst tot 200% vergroot, en alleen de letter 'm' van 'wpclipart.com' komt buiten de pop-up te staan. Omdat de tekst in de link bij #linkje span een doorzichtig witte achtergrondkleur heeft gekregen, is ook die letter 'm' nog duidelijk te zien.

margin-left: -94px;

Bij #linkje is de linkerkant van a#linkje met left: 50%; horizontaal in het midden van het browservenster gezet. De pop-up is 188 px breed (een breedte van 186 px en een border van 1 px links en rechts). Door de pop-up 94 px ,de helft van die breedte, terug naar links te zetten, komt de pop-up echt in het midden van het venster te staan.

(Normaal genomen zou de <a> met de pop-up deze marge al bij #linkje hebben gekregen en buiten het scherm zijn geparkeerd, tot de <a> zichtbaar moet worden. Dan geef je de hele opmaak op één plek. Omdat dat buiten het scherm parkeren echter in TalkBack op Android problemen geeft, kan de negatieve linkermarge niet eerder worden gegeven. a#linkje wordt onder label#vraagteken verborgen, en met zo'n negatieve marge zou a#linkje niet onder, maar links van het vraagteken komen te staan.)

border: black solid 1px;

Zwart randje.

(Normaal genomen zou de <a> met de pop-up deze border al bij #linkje hebben gekregen en buiten het scherm zijn geparkeerd, tot de <a> zichtbaar moet worden. Dan geef je de hele opmaak op één plek. Omdat dat buiten het scherm parkeren echter in TalkBack op Android problemen geeft, kan de border pas hier worden opgegeven.

Als de border eerder zou worden opgegeven, zou de border voortdurend aanwezig zijn. a#linkje heeft bij #linkje een grootte van 1 x 1 px gekregen. De border zou dus heel klein zijn, 'n soort stip. De pop-up wordt met een vertraging van 0,25 seconde geopend. Hierdoor is die stip heel even zichtbaar. Op deze manier wordt dat voorkomen. Dat kan ook nog op andere manieren, maar deze manier is redelijk simpel.)

z-index: 20; Afbeelding 6: vraagteken staat boven pop-up

De <a> met de pop-up komt over label#vraagteken te staan. Normaal genomen komen elementen die later in de html staan boven eerdere elementen te staan. Normaal genomen zou a#linkje daarom boven label#vraagteken komen te staan. Maar omdat label#vraagteken bij #vraagteken een z-index heeft gekregen, komt label#vraagteken toch boven a#linkje met de pop-up te staan. Dat ziet eruit zoals op de afbeelding: de <label> met het vraagteken verbergt een groot deel van de bovenkant van de pop-up.

Om dit te voorkomen, krijgt de <a> met de pop-up een hogere z-index dan label#vraagteken. De z-index van label#vraagteken heeft een waarde van 10, de z-index van a#linkje krijgt een waarde van 20. De getallen sluiten niet op elkaar aan, waardoor het makkelijk is er later eventueel nog elementen met een z-index tussen te voegen. (Als je ooit 300 z-indexen hebt moeten hernummeren, omdat er helemaal aan het begin eentje bij moest komen, vergeet je nooit meer, waarom dat overslaan van nummers handig is...)

Een z-index werkt alleen in bepaalde omstandigheden. Twee van die omstandigheden zijn een absolute positie en transform. De absolute positie is gelijk hierboven gegeven, transform wordt gelijk hieronder gebruikt, dus dat is hier zelfs dubbelop geregeld.

(Normaal genomen zou de <a> met de pop-up deze z-index al bij #linkje hebben gekregen en buiten het scherm zijn geparkeerd, tot de <a> zichtbaar moet worden. Dan geef je de hele opmaak op één plek. Omdat dat buiten het scherm parkeren echter in TalkBack op Android problemen geeft, kan de z-index niet eerder worden opgegeven. De <a> heeft bij #linkje een grootte van 1 x 1 px gekregen. Als de <a> boven de <label> met het vraagteken zou staan en je zou precies die ene pixel aanraken, zou de link gelijk worden gevolgd. Nu wordt de <a> afgeschermd door de <label> met het vraagteken.)

-webkit-transition-delay: 0.25s; transition-delay: 0.25s;

Hier staat in feite twee keer hetzelfde: transition-delay: 0.25s;. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.

Voordat de pop-up zichtbaar wordt, is er een vertraging van 0,25 seconde. a#linkje met de pop-up komt boven het vraagteken te staan. Veel browsers op touchscreens blijken, na aanraken van label#vraagteken, gelijk de link te volgen. Deze kleine vertraging voorkomt dat in de meeste browsers. Meer over hoe dit precies werkt is te vinden bij -webkit-transition-delay: 0.001s; transition-delay: 0.001s;.

vraagteken:hover + #linkje span, #linkje:hover span

Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.

#linkje span {background: rgba(255, 255, 255, 0.7); margin-left: -20000px; -ms-user-select: none;}

Dit zijn twee selectors, gescheiden door een komma.

De selector voor de komma #vraagteken:hover + #linkje span zorgt voor het verschijnen van de tekst boven de achtergrond-afbeelding in de pop-up:

#vraagteken:hover: als over label#vraagteken wordt gehoverd, of als dit wordt aangeraakt.

+: het element achter de + moet in de html direct volgen op het element voor de +. In dit geval gaat het om een element met id="linkje", dat gelijk op een element met id="vraagteken" volgt.

#linkje span: de <span>'s in het element met id="linkje". Dit is de <span>, waarbinnen de tekst in a#linkje zit.

In gewone mensentaal: doe iets met de <span> in a#linkje, als over label#vraagteken wordt gehoverd, of als dit wordt aangeraakt. In dit geval moet de tekst in a#linkje binnen het scherm worden gezet.

De selector na de komma #linkje:hover span zorgt dat de tekst boven de achtergrond-afbeelding in de pop-up blijft staan.

#linkje:hover: als over a#linkje met de pop-up wordt gehoverd. Bij de eerste selector gelijk hierboven is geregeld dat de tekst in de <span> in a#linkje zichtbaar wordt, als over label#vraagteken wordt gehoverd, of als deze wordt aangeraakt. Maar op het moment dat dat gebeurt, wordt a#linkje boven label#vraagteken gezet. Daardoor wordt niet meer over label#vraagteken gehoverd, maar over a#linkje. En verdwijnt de <span> met de tekst dus weer. Oftewel: de tekst verschijnt, om daarna op vrijwel hetzelfde moment weer te verdwijnen.

Door ook a#linkje zelf te laten reageren op hoveren, wordt dit voorkomen. Eerst wordt, door de eerste selector, hoveren over label#vraagteken geregeld. Zodra a#linkje verschijnt, neemt deze tweede selector het over.

Alles bij elkaar: doe iets met de <span> in a#linkje als over label#vraagteken wordt gehoverd (of als die wordt aangeraakt), of als over a#linkje wordt gehoverd.

margin-left: 0;

Bij #linkje span is de <span> met margin-left: -20000px; links buiten het scherm geparkeerd. Waarom dat nodig is, staat daar beschreven. Hier wordt de <span>, en daarmee de erin zittende tekst, weer binnen het scherm gezet en daardoor zichtbaar.

-webkit-transition-delay: 0.25s; transition-delay: 0.25s;

Hier staat in feite twee keer hetzelfde: transition-delay: 0.25s;. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.

a#linkje met de pop-up wordt met een vertraging van 0,25 seconde getoond. Omdat de tekst in de <span> op de achtergrond-afbeelding in a#linkje moet komen te staan, moet ook de tekst pas na een vertraging van 0,25 seconde worden getoond. Meer over de reden van deze vertraging is te vinden bij -webkit-transition-delay: 0.001s; transition-delay: 0.001s;.

#linkje:focus

Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.

#linkje {background: url(../026-pics/rapunzel.jpg); color: black; width: 1px; height: 1px; text-align: center; text-decoration: none; margin-top: -3rem; margin-top: calc(-3rem – 2px); position: absolute; left: 50%; -webkit-transition-delay: 0.001s; transition-delay: 0.001s;}

Als het element met id="linkje" focus heeft. Als a#linkje met de pop-up focus heeft.

Sommige mensen gebruiken niet de muis, maar de Tab-toets om links, tekstvelden, knoppen, en dergelijke langs te lopen. Vanwege een handicap, of omdat dat soms gewoon veel handiger is. Omdat de pop-up in een gewone <a> staat, kan deze focus krijgen, als de Tab-toets wordt gebruikt.

Deze selector heeft hetzelfde effect als #vraagteken:hover + #linkje, #linkje:hover iets hierboven, maar die selector is voor :hover. Je zou deze en die selector kunnen combineren, maar bij de selector voor :hover is met transition-delay een kleine vertraging ingebouwd. Die vertraging is niet hinderlijk bij :hover, maar wel bij gebruik van de Tab-toets. En omdat die vertraging ook niet nodig is bij de Tab-toets, krijgt :focus een eigen selector, zonder transition-delay.

width: 186px; height: 254px; margin-left: -94px; border: black solid 1px; z-index: 20;

De css voor deze selector werkt precies hetzelfde als die voor #vraagteken:hover + #linkje, #linkje:hover iets hierboven. De beschrijving is daar te vinden.

#linkje:focus span

Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.

#linkje span {background: rgba(255, 255, 255, 0.7); margin-left: -20000px; -ms-user-select: none;}

Als het element met id="linkje" focus heeft, doe dan iets met de <span> 's die in #linkje zitten. Dat is hier maar één <span>: de tekst in de link zit erin.

Sommige mensen gebruiken niet de muis, maar de Tab-toets om links, tekstvelden, knoppen, en dergelijke langs te lopen. Vanwege een handicap, of omdat dat soms gewoon veel handiger is. Omdat de pop-up in een gewone <a> staat, kan deze focus krijgen, als de Tab-toets wordt gebruikt.

Deze selector heeft hetzelfde effect als #vraagteken:hover + #linkje span, #linkje:hover span iets hierboven, maar die selector is voor :hover. Je zou deze en die selector kunnen combineren, maar bij de selector voor :hover is met transition-delay een kleine vertraging ingebouwd. Die vertraging is niet hinderlijk bij :hover, maar wel bij gebruik van de Tab-toets. En omdat die vertraging ook niet nodig is bij de Tab-toets, krijgt :focus een eigen selector, zonder transition-delay.

margin-left: 0;

Bij #linkje span is de <span> met margin-left: -20000px; links buiten het scherm geparkeerd. Waarom dat nodig is, staat daar beschreven. Hier wordt de <span>, en daarmee de erin zittende tekst, weer binnen het scherm gezet en daardoor zichtbaar.

#sluit

Het element met id="sluit". Dit is een <label> die speciaal voor iOS is aangebracht, omdat sluiten van de pop-up in Safari, UC browser en Chrome op iOS anders lastig is. De pop-up sluit in deze browsers alleen, als een ander voor aanraking gevoelig element, zoals een <label>, wordt aangeraakt. Zodra de pop-up opent, bedekt deze <label> het hele browservenster. Alleen de pop-up staat boven deze <label>. Waar je het venster ook buiten de pop-up aanraakt, je raakt deze <label> aan, waardoor de pop-up weer sluit (en deze <label> ook weer verdwijnt.)

display: none;

Verbergen. Normaal genomen wordt deze <label> niet weergegeven, pas als de pop-up is geopend wordt hij bij #vraagteken:hover ~ #sluit, #linkje:hover + #sluit, #linkje:focus + #sluit met display: block; zichtbaar gemaakt.

background: rgba(0, 0, 0, 0.7);

Dit levert een zwarte, doorzichtige achtergrond op. Hoe rgba() precies werkt, is te vinden bij background: rgba(255, 255, 255, 0.7);. Het enige verschil is dat hier de eerste drie getallen niet 255, maar 0 zijn. Dit levert daarom geen doorzichtig wit, maar doorzichtig zwart op. Verder is het verhaal precies hetzelfde.

Omdat de achtergrondkleur enigszins doorzichtig is, zie je de pagina nog enigszins door de achtergrond heen, maar is wel goed duidelijk dat eerst de pop-up weer moet worden gesloten.

position: fixed;

Positioneren ten opzichte van het venster van de browser.

top: 0; right: 0; bottom: 0; left: 0;

De <span> moet het volledige browservenster bestrijken.

#vraagteken:hover ~ #sluit, #linkje:hover + #sluit, #linkje:focus + #sluit

Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.

#sluit {background: rgba(0, 0, 0, 0.7); display: none; position: fixed; top: 0; right: 0; bottom: 0; left: 0;}

Dit zijn drie selectors, gescheiden door een komma. Alle drie de selectors doen iets met label#sluit. Dit is een tweede <label> bij input#open dat nodig is om op iOS de pop-up weer te laten verdwijnen. Zodra de pop-up wordt getoond, dekt deze <label> het hele browservenster af, behalve de pop-up. Door het aanraken van de <label> verdwijnt de pop-up weer. Over de werking op iOS is meer te vinden bij :focus.

Omdat deze <label> toch aanwezig is, wordt hij daarnaast ook gebruikt om het browservenster – met uitzondering van de pop-up – donkerder te maken, als de pop-up wordt getoond.

De selector voor de eerste komma #vraagteken:hover ~ #sluit:

#vraagteken:hover: als over label#vraagteken wordt gehoverd, of als dit wordt aangeraakt.

~: het hierachter staande element moet ergens in de html staan, na het voor de ~ staande element. Het hoeft er, anders dan bij de +, niet gelijk op te volgen, als het maar ergens na het eerste element in de html staat.

De enige voorwaarde is verder dat het voor en na de ~ staande element dezelfde ouder hebben. Dat is hier het geval: #vraagteken voor de ~ en #sluit na de ~ hebben beide als ouder <main>.

#sluit: het element met id="sluit". De tweede <label> bij input#open.

In gewone mensentaal: doe iets met label#sluit, als over label#vraagteken wordt gehoverd, of als dit wordt aangeraakt.

De selector tussen de komma's #linkje:hover + #sluit:

#linkje:hover: als over a#linkje met de pop-up wordt gehoverd, of als dit wordt aangeraakt.

+: het element achter de + moet in de html direct volgen op het element voor de +. In dit geval gaat het om een element met id="sluit", dat gelijk op een element met id="linkje" volgt.

#sluit: het element met id="sluit". De tweede <label> bij input#open.

In gewone mensentaal: doe iets met label#sluit, als over a#linkje met de pop-up wordt gehoverd, of als dit wordt aangeraakt. (In de praktijk heeft dit alleen effect bij hoveren, want als #linkje wordt aangeraakt, wordt de link gevolgd.)

De selector achter de tweede komma #linkje:focus + #sluit;

#linkje:focus: als a#linkje focus heeft.

+: het element achter de + moet in de html direct volgen op het element voor de +. In dit geval gaat het om een element met id="sluit", dat gelijk op een element met id="linkje" volgt.

#sluit: het element met id="sluit". De tweede <label> bij input#open.

In gewone mensentaal: doe iets met label#sluit, als a#linkje focus heeft.

De drie selectors samen in gewone mensentaal: doe iets met label#sluit, als over label#vraagteken of over a#linkje wordt gehoverd, of als deze worden aangeraakt, of als a#linkje focus heeft.

display: block;

Alle eerdere css is al bij sluit opgegeven. Daar is label#sluit ook verborgen met display: none;. Nu moet de <label> worden getoond.

main div

De <div>'s binnen <main>. Dat is hier maar één <div>, waarbinnen de Latijnse tekst staat.

background: white;

Witte achtergrond.

color: black;

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

Hoewel dit de standaardkleur is, wordt deze toch specifiek opgegeven. Hierboven is een achtergrondkleur opgegeven. Sommige mensen hebben zelf de voorgrond‑ en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als nu de achtergrondkleur wordt veranderd, maar niet de voorgrondkleur, loop je het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.

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

Dit is ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.

width: 800px;

Breedte.

max-width: 90%;

Hier gelijk boven is een breedte van 800 px opgegeven. In smallere browservensters is dat te breed. Daarom wordt hier een maximumbreedte opgegeven.

Een breedte in procenten is normaal genomen ten opzichte van de ouder van het element. Dat is hier het blok-element <main>. Een blok-element wordt normaal genomen even breed als z'n ouder, hier het blok-element <body>. Ook dit blok-element wordt normaal genomen even breed als z'n ouder <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster van de browser. Uiteindelijk wordt hierdoor de <div> niet breder dan 90% van het venster.

margin: 10px auto 0;

Omdat voor links geen waarde is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 10px auto 0 auto in de volgorde boven – rechts – onder – links. Boven een kleine afstand tot het vraagteken erboven. Onder geen marge. Links en rechts auto, wat hier evenveel betekent. Hierdoor staat de <div> altijd horizontaal gecentreerd binnen z'n ouder <main>, ongeacht hoe breed <main> is.

<main> is een blok-element en wordt daarom normaal genomen even breed als z'n ouder, hier het blok-element <body>. Ook dit blok-element wordt normaal genomen even breed als z'n ouder <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster van de browser. Uiteindelijk staat de <div> hierdoor altijd horizontaal gecentreerd binnen het venster.

border: black solid 1px;

Zwart randje.

padding: 5px;

Kleine ruimte tussen rand om en inhoud van de <div>.

css voor vensters minimaal 760 px breed

@media screen and (min-width: 760px)

De css die hier tot nu toe staat, geldt voor alle browservensters.

De css die binnen deze media query staat, geldt alleen voor vensters die minimaal 760 px breed zijn. In deze bredere vensters worden de letters iets vergroot.

@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 @media-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.

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

(min-width: 760px): het venster moet minimaal 760 px breed zijn. Is het venster smaller, 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-width: 760px) { 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 }.

Als je nou 'n mobieltje hebt met een resolutie van – ik roep maar wat – 1024 x 768 px, dan geldt deze media query toch niet voor dat mobieltje. Terwijl dat toch echt meer dan 760 px breed is. Een vuig complot van gewetenloze multinationals? Voordat je je gaat beklagen bij Radar, zou ik eerst even verder lezen.

Steeds meer mobiele apparaten, maar ook steeds meer gewone beeldschermen, hebben een hogere resolutiedichtheid. Dat wil zeggen dat ze kleinere pixels hebben, die dichter bij elkaar staan. Daardoor zijn foto's, tekst, en dergelijke veel scherper weer te geven. Hoe kleiner de puntjes (de pixels) zijn, waaruit een afbeelding is opgebouwd, hoe duidelijker het wordt.

Er ontstaat alleen één probleem: als je de pixels twee keer zo klein maakt, wordt ook wat je ziet twee keer zo klein. En inmiddels zijn er al apparaten met pixels die meer dan vier keer zo klein zijn. Een lijntje van 1 px breed zou op die apparaten minder dan 'n kwart van de oorspronkelijke breedte krijgen en vrijwel onzichtbaar zijn. Een normale foto zou in een thumbnail veranderen. Kolommen zouden heel smal worden. Tekst zou onleesbaar klein worden. Allemaal fantastisch scherp, maar je hebt 'n vergrootglas nodig om 't te kunnen zien.

Om dit te voorkomen wordt een verschil gemaakt tussen css-pixels en schermpixels (in het Engels 'device-pixels'). De css-pixels zijn gebaseerd op de – tot voor kort – normale beeldschermen van de desktop. 1 css-pixel is op zo'n beeldscherm 1 pixel. Het aantal schermpixels is het werkelijk op het apparaat aanwezige aantal pixels (dat is het aantal pixels, waarvoor je hebt betaald).

Dat eerder genoemde mobieltje van 1024 x 768 px heeft wel degelijk het aantal pixels, waarvoor je hebt betaald. Maar die zitten dichter bij elkaar. Op een gewoon beeldscherm zitten 96 pixels per inch, wat wordt uitgedrukt met de eenheid dpi ('dots per inch'). Als dat mobieltje een resolutie van 192 dpi heeft, 192 pixels per inch, zijn de pixels ervan twee keer zo klein als op een origineel beeldscherm. Er zijn per inch twee keer zoveel schermpixels aanwezig.

Om nu te voorkomen dat alles op dat mobieltje twee keer zo klein wordt, geeft het mobieltje niet het echte aantal schermpixels (1024 x 768), maar een lager aantal css-pixels door bij een media query. De 192 dpi van het mobieltje is twee keer zo veel als de 96 dpi van een normaal beeldscherm. Het aantal css-pixels is dan het aantal schermpixels gedeeld door 2. 1024 x 768 gedeeld door 2 is 512 x 384 px. Het aantal css-pixels is 512 x 384 px en zit daarmee dus ruim onder de 760 px van deze media query. Je bent dus niet opgelicht, of in ieder geval niet wat betreft het aantal pixel.

Door deze truc is een lijn van 1 px breed op een normaal beeldscherm ook op het mobieltje nog steeds 1 px breed, alleen wordt die ene (css-)pixel opgebouwd uit twee schermpixels (feitelijk vier, want het verhaal geldt voor breedte én hoogte). De dikte van het lijntje is hetzelfde, maar het is veel fijner opgebouwd. Bij lijntjes is dat verschil bijvoorbeeld in bochten goed te zien.

Hetzelfde verhaal geldt voor hogere resoluties, Een tablet met een breedte van 4096 schermpixels en een dpi van 384 (vier keer de originele dichtheid) geeft 4096 gedeeld door 4 = 1024 css-pixel door. Het lijntje van 1 px breedte op de originele monitor is nog steeds 1 css-pixel breed op de tablet, maar die ene css-pixel is nu opgebouwd uit zestien schermpixel.

(Overigens kun je met behulp van media query's ook testen op de resolutie met gebruik van het sleutelwoord 'resolution'. Apple gebruikt het niet-standaard 'device-pixel-ratio', maar het idee is hetzelfde. Dit kan bijvoorbeeld handig zijn om te bepalen, hoe groot een foto moet zijn.)

Kort samengevat: omdat niet het aantal schermpixels (waarvoor je hebt betaald), maar het aantal css-pixels (de door de ontwerper bedoelde afmeting) wordt doorgegeven, wordt voorkomen dat een hogeresolutiescherm onleesbaar klein wordt.

body

Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat. (Alleen wat binnen deze media query geldig is, wordt binnen dit blokje herhaald.)

body {background: #ff9; color: black; font-family: Arial, Helvetica, sans-serif; margin: 0; padding: 0;}

Het element waarbinnen de hele pagina staat. Veel instellingen die hier worden opgegeven, worden geërfd door de nakomelingen 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: 110%;

Iets groter dan standaard. 't Zal de leeftijd zijn, maar ik vind de standaardgrootte wat te klein.

Als eenheid wordt de relatieve eenheid % gebruikt, omdat bij gebruik van een absolute eenheid zoals px niet alle browsers de lettergrootte kunnen veranderen. Zoomen kan wel altijd, ongeacht welke eenheid voor de lettergrootte wordt gebruikt.