Skip links en inhoudsopgave

Geneste pop-ups die openen bij aanraken, hoveren of tabben - uitleg

Laatst aangepast: .

Afbeelding 1: geneste pop-ups geopend en gesloten

Korte omschrijving

Binnen een afbeelding zit een serie geneste pop-ups. Bij aanraken van, hoveren over of tabben naar de afbeelding, opent steeds een volgende pop-up.

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 twee beperkingen:

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

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

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

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

Als je in een desktopbrowser met behulp van zoomen het beeld vergroot, heeft dit hetzelfde effect, als wanneer de pagina in een kleiner browservenster wordt getoond. Je kunt hiermee dus kleinere apparaten zoals een tablet of een smartphone simuleren. Maar het blijft natuurlijk wel een simulatie: het is nooit hetzelfde als testen op een écht apparaat. Zo kun je bijvoorbeeld aanrakingen alleen echt testen op een echt touchscreen.

Inmiddels hebben veel browsers mogelijkheden voor het simuleren van weergave op een kleiner scherm in de ontwikkelgereedschappen ingebouwd. Ook dit blijft een simulatie, maar geeft vaak wel een beter beeld dan zoomen.

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

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

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

Om dat maar gelijk gehad te hebben: dit hele verhaal is gebaseerd op een vuige leugen. Het gaat helemaal niet over pop-ups, maar over afbeeldingen die voortdurend aanwezig zijn. Alleen staan ze links buiten het scherm geparkeerd en zie je ze pas, als ze op het scherm worden gezet. Dit ziet er echter precies uit als 'echte' pop-ups en daarom worden ze in het algemeen ook gewoon 'pop-up' (of 'css-pop-up') genoemd. Nu je dus weet dat je vanaf het begin voor de gek wordt gehouden, kan het echte verhaal komen. Of je dat dan nog wel vertrouwt, mag je zelf beslissen.

In een <div> zit een gewone afbeelding. Binnen de <div> zit weer een andere <div>, waarin ook een gewone afbeelding zit. Binnen die <div> zit weer een <div> met een afbeelding. Enz., tot zes niveaus diep.

Behalve de buitenste <div> staan alle <div>'s links buiten het scherm geparkeerd. Daardoor staan ook de in de <div>'s zittende afbeeldingen buiten het scherm, zodat deze niet te zien zijn.

Je zou de <div>'s ook kunnen verbergen met display: none;, maar dan worden ze door schermlezers volledig genegeerd. Als ze buiten het scherm staan, worden ze gewoon voorgelezen door schermlezers. In dit geval zitten er alleen afbeeldingen in de <div>'s, en die lezen wat lastig voor. Daarom heeft elke afbeelding een alt-omschrijving: die wordt door schermlezers wel voorgelezen. (Ook voor zoekmachines is een alt-omschrijving belangrijk, want die kunnen ook geen plaatjes 'zien'.)

Bij hoveren over of aanraken van de buitenste <div> wordt de eerste daarin geneste <div> op het scherm gezet. Daardoor wordt de in die geneste <div> zittende afbeelding zichtbaar. Bij hoveren over of aanraken van deze eerste op het scherm gezette <div>, wordt de daarin weer geneste <div> met afbeelding op het scherm gezet, en daarmee zichtbaar. Bij hoveren daarover of aanraken daarvan de daarin zittende <div>, enz., tot zes niveaus diep.

Bij het hoveren of het aanraken is een kleine vertraging van 0.4 seconde ingebouwd, voordat de <div> wordt getoond. Sommige browsers op touchscreens hebben die vertraging nodig, omdat anders twee (of zelfs meer) geneste <div>'s gelijktijdig worden geopend. Of dat aan de browser of aan het touchscreen ligt, weet ik niet. 0,4 seconde is de kortste vertraging, waarbij alle browsers op alle touchscreens goed werken. Deze vertraging is zo klein, dat het nauwelijks opvalt.

Voor gebruikers van de Tab-toets is gelijk voor elke geneste <div> een <span> aangebracht. Door de <span> het attribuut tabindex="0" te geven, kan deze focus krijgen. Door in de css te testen op <span>'s met focus, kan de gelijk op de <span> volgende <div> – en dus de daarin zittende afbeelding – op het scherm worden gezet. Anders dan bij hoveren of aanraken, is hierbij steeds slechts één geneste <div> met afbeelding zichtbaar, want slechts één element kan focus krijgen. Zodra nogmaals op de Tab-toets wordt gedrukt, verliest de <span> die focus heeft deze, en krijgt de volgende <span> focus.

Er zijn twee afbeeldingen met elk vijf <span>'s. Om bij de tekst onder de pop-ups te komen, moet daarom tien keer de Tab-toets worden ingedrukt. Als iemand gewoon naar de tekst wil gaan, zonder eerst al die pop-ups te zien, begint die vermoedelijk niet spontaan te jubelen van geluk, als eerst tien keer de Tab-toets moet worden ingedrukt. Daarom wordt bij het de eerste keer indrukken van de Tab-toets een zogenaamde skip-link zichtbaar. Hiermee kan in één keer naar de tekst worden gegaan, zonder dat je eerste alle pop-ups moet langslopen. Bij het nogmaals indrukken van de Tab-toets verdwijnt deze skip-link weer, zodat deze de lay-out van de pagina niet verstoort.

Bij het openen van de pop-ups is een kleine vertraging van 0,4 seconde aangebracht. Deze is niet storend bij hoveren of aanraken, maar is wel uiterst storend bij gebruik van de Tab-toets. Door de kleine vertraging denk je denk steeds dat de Tab-toets niet goed is ingedrukt. Daarom worden de afbeeldingen bij gebruik van de Tab-toets op een andere manier op het scherm gezet, dan bij hoveren of aanraken. Hierdoor kan de vertraging bij gebruik van de Tab-toets worden omzeild..

Omdat de <span>'s verder leeg zijn, hebben deze geen enkele mogelijk storende invloed op touchscreens.

Voor iOS is een minieme hoeveelheid JavaScript gebruikt, omdat de pop-ups daarin anders lastig zijn te sluiten. (Applefans beginnen dan altijd te roepen dat dit geen probleem, maar een 'feature' is.)

Dan zijn er verder nog wat dingen, om het er wat netter uit te laten zien en zo. En in smalle browservensters staan de twee afbeeldingen niet naast elkaar, maar onder elkaar. Dit komt allemaal bij de bespreking van de code aan de orde.

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.

In dit voorbeeld wordt transition-delay gebruikt.

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.

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.

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.

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.

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

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" niet gebruikt.

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 gebruikt bij de <span>'s die gelijk boven de geneste <div>'s staan:

<span tabindex="0"></span>

Door de toevoeging van tabindex="0" kan de <span> focus krijgen bij gebruik van de Tab-toets, terwijl een <span> dat normaal genomen niet kan krijgen. Door als selector iets als span:focus + #li-mid te gebruiken, kan de pop-up nu worden geopend, als de <span> focus heeft. Waarmee de pop-up ook is te openen door gebruikers van de Tab-toets.

Als elders op de pagina nog een tabindex wordt gebruikt, kan een tabindex="0" problemen geven met de volgorde, zoals iets hierboven beschreven. Op de site zelf, waar ook knoppen voor navigatie op de site aanwezig zijn, gaat het goed. Geen enkele knop heeft daar een tabindex, waardoor in alle browsers eerst de navigatieknoppen en dan pas de <span>'s met de tabindex worden bezocht. Precies zoals de bedoeling is. Maar als je wel een tabindex elders op de pagina gebruikt, moet je in zoveel mogelijk browsers op zoveel mogelijk systemen de volgorde bij gebruik van de Tab-toets controleren.

tabindex="..."

Op de plaats van de puntjes moet een positief getal worden ingevuld: het volgnummer. Positieve tabindexen worden hier 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.

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 internet Explorer 11 en Edge op een touchscreen.

iOS

Als :hover met :focus wordt gecombineerd op hetzelfde element, zijn daar op iOS vaak aanpassingen voor nodig. Deze combinatie komt in dit voorbeeld niet voor, dus daarvoor zijn geen speciale aanpassingen nodig.

Op iOS blijft :hover werken, tot een andere element dat focus kan krijgen wordt aangeraakt, of tot de pagina opnieuw wordt geopend. Daarom is een klein stukje JavaScript toegevoegd, zodat ook op iOS de pop-ups sluiten, als het scherm ergens buiten de pop-ups wordt aangeraakt. Meer hierover bij JavaScript.

Internet Explorer 11 en Edge op touchscreens

Op touchscreens in Windows en Windows Phone openen de pop-ups pas na langdurige aanraking, en soms zelfs helemaal niet. Soms opent het contextuele menu. (Hier zit vast enige regelmaat in, maar daar heb ik verder niet naar gezocht.) Door het toevoegen van aria-haspopup="true" aan de buitenste <div>, openen de pop-ups ook goed in Internet Explorer en Edge op touchscreens:

<div id="li-bui" aria-haspopup="true">

Eigenaardig genoeg hoeft alleen aan de buitenste <div> dit attribuut te worden toegevoegd. Je zou verwachten dat dit bij élke <div>, waarbinnen een pop-up zit, moet worden toegevoegd. Maar als je het alleen aan de buitenste <div> toevoegt, openen de pop-ups in álle <div>'s.

Dit attribuut is eigenlijk een zogenaamde WAI-ARIA-code. Dit is een uitgebreide serie codes, bedoeld voor schermlezers. Volgens de specificatie 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.

Als het echter, zoals hier, bij een <div< wordt gebruikt, negeren schermlezers het. Mogelijk wordt in de toekomst de specificatie aangepast, zodat dit attribuut in de toekomst niet alleen meer voor menu's is bedoeld.

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

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'. (Over het gebruik van de Tab-toets staat meer bij Tabindex en Tab-toets.)

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

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. In dit voorbeeld is er helemaal geen kadertje, omdat de focus op andere manieren wordt aangegeven: de pop-up is dan geopend.

Als :hover met :focus wordt gecombineerd op hetzelfde element, zijn daar op iOS vaak aanpassingen voor nodig. Deze combinatie komt in dit voorbeeld niet voor, dus er zijn geen speciale aanpassingen voor iOS nodig. Ook voor andere touchscreens zijn geen aanpassingen nodig.

In dit voorbeeld zijn voor gebruikers van de Tab-toets <span>'s aangebracht met het attribuut tabindex="0". Hierdoor kunnen de <span>'s focus krijgen, wat normaal genomen niet zo is, zodat de pop-ups ook openen bij gebruik van de Tab-toets. Meer daarover is te vinden bij Tabindex en Tab-toets.

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

:active wordt hier 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

Getest in

Laatst gecontroleerd op 28 maart 2016

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:

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

Ik maak één uitzondering: Android browser. Omdat Android vaak niet geüpdatet kan worden, test ik ook nog in oudere versies van Android browser.

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

Er is getest met behulp van muis en toetsenbord, behalve op de iPad, Android en Windows Phone, 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.

Op de desktop is ook getest, als JavaScript uitstaat. Eventuele problemen staan hierboven bij Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld. (Op iOS, Android en Windows Phone 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.)

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

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 in combinatie met Firefox op Windows 7.

TalkBack is een in Android ingebouwde schermlezer. Er is getest in combinatie met Chrome.

VoiceOver is een in iOS en OS X ingebouwde schermlezer. Er is getest in combinatie met Safari op iOS en OS X.

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

Bekende problemen (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.

Internet Explorer 9 en 10

Internet Explorer 9 en 10 kennen transition-delay niet. Hierdoor is er geen vertraging van 0,4 seconde bij het openen van de pop-ups door middel van hoveren of aanraken. Dit is geen probleem, omdat deze vertraging alleen nodig is op touchscreens. En deze fossielen zullen niet vaak worden gebruikt op een touchscreen.

Pop-ups sluiten niet op iOS

Apple heeft de mensheid verblijd met nogal wat eigenaardigheden, die door de echte Applefan trouwhartig als verbetering worden gezien. Om de pop-ups op iOS te kunnen sluiten, is een klein beetje JavaScript nodig. Meer daarover is te vinden bij JavaScript. Door dit JavaScript te gebruiken, kan ook op iOS de pop-up worden gesloten door aanraking van het scherm op een willekeurige plaats (maar wel buiten de pop-ups).

Dit JavaScript is aan <body> gekoppeld: het werkt alleen als het venster binnen <body> wordt aangeraakt. Als er nou heel weinig inhoud is op de pagina, kan <body> mogelijk lager zijn dan het venster van de browser. In dat geval sluiten de pop-ups niet, als het scherm onder <body> wordt aangeraakt.

Dit kan worden opgelost door de volgende css toe te voegen:

html {min-height: 100%;}

body {min-height: 100%;}

Nu is <body> altijd minimaal even hoog als het venster van de browser. Bij tablets en mobieltjes zal dat meestal ook de hoogte van het scherm zijn, waardoor de pop-ups nu altijd sluiten, ongeacht waar het scherm wordt aangeraakt.

UC browser op Android opent image viewer in plaats van pop-up

Op sommige touchscreens opent UC browser bij aanraking van de afbeelding gelijk de zogenaamde image viewer: de afbeelding wordt groot getoond. Deze viewer hoort pas na een iets langere aanraking van een afbeelding te worden geopend. Als wordt teruggegaan naar het normale scherm, werkt het daarna meestal wel, zoals het is bedoeld: de pop-ups openen, en niet de image viewer.

Dit is een bug in UC browser. Het voor iOS gebruikte stukje JavaScript, blijkt ook deze bug in UC browser op te lossen. Meer over dit script bij JavaScript.

Wijzigingen

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

:

Nieuw opgenomen.

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-109-dl.html: de pagina met het voorbeeld.

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

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

109-css-dl:

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

menu-019-hulp-dl.css: stylesheet voor pagina's in 019-files.

109-pics:

De 12 in het voorbeeld gebruikte afbeeldingen.

De afbeeldingen aan de linkerkant zijn afkomstig van clker.com (dit zijn 'huis.jpg', 'kamer.jpg', 'kast.jpg', 'kistje.jpg', 'la.jpg' en 'ring.jpg'). Deze afbeeldingen zijn, waar nodig, voorzien van een witte achtergrond, en de afmetingen zijn aangepast.

De afbeeldingen aan de rechterkant zijn afkomstig van PD Photo.org (dit zijn 'blue-stilton-kaas.jpg', 'brie.jpg', 'diverse-soorten-kaas.jpg', 'mozzarella.jpg', 'pecorino-sardo-kaas.jpg' en 'stravecchio-parmezaanse-kaas.jpg'). Waar nodig zijn de afmetingen van deze afbeeldingen aangepast.

Alle afbeeldingen vallen onder het publieke domein en mogen dus vrij 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, enz., maar dan moet je waarschijnlijk heel erg lang wachten.

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

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

Nieuwe sites of pagina's kunnen echter wel rekening houden met de veel kleinere vensters van mobiele apparaten. Op deze pagina bijvoorbeeld worden knoppen, pop-ups, enz. volledig aangepast aan de grootte van 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.

<div id="li-bui" aria-haspopup="true">

In Internet Explorer 11 en Edge op touchscreens, openen de pop-ups bij aanraking niet. Of ze openen pas na een hele tijd. Of het contextuele menu wordt geopend. Kortom: enorme kommer en kwel. Door het toevoegen van aria-haspopup="true" openen de pop-ups gewoon.

Dit attribuut is eigenlijk een zogenaamde WAI-ARIA-code. Dit is een uitgebreide serie codes, bedoeld voor schermlezers. Met aria-haspopup="true" kan 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.

Als het echter, zoals hier, bij een <div> wordt gebruikt, negeren schermlezers het. Mogelijk wordt in de toekomst de specificatie aangepast, zodat dit attribuut in de toekomst niet alleen meer voor menu's is bedoeld.

<span tabindex="0"></span>

Deze <span>'s zijn speciaal voor gebruikers van de Tab-toets toegevoegd, zodat ook bij gebruik van de Tab-toets de pop-ups kunnen worden geopend. Normaal genomen negeert de Tab-toets een <span>, maar door het toevoegen van tabindex="0" kan de <span> toch focus krijgen bij gebruik van de Tab-toets.

Door in de css een selector als span:focus + #li-mid-bui te gebruiken, kan div#li-mid-bui (en dus de daarin zittende afbeelding) worden getoond, als de <span> voor die <div> focus heeft.

<p id="tekst" lang="la">Lorem ipsum dolor sit amet,

Met <html lang="nl"> bovenaan de pagina wordt aangegeven 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.

De tekst onder de afbeeldingen is echter in het Latijn. Met lang="la" wordt dit aangegeven. (En tot mijn niet geringe verbazing blijkt een schermlezer als NVDA dit dan – voor zover ik dat kan beoordelen – correct te kunnen voorlezen.)

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, enz., 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 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-109-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 kleur 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;

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

margin: 0; padding: 0;

Verschillende browsers hebben verschillende standaard-instellingen hiervoor. Door ze gewoon op 0 te zetten, zijn ze overal hetzelfde.

#skippy

Afbeelding 2: skip-link

Het element met id="skippy". Dit is een zogenaamde skip-link. Het geeft aan gebruikers van de Tab-toets de mogelijkheid in één keer naar de tekst onder de pop-ups te gaan, zonder dat deze eerst alle tien pop-ups geopend moeten worden.

Sommige mensen kunnen (of willen) de muis niet gebruiken. Met behulp van de Tab-toets of een soortgelijke toets kun je één voor één alle links, tekstvelden, en dergelijke op een pagina aflopen. <div>'s, <span>'s en dergelijke worden normaal genomen genegeerd door de Tab-toets, maar door het toevoegen van tabindex="0" kan ook dit soort elementen focus krijgen.

In dit voorbeeld is, gelijk voor elke <div> met een pop-up, een <span> aangebracht. Door in de css een selector als span:focus + #li-mid-bui te gebruiken, kan de op de <span> volgende <div> – en dus de erin zittende afbeelding – worden getoond. Hierdoor kunnen ook gebruikers van de Tab-toets de pop-ups zien.

Er is alleen één probleempje: als de gebruiker van de Tab-toets die pop-ups helemaal niet wíl zien, moet de gebruiker toch eerst tien keer de Tab-toets indrukken om door die pop-ups heen te tabben. Dit kan leiden tot taalgebruik, waar de Bond Tegen het Vloeken ernstig bezwaar tegen maakt. Zeker als zoiets bijvoorbeeld bovenaan elke pagina wordt herhaald, of als er driehonderd pop-ups zijn.

Voor de gemoedsrust van deze mensen wordt daarom gelijk boven de pop-ups een zogenaamde skip-link neergezet. De hierboven afgebeelde skip-link zie je normaal genomen niet, omdat hij met behulp van css ver links buiten het scherm wordt geparkeerd. Maar ook al zie je hem niet, hij is er wel. En wordt dus door de Tab-toets gewoon gezien.

Bij het begin van de tekst onder de afbeeldingen staat het anker, waarnaar wordt gelinkt:

<p id="tekst" lang="la">

Als je de Tab-toets gebruikt, is de skip-link de eerste link die focus krijgt. Zodra de link focus heeft, wordt hij duidelijk zichtbaar op het scherm gezet. En omdat hij groot is en 'n knalrode rand heeft en zo, is hij vrijwel niet te missen. Als je nu op Enter drukt, wordt de link gevolgd: je passeert met één toetsindruk alle pop-ups.

Deze link is natuurlijk absoluut foeilelijk. En dat is precies de bedoeling: nu valt hij goed op. Zodra je nog 'n keer op de Tab-toets drukt, heeft de link geen focus meer en verdwijnt weer links buiten het scherm. Hij verpest dus niet de hele pagina, want hij is alleen maar zichtbaar als mensen de Tab-toets gebruiken. En precies voor die mensen is de link bedoeld.

background: white;

Witte achtergrond.

width: 360px;

Breedte.

max-width: 100%;

De kans dat deze skip-link in een heel smal browservenster (smaller dan de hierboven opgegeven breedte van 360 px) verschijnt, is heel klein. Maar het kan geen kwaad voor de zekerheid de maximumbreedte te beperken.

Een breedte in procenten is altijd ten opzichte van de ouder van het element. Dat is hier <body>, een blok-element. Een blok-element wordt normaal genomen automatisch even breed als z'n ouder: het blok-element <html>. Ook aan <html> is geen breedte opgegeven, dus ook <html> wordt even breed als z'n ouder. Omdat <html> geen ouder heeft, wordt <html> automatisch even breed als het venster van de browser.

De skip-link kan nu dus nooit breder worden dan het venster van de browser. (Dat klopt niet helemaal, want bij de breedte komt links en rechts nog de iets hieronder opgegeven border van 3 px, dus de breedte wordt maximaal 100% + 6 px. Maar het lijkt me dat de uiterst minieme kans op het verlies van 6 px niet direct zal leiden tot een bloedige revolutie, dus ik vind het wel prima zo. (Als je daar toch problemen mee hebt, heb ik nog slecht één ding te zeggen: "Kssst, gaat henen, liefhebber van ontuchtige handelingen met mieren.")

line-height: 5em;

Regelhoogte. Omdat geen hoogte is opgegeven, is dit ook gelijk de hoogte van de hele <a>.

Standaard wordt tekst halverwege de regelhoogte neergezet. Hierdoor komt de tekst netjes verticaal in het midden te staan.

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

text-align: center;

Tekst horizontaal centreren.

margin-left: -183px;

Iets hierboven is een breedte van 360 px opgegeven. Hier iets onder wordt de <a> absoluut gepositioneerd. Als de link getoond moet worden, wordt deze bij #skippy:focus halverwege het venster van de browser neergezet. Als de <a> 183 px naar links wordt teruggezet, staat de link hierdoor altijd horizontaal gecentreerd in het venster.

(183 px en geen 180 px, omdat er links en rechts ook een border van 3 px is.)

border: red solid 3px;

Rood randje.

position: absolute;

Om de <a> 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. Hierdoor kunnen eigenschappen als breedte niet worden gebruikt. Door de <a> absoluut te positioneren, verandert deze in een soort blok-element, waardoor dit soort eigenschappen wel gebruikt kan worden.

top: 30px;

Op 30 px vanaf de bovenkant zetten.

left: -20000px;

Links buiten het scherm parkeren. Om de link zichtbaar te maken, hoeft deze alleen maar binnen het scherm te worden geplaatst.

z-index: 10;

De link moet altijd zichtbaar zijn, dus voor de zekerheid een iets hogere z-index geven. Een z-index werkt alleen in sommige omstandigheden, zoals bij een absolute positie. Die is hierboven gegeven, dus dat is geregeld.

#skippy: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.

#skippy {background: white; width: 360px; max-width: 100%; line-height: 5em; text-align: center; margin-left: -183px; border: red solid 3px; position: absolute; top: 30px; left: -20000px; z-index: 10;}

Als het element met id="skippy" focus heeft. Als door het indrukken van de Tab-toets de skip-link is bereikt.

De hele opmaak van de skip-link is gelijk hierboven al opgegeven. Hier hoeft de skip-link alleen nog zichtbaar te worden gemaakt.

left: 50%;

Halverwege het venster van de browser neerzetten, zodat de skip-link zichtbaar wordt. Als de Tab-toets nogmaals wordt ingedrukt, heeft de <a> geen focus meer en geldt weer de eerder bij #skippy opgegeven left: -20000px;. Hierdoor wordt de skip-link weer links buiten het scherm geparkeerd en daarmee onzichtbaar.

h1

Alle <h1>'s. Dat is er maar eentje: de belangrijkste kopregel.

font-size: 1em;

Van zichzelf heeft een <h1> een veel grotere letter. Hier wordt dat veranderd in 'n normale lettergrootte.

Als eenheid wordt de relatieve eenheid em 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.

text-align: center;

Tekst horizontaal centreren.

main

Alle <main>'s. Dat is er maar eentje: het element waarin de belangrijkste inhoud van de pagina staat.

display: block;

<main> is een blok-element, maar oudere browsers kennen <main> niet. Onbekende elementen worden automatisch een inline-element. Hier wordt dat gecorrigeerd.

width: 360px;

Breedte.

max-width: 90%;

Maximumbreedte.

Een breedte in procenten wordt altijd genomen ten opzichte van de ouder van het element. Dat is hier het blok-element <body>. Een blok-element wordt normaal genomen even breed als z'n ouder, het blok-element <html>. Omdat <html> geen ouder heeft, wordt <html> normaal genomen even breed als het venster van de browser.

<main> wordt dus nooit breder dan 90% van de breedte van het venster van de browser. Hierdoor blijft er links en rechts van de afbeeldingen altijd ruimte vrij, ook in browservensters smaller dan de hierboven opgegeven breedte van 360 px Als die vrije ruimte wordt aangeraakt, worden de pop-ups weer gesloten. Zonder deze vrije ruimte kan het erg lastig zijn de pop-ups weer te sluiten.

margin: 0 auto;

Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarden als boven en rechts. Hier staat dus eigenlijk 0 auto 0 auto in de volgorde boven – rechts – onder – links. Onder en boven geen marge, links en rechts auto, wat hier hetzelfde betekent als evenveel. <main> staat dus altijd horizontaal gecentreerd, ongeacht de breedte van het venster van de browser.

div

Alle <div>'s.

max-width: 100%;

Elke <div> krijgt verderop een breedte die past bij de grootte van de erin zittende afbeelding.

Hier gelijk boven heeft <main>, waar alle <div>'s in zitten, een breedte van 360 px gekregen en een maximumbreedte van 90%. In een heel smal browservenster van bijvoorbeeld 300 px breed, wordt de breedte van <main> 90% van die 300 px: 270 px.

Een breedte in procenten wordt altijd genomen ten opzichte van de ouder. Voor de buitenste <div> is dat <main>. De buitenste <div> krijgt hieronder een breedte van 360 px. Waarmee die dus in een smal venster breder zou worden dan <main> en daarmee – samen met de erin zittende <img> – gedeeltelijk buiten het venster zou komen te staan.

(Standaard worden ook dingen die niet in het element passen weergegeven. Dat is meestal ook wat je wilt: mogelijk wordt de lay-out verstoord, maar er verdwijnt geen tekst of zo.)

Door de maximumbreedte te beperken tot 100%, kan de buitenste <div> nooit breder worden dan <main>, en blijft dus altijd de in de buitenste <div> zittende afbeelding volledig zichtbaar.

Hetzelfde verhaal geldt voor de geneste <div>'s. De een een-na-buitenste <div> krijgt iets hieronder een breedte van 300 px. Als de buitenste <div> smaller zou worden dan die 300 px, zou een deel van de afbeelding in de een-na-buitenste <div> daarbuiten komen te vallen. Maar ook voor die een-na-buitenste <div> geld dat die niet breder kan worden dan 100% van z'n ouder: de buitenste <div>.

Dit geldt voor alle <div>'s: ze kunnen nooit breder worden dan hun ouder, de <div> waar ze in zitten. (Voor de buitenste <div> is de ouder <main>.)

margin: auto;

Aan alle kanten een marge van auto, wat hier betekent: evenveel. Oftewel: horizontaal en verticaal gecentreerd, ongeacht hoe breed of hoog de ouder van de <div> is.

Deze manier van horizontaal centreren van een blok-element werkt alleen, als het blok-element een breedte heeft gekregen. Elke <div> krijgt verderop een eigen breedte, dus dat is geregeld.

Maar dan doet zich een probleem voor: deze simpele truc om horizontaal te centreren werkt niet, als het element absoluut is gepositioneerd, wat gelijk hieronder gebeurt. En mogelijk heb je ook al opgemerkt dat ik het verticaal centreren kennelijk maar helemaal ben vergeten.

Verticaal centreren werkt normaal genomen hoe dan ook niet met deze simpele truc. Maar als je het element absoluut positioneert, is er een weinig bekende andere truc, en die werkt voor horizontaal én verticaal centreren. Als je onmogelijke maten opgeeft, besluit de browser kennelijk uit pure wanhoop het element te centreren, verticaal én horizontaal.

Als voorbeeld de een-na-buitenste <div>. (Het werkt voor alle <div>'s op precies dezelfde manier, alleen verschillen breedte en hoogte.)

De een-na-buitenste <div> wordt iets hieronder 300 px breed en 300 px hoog gemaakt. Gelijk hieronder wordt de <div> absoluut gepositioneerd met top: 0; right: 0; en bottom: 0;. Zodra de <div> getoond moet worden, komt daar ook nog left: 0; bij. Bij het tonen van de <div> hebben top, right, bottom en left dus alle vier de waarde '0'.

De een-na-buitenste <div> wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Dat is hier de buitenste <div>. De een-na-buitenste <div>, die 300 px breed en hoog is, wordt dus op 0 px afstand van alle kanten van de buitenste <div> gezet, die iets hieronder 360 px breed en hoog wordt gemaakt.

Een <div> van 300 px breed en hoog aan alle kanten op 0 px afstand van een <div> van 360 px breed en hoog neerzetten, is gewoon onmogelijk zonder vierendelen, oprekken op de pijnbank, of andere methodes die weinig met css te maken hebben en hoe dan ook verwerpelijk zijn.

Als een element absoluut is gepositioneerd én right en left hebben beide een andere waarde dan de standaardwaarde auto én het element heeft een breedte én margin-left en margin-right hebben beide de waarde auto, dan worden de marges links en rechts even groot. Oftewel: het element wordt horizontaal gecentreerd.

Hetzelfde geldt voor de hoogte: als een element absoluut is gepositioneerd én top en bottom hebben beide een andere waarde dan de standaardwaarde auto én het element heeft een hoogte én margin-top en margin-bottom hebben beide de waarde auto, dan wordt worden de marges boven en onder even groot. Oftewel: het element wordt verticaal gecentreerd. (Het grappige is dat verticaal centreren van een blok-element normaal genomen vaak nogal lastig is, maar niet met deze truc.)

Met een paar regels css worden nu alle <div>'s, en dus ook de daarin zittende afbeeldingen, horizontaal en verticaal gecentreerd, zonder dat het nodig is voor elke <div> een precieze positie op te geven.

(In browservensters smaller dan ongeveer 400 px wordt niet verticaal gecentreerd, maar dat heeft een reden die niet met het hierboven staande te maken heeft: de afbeeldingen zouden anders kleiner worden dan nodig is. Meer hierover bij max-width: 100%;.)

position: absolute;

De <div>'s – met de daarin zittende afbeelding – worden bij div div met left: -20000px; links buiten het scherm geparkeerd, zodat ze onzichtbaar zijn. (Omdat het bij de daar gebruikte selector div div om <div>'s binnen een <div> gaat, geldt dit niet voor de buitenste <div>. Die is gewoon altijd zichtbaar.) Om left te kunnen gebruiken, moet er een (absolute) positie aanwezig zijn.

Je zou de <div>'s ook op andere manieren buiten het scherm kunnen parkeren, maar absoluut positioneren is ook bruikbaar voor verticaal en horizontaal centreren. Daarom is in dit geval voor deze methode gekozen. Hoe dat centreren precies werkt, staat hierboven bij margin: auto;.

Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Behalve de buitenste <div> staat elke <div> zelf weer in een andere <div>. Omdat elke <div> een positie heeft, wordt – behalve de buitenste <div> – elke <div> dus gepositioneerd ten opzichte van de <div>, waarbinnen hij staat.

Bij #li-bui, #re-bui wordt voor de buitenste <div> de absolute positie veranderd in een relatieve, dus voor de buitenste <div> geldt dit hele verhaal niet.

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

Normaal genomen worden de <div>'s helemaal bovenaan én helemaal onderaan neergezet, en helemaal rechts. Helemaal onderaan én helemaal bovenaan is onmogelijk, omdat elke <div> kleiner is dan z'n ouder. Dit is een truc om de <div>'s horizontaal en verticaal te centreren. Hoe dat precies werkt, is hierboven bij margin: auto; beschreven.

img

Alle afbeeldingen. Dit zijn de afbeeldingen die binnen de pop-ups staan, en de twee afbeeldingen die al gelijk bij openen van de pagina zichtbaar zijn.

box-sizing: border-box;

Hieronder wordt een border van 1 px aan de afbeeldingen gegeven. Normaal genomen wordt die bij de breedte van de afbeelding opgeteld. Hier gelijk onder wordt een maximumbreedte van 100% aan de afbeeldingen gegeven. De totale maximumbreedte zou dan 100% + 2 px worden. Oftewel: breder dan de <div> waar de afbeelding in staat.

Met deze regel wordt de border niet bij de breedte opgeteld, maar is de breedte altijd 100% en valt de border binnen die 100%.

(Dit is ook de reden voor de ietwat vreemde afmetingen van de afbeeldingen. De grootste is geen 360 x 360 px, maar 358 x 358 px. Als de border bij 358 px wordt opgeteld, vult de afbeelding precies de breedte van de <div> van 360 px. Ook bij alle andere afbeeldingen zijn breedte en hoogte om deze reden steeds 2 px minder dan die van de <div>, waar ze in staan.)

max-width: 100%;

Een breedte in procenten is altijd ten opzichte van de ouder van het element. Dat zijn hier de <div>'s. In principe zijn de <div>'s precies groot genoeg voor de erin zittende afbeelding. Maar in heel smalle browservensters kunnen de <div>'s smaller worden dan de erin zittende afbeelding. Dit zorgt ervoor dat in die gevallen de afbeelding ook wordt versmald, zodat deze binnen de <div> blijft passen.

Omdat er geen hoogte wordt opgegeven, blijven de verhoudingen van de afbeelding intact. Als de breedte bijvoorbeeld 10% minder wordt, wordt ook de hoogte automatisch 10% minder. Hierdoor wordt een lachspiegel-effect voorkomen.

Afbeelding 3: een-na-buitenste pop-up is te hoog

Bij div hebben alle <div>'s een maximumbreedte van 100% gekregen. Een breedte in procenten is altijd ten opzichte van de ouder. De een-na-buitenste <div> is 300 px breed. In smalle browservensters kan het hierdoor voorkomen dat de een-na-buitenste <div> de hele buitenste <div> vult. Die buitenste <div> is normaal genomen 360 px breed, maar in smalle vensters wordt dat minder.

Op de afbeelding is de een-na-buitenste pop-up geopend in een tamelijk smal browservenster. De een-na-buitenste pop-up vult nog niet de hele breedte van de buitenste pop-up, maar al wel meer dan het geval is in een breder browservenster.

Omdat geen hoogte is opgegeven, komt de onderkant van de een-na-buitenste <div> (en dus van de daarin zittende afbeelding) hier iets onder de buitenste <div> te staan, waardoor deze verticaal niet meer gecentreerd is.

Dit kan vrij simpel worden voorkomen door de afbeelding te verkleinen. Maar dan wordt de afbeelding in de een-na-buitenste <div> (en in de daar weer in zittende <div>'s) kleiner dan nodig is. In dit geval vind ik het centreren minder belangrijk dan een iets grotere afbeelding.

border: black solid 1px;

Randje rondom de afbeelding.

position: absolute; Afbeelding 4: een-na-buitenste pop-up staat niet op, maar onder afbeelding

Bij hoveren of aanraken heeft deze absolute positie geen enkele invloed. Ook als je het weglaat, werkt alles zoals het hoort te werken. Maar als de pop-up wordt geopend met gebruik van de Tab-toets, dus door het geven van focus aan de voor de Tab-toets aangebrachte <span>, komt de afbeelding in de pop-up niet over, maar ónder de oorspronkelijke afbeelding te staan. Op de afbeelding is de een-na-buitenste pop-up te zien, maar het geldt voor alle pop-ups.

(De opening tussen de onderste en bovenste afbeelding is de margin-top: 30px; die bij span:focus + div img aan de <img> wordt gegeven.)

Als een <span> focus krijgt, wordt de absolute positie van de op die <span> volgende <div> veranderd in een statische positie, de standaardwaarde. Dat betekent onder andere dat de <div> nu op z'n normale plaats komt te staan, en niet op de plaats die met behulp van top en dergelijke wordt bepaald, want die werken niet meer bij gebrek aan een absolute positie.

En dan gebeurt er iets vreemds.

De afbeeldingen uit de pop-ups zijn weliswaar niet te zien, maar ze zijn wel aanwezig. Dat ze links buiten het scherm staan, maakt geen verschil voor de positie van andere elementen. De normale plaats van de <div> die in de html op een <img> volgt, is ónder die <img>. Dat is precies wat er op de afbeelding gebeurt: de een-na-buitenste <div> staat tegen de onderkant van de afbeelding uit de buitenste <div> aan.

De volgende pop-up staat tegen de onderkant van de afbeelding in de een-na-buitenste <div> aan enz.

Door de afbeeldingen absoluut te positioneren, worden ze uit de normale weergave gehaald en hebben geen invloed meer op de plaats van andere elementen. Hierdoor staat de <div> weer op de plaats, waar hij hoort te staan: bovenin de voorafgaande <div>.

#li-bui, #re-bui

Voor deze elementen 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.

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

De elementen met id="li-bui" en id="re-bui". Dit zijn de twee buitenste <div>'s, waarbinnen de twee afbeeldingen staan die al bij openen van de pagina zijn te zien. 'li-bui' is de linker-<div>, 're-bui' is de rechter‑<div>.

width: 360px; height: 360px;

De afbeelding in de buitenste <div> is 360 x 360 px. Als de buitenste <div> op de juiste plaats staat, staat de afbeelding daar dus ook op.

(Feitelijk is de afbeelding 358 x 358 px, maar daar komt nog een border van 1 px bij.)

margin-top: 10px;

Bij de buitenste <div>'s kleine marge aan de bovenkant voor wat afstand tot de bovenkant van het browservenster.

position: relative;

Bij div zijn alle <div>'s absoluut gepositioneerd. Dat is handig voor de <div>'s met pop-ups, maar deze twee buitenste <div>'s worden dan verkeerd geplaatst. Bovendien komen ze over elkaar heen te staan, omdat absolute elementen niet meetellen voor de plaats van andere elementen. Hierdoor komt de tweede <div> vrolijk over de eerste heen te staan. Kortom: weg met die absolute positie.

De <div>'s binnen deze buitenste <div>'s moeten echter wel gepositioneerd kunnen worden ten opzichte van deze buitenste <div>'s. Dat kan alleen, als deze <div> zelf een positie heeft. Een relatieve positie is daarvoor prima geschikt, zonder dat alle bijwerkingen van een absolute positie optreden.

Omdat er verder niets bij top en dergelijke wordt opgegeven, heeft dit verder geen enkele invloed op de buitenste <div>'s zelf.

#li-mid-bui, #re-mid-bui

Voor deze elementen 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.

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

De elementen met id="li-mid-bui" en id="re-mid-bui". Dit zijn de twee een-na-buitenste <div>'s. 'li-mid-buit' is de linker, 're-mid-bui' is de rechter.

width: 300px; height: 300px;

De op een-na-buitenste <div>. De hierin zittende afbeelding is 298 x 298 px. Samen met een border van 1 px is dat 300 px. De afbeelding past hierdoor precies binnen deze <div>. Als de <div> op de juiste plaats staat, staat daardoor ook de afbeelding op de juiste plaats.

#li-mid, #re-mid

{width: 240px; height: 240px;} #li-mid-bin, #re-mid-bin {width: 180px; height: 180px;} #li-bin, #re-bin {width: 120px; height: 120px;} #li-kern, #re-kern {width: 60px; height: 60px;}

Voor deze elementen 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.

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

Dit zijn de meer naar binnen zittende <div>'s. Ze hebben elk de maat van de daarin zittende afbeeldingen met de om de afbeelding zittende border.

div div

Voor deze elementen 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.

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

#li-mid-bui, #re-mid-bui {width: 300px; height: 300px;}

#li-mid, #re-mid {width: 240px; height: 240px;}

#li-mid-bin, #re-mid-bin {width: 180px; height: 180px;}

#li-bin, #re-bin {width: 120px; height: 120px;}

#li-kern, #re-kern {width: 60px; height: 60px;}

Alle <div>'s die binnen een andere <div> zitten. Dat zijn alle <div>'s, behalve de buitenste. Het zijn de <div>'s die een pop-up bevatten.

left: -20000px;

De <div>'s – en daarmee de erin zittende afbeelding – links buiten het scherm parkeren. Als ze zichtbaar moeten worden, hoeven ze alleen maar binnen het scherm gepositioneerd te worden.

Je zou dit ook met behulp van display: none; kunnen doen, maar dan negeren schermlezers de <div>'s en alles wat daarin zit. Als ze buiten het scherm staan, worden ze gewoon voorgelezen door schermlezers, ook al zie je ze niet.

-webkit-transition-delay: 0.4s; transition-delay: 0.4s;

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

Hierboven zijn de <div>'s 20000px links buiten het scherm geparkeerd. Bij hoveren over of aanraken van de afbeelding worden ze bij div:hover > div met left: 0; weer binnen het scherm gezet.

Bij hoveren levert dat geen probleem op. Maar bij aanraken op een touchscreen wel. Als de eerste afbeelding in het midden wordt aangeraakt, moet de eerste pop-up openen. Pas bij aanraking van die eerste pop-up moet de tweede pop-up openen. Bij aanraking van de tweede pop-up moet de derde openen, enz.

Sommige touchscreens en/of browsers zijn zo gevoelig (of zo gammel, net hoe je 't wilt bekijken...) dat ze niet één, maar twee of zelfs gelijk alle pop-ups openen bij de eerste aanraking. Door een minieme vertraging in te bouwen, wordt dat voorkomen. Een vertraging van 0,4 seconde, de hier opgegeven vertraging, zorgt ervoor dat alle browsers slechts één pop-up per aanraking openen. Deze vertraging is zo klein dat hij nauwelijks storend is. Integendeel: bij hoveren voorkomt de kleine vertraging dat de pop-ups je om de oren vliegen, als je per ongeluk gelijk naar het midden van de eerste afbeelding gaat.

(Bij gebruik van de Tab-toets is deze kleine vertraging wel uiterst hinderlijk. Daarom wordt daarvoor een andere methode van openen gebruikt, zodat de vertraging wordt vermeden.)

Bij div:hover > div wordt left: 0; opgegeven. Hierboven is left: -20000px; opgegeven. transition-delay zorgt ervoor dat er een vertraging zit tussen de hierboven opgegeven positie van left: -20000px; zonder :hover , en de positie bij :hover van left: 0;. Die vertraging is hier 0.4s, 0,4 seconde. (Met een punt, want decimalen worden op de Amerikaanse manier aangegeven.)

Met transition is nog veel meer mogelijk, maar hier wordt alleen de sub-eigenschap transition-delay gebruikt.

Als er meerdere eigenschappen worden veranderd, maar ze moeten niet allemaal met behulp van transition veranderen, moet je de eigenschappen die onder transition vallen specifiek opgeven. In dit geval is de enige eigenschap die bij :hover verandert left. Er zijn dus geen eigenschappen die niet onder transition vallen, daarom hoeven hier geen eigenschappen opgegeven te worden.

p

Alle <p>'s.

padding: 0 5px;

Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 5px 0 5px in de volgorde boven – rechts – onder – links. Boven en onder geen padding, links en rechts 5 px afstand tussen de buitenkant van de <p> en de tekst erin.

div:hover > div

Voor deze elementen 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.

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

#li-mid-bui, #re-mid-bui {width: 300px; height: 300px;}

#li-mid, #re-mid {width: 240px; height: 240px;}

#li-mid-bin, #re-mid-bin {width: 180px; height: 180px;}

#li-bin, #re-bin {width: 120px; height: 120px;}

#li-kern, #re-kern {width: 60px; height: 60px;}

div div {left: -20000px; -webkit-transition-delay: 0.4s; transition-delay: 0.4s;}

De selector div:hover div zou betekenen: als over een <div> wordt gehoverd, doe dan iets met de daarbinnen zittende <div>'s. Álle binnen die <div> zittende <div>'s. Dat zou, in dit geval, betekenen dat bij hoveren over de buitenste <div> álle pop-ups in één keer worden geopend.

Dat is weliswaar een indrukwekkend gezicht, waar eigenlijk trompetgeschal en tromgeroffel bij zouden moeten klinken, maar het is – saai als ik ben – toch niet helemaal de bedoeling.

Daarom wordt een > toegevoegd. Dit zorgt ervoor dat het alleen voor de <div> geldt, die een direct kind is van de <div> waarover wordt gehoverd:

<div id="een"> <div id="twee"> <div id="drie"> </div> </div> </div>

div#twee is een direct kind van div#een. div#drie is dat niet. Bij hoveren over div#een geldt de selector div:hover > div wel voor div#twee, want dat is een direct kind van div#een, maar niet voor div#drie, want dat is geen direct kind: div#twee zit ertussen.

Bij hoveren over div#twee geldt de selector div:hover > div wel voor div#drie, want div#drie is een direct kind van div#twee.

left: 0;

Bij div div zijn alle <div>'s met een pop-up links buiten het scherm geparkeerd met left: -20000px;. Omdat het alleen om <div>'s binnen een andere <div>'s gaat, geldt dat niet voor de buitenste <div>. Maar wel voor alle andere, en dat zijn precies de <div>'s met de pop-ups. Die worden hier binnen het scherm gezet, en daarmee ook de erin zittende afbeelding.

span:focus + #li-mid-bui, span:focus + #re-mid-bui

Voor deze elementen 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.

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

#li-mid-bui, #re-mid-bui {width: 300px; height: 300px;}

div div {left: -20000px; -webkit-transition-delay: 0.4s; transition-delay: 0.4s;}

De eerste selector, voor de komma: span:focus + #li-mid-bui:

span: speciaal voor gebruikers van de Tab-toets zijn <span>'s aangebracht, waardoor ook met behulp van de Tab-toets de pop-ups geopend kunnen worden. Normaal genomen kan een <span> geen focus krijgen, maar door het aanbrengen van het attribuut tabindex="0" kan dat hier wel.

span:focus: als de <span> 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="li-mid-bui" of id="re-mid-bui", dat gelijk op een <span> volgt.

#li-mid-bui: het element met id="li-mid-bui". Dit is de een-na-buitenste linker-div, de <div> waarbinnen de eerste pop-up staat.

De tweede selector, achter de komma: span:focus + #re-mid-bui:

Deze is precies hetzelfde als de eerste selector, alleen gaat het hierbij om div#re-mid-bui: de een-na-buitenste <div> rechts.

Er is maar één div#li-mid-bui, en maar één div#re-mid-bui. De combinatie van een <span> direct gevolgd door een van deze <div>'s komt dus ook maar één keer voor. Deze selector werkt dus specifiek voor de twee een-na-buitenste <div>'s, niet voor andere <div>'s. Ook niet als die direct op een <span> volgen, want die andere <div>'s hebben een andere id.

position: static;

In het blokje bovenaan kun je zien dat eerder een absolute positie is opgegeven met een top, right, bottom en left. Als je de absolute positie verandert in een statische, de standaardwaarde, werken top, right, bottom en left niet meer. De <div> komt op de plaats, waar hij van zichzelf automatisch terecht komt.

Dat ruimt lekker op: met één verandering vijf eerdere opdrachten om zeep helpen. Feitelijk zes, want ook transition-delay werkt niet meer. Als left om zeep is geholpen, is er ook geen verandering van left meer om te vertragen.

Wat wel blijft werken is margin: auto;. Omdat maar één waarde is opgegeven, geldt deze voor alle vier de marges: boven, rechts, onder en links. Bij een marge wil auto zeggen: evenveel. Aan alle kanten een even grote marge, oftewel: gecentreerd.

Het op deze manier centreren van een blok-element werkt alleen, als het te centreren blok-element een breedte heeft. Dat is hier ook geregeld: de <div> is 300 px breed.

Helaas werkt deze simpele manier van centreren alleen in horizontale richting. Als een marge boven- of onderaan auto is, wordt dit normaal genomen vertaald naar '0'. De buitenste <div> is 360 px hoog. Deze <div> is slechts 300 px hoog. Als er onder‑ en bovenaan een marge van 0 px is, past dat niet. Je komt 60 px te kort. In dat geval 'wint' de marge bovenaan. En die is dus veranderd van auto naar 0 px, oftewel: de <div> staat helemaal bovenin de buitenste <div>. En daarmee de erin zittende afbeelding ook.

Om de afbeelding toch verticaal te centreren, wordt bij span:focus + div img aan de bovenkant van de <img> een marge van 30 px toegevoegd.

span:focus + #li-mid, span:focus + #re-mid

Voor deze elementen 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.

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

#li-mid, #re-mid {width: 240px; height: 240px;}

div div {left: -20000px; -webkit-transition-delay: 0.4s; transition-delay: 0.4s;}

De eerste selector, voor de komma: span:focus + #li-mid:

span: speciaal voor gebruikers van de Tab-toets zijn <span>'s aangebracht, waardoor ook met behulp van de Tab-toets de pop-ups geopend kunnen worden. Normaal genomen kan een <span> geen focus krijgen, maar door het aanbrengen van het attribuut tabindex="0" kan dat hier wel.

span:focus: als de <span> 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="li-mid" of id="re-mid", dat gelijk op een <span> volgt.

#li-mid: het element met id="li-mid". Dit is de twee-na-buitenste linker-div, de <div> waarbinnen de tweede pop-up staat.

De tweede selector, achter de komma: span:focus + #li-mid:

Deze is precies hetzelfde als de eerste selector, alleen gaat het hierbij om div#re-mid: de twee-na-buitenste <div> rechts.

Er is maar één div#li-mid, en maar één div#re-mid. De combinatie van een <span> direct gevolgd door een van deze <div>'s komt dus ook maar één keer voor. Deze selector werkt dus specifiek voor beide twee-na-buitenste <div>'s, niet voor andere <div>'s. Ook niet als die direct op een <span> volgen, want die andere <div>'s hebben een andere id.

margin-left: 10030px;

De <div>'s met de afbeeldingen zijn bij div div links buiten het scherm geparkeerd met left: -20000px;. Bij hoveren en aanraken wordt dat bij div:hover > div veranderd in left: 0;, waarmee de <div> – met de daarin zittende afbeelding – zichtbaar wordt. Om dat op alle touchscreens in alle browsers goed te laten werken, is bij het zichtbaar worden een vertraging van 0,4 seconde ingebouwd. Die vertraging is niet storend bij aanraken of hoveren, maar wel bij openen met behulp van de Tab-toets. Zelfs een kleine vertraging van 0,4 seconde laat je steeds denken dat de toets niet goed is ingedrukt of zoiets. Daarom moet bij gebruik van de Tab-toets de pop-up openen zonder vertraging.

De bij left opgegeven vertraging is niet uit te schakelen. Als die bij :hover werkt, werkt die ook bij :focus (en :active, en ...). Daarom wordt left niet gebruikt bij de Tab-toets. Hier gelijk onder wordt de absolute positie veranderd in een statische, de standaardwaarde. Hierdoor is left (en top, right en bottom) ook gelijk uitgeschakeld.

Deze <div> wordt met behulp van een hele grote linkermarge op het scherm gezet. Omdat bij het veranderen van die linkermarge geen vertraging is ingebouwd, wordt de <div> gelijk zichtbaar bij het indrukken van de Tab-toets: floep, daar staat de pop-up (die dus eigenlijk helemaal geen pop-up is, maar een <div> die al die tijd al stiekem klaarstond in de coulissen links).

De een-na-buitenste <div>, de ouder van deze <div>, is met left: -20000px; buiten het scherm gezet. Je zou dus denken dat je een linkermarge van ook ongeveer 20000 px moet gebruiken om deze <div> binnen het scherm te krijgen. Dat blijkt niet zo te zijn. Bij een marge van 10030 px staat de <div> precies horizontaal gecentreerd in z'n ouder, met links en rechts een marge van 30 px.

De <div>'s zijn horizontaal gecentreerd met een wat onbekende truc, die bij margin: auto; wordt beschreven. Kennelijk heeft de daar beschreven methode ook invloed bij positioneren buiten het venster van de browser. Bij een linkermarge van 10000 px staat de linkerkant van de <div> precies tegen de linkerkant van de een-na-buitenste <div>, dus het lijkt erop dat de left: -20000px; wordt gehalveerd, maar zeker weet ik dat niet. En het is heel erg moeilijk (of onmogelijk) hier betrouwbare informatie over te vinden. Of in ieder geval kost dat onwijs veel tijd. Deze waarde heb ik gekregen door het gewoon uit te proberen. En het werkt in alle browsers, en daar gaat het om.

(Zoals ik de specificatie lees, is alleen van belang dat bij left en right een andere waarde dan auto is opgegeven, om de marge links en rechts even groot te krijgen. Maar kennelijk is dit zo geïmplementeerd in browsers, dat de waarde wel degelijk meetelt. Bij een andere waarde dan left: -20000px; wordt de benodigde linkermarge steeds de helft van de waarde bij left. Mogelijk lees ik de specificatie verkeerd, of hebben browsermakers het op een meer logische manier geïmplementeerd.)

position: static;

In het blokje bovenaan kun je zien dat eerder een absolute positie is opgegeven met een top, right, bottom en left. Als je de absolute positie verandert in een statische, de standaardwaarde, werken top, right, bottom en left niet meer. De <div> komt op de plaats, waar hij van zichzelf automatisch terecht komt.

Helaas is de <div> daarmee nog steeds links buiten het scherm geplaatst en daarmee onzichtbaar. Deze <div> zit in div#li-mid-bui of div#re-mid-bui, en die <div>'s staan nog steeds links buiten het scherm geparkeerd. En dus ook deze twee-na-buitenste <div>, want zonder absolute positie komen deze <div>'s gewoon binnen div#li-mid-bui of div#re-mid-bui te staan, dus nog steeds links buiten het scherm.

Daarom moeten deze <div>'s naar links worden verplaatst, tot ze binnen het scherm komen te staan en daarmee de in de <div>'s zittende afbeelding zichtbaar wordt: de pop-up.

Dat op het scherm zetten is hier gelijk boven bij margin-left: 10030px; gebeurd. Waarom dat niet gewoon met left gebeurt, staat ook daar.

span:focus + #li-mid-bin, span:focus + #re-mid-bin

{margin-left: 20030px; position: static;} span:focus + #li-bin, span:focus + #re-bin {margin-left: 30030px; position: static;} span:focus + #li-kern, span:focus + #re-kern {margin-left: 40030px; position: static;}

Voor deze elementen 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.

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

#li-mid-bin, #re-mid-bin {width: 180px; height: 180px;}

#li-bin, #re-bin {width: 120px; height: 120px;}

#li-kern, #re-kern {width: 60px; height: 60px;}

div div {left: -20000px; -webkit-transition-delay: 0.4s; transition-delay: 0.4s;}

Dit zijn de meer naar binnen zittende <div>'s met pop-ups. Ze werken precies hetzelfde als de twee-na-buitenste <div>, zoals beschreven bij span:focus + #li-mid, span:focus + #re-mid.

De enige verschillen zijn de id's, omdat het om andere <div>'s gaat.

Verder is de marge links verschillend. Omdat elke <div> met left: -20000px; buiten het scherm is geparkeerd, staat elke geneste <div> steeds een stuk verder naar links. Daarom is de benodigde marge links om een <div> op het scherm te krijgen groter, naargelang de <div> dieper is genest.

span:focus + div img

Voor dit elementen 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.

img {box-sizing: border-box; max-width: 100%; border: black solid 1px; position: absolute;}

span:focus: als een <span> focus heeft.

+: het element achter de + moet in de html direct volgen op het element voor de +. In dit geval gaat het om een <div> die gelijk op een <span> volgt.

div img: de <img>'s binnen bovengenoemde <div>. Binnen elke <div> zit maar één <img>.

In normale mensentaal: doe iets met de afbeelding binnen de <div>, die gelijk volgt op de <span> die focus heeft.

margin-top: 30px;

Marge aan de bovenkant.

De <div>'s met de afbeelding staan bovenin hun ouder. Elke <div> is steeds 60 px minder hoog dan z'n ouder-<div>. Als je dus de afbeelding 30 px omlaag zet, staat de afbeelding precies verticaal gecentreerd binnen de ouder van de <div>, waar de afbeelding in zit.

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 vensters worden de twee afbeeldingen die al zichtbaar zijn bij het openen van de pagina niet onder elkaar, maar naast elkaar gezet.

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

h1

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

h1 {font-size: 1em; text-align: center;}

Alle <h1>'s. Dat is er maar eentje: de belangrijkste kopregel.

font-size: 1.3em;

In deze bredere browservensters is er ruimte voor een grotere letter.

Als eenheid wordt de relatieve eenheid em 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.

font-weight: normal;

Van zichzelf is een <h1> vet. Dat is wat teveel van het goede, daarom wordt dit hier weggehaald.

main

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

main {display: block; width: 360px; max-width: 90%; margin: 0 auto;}

Alle <main>'s. Dat is er maar eentje: het element waarin de belangrijkste inhoud van de pagina staat.

width: 720px;

Het venster van de browser is minimaal 760 px breed. Als <main> niet breder wordt dan 720 px, is er op touchscreens links en rechts van de pop-ups voldoende lege ruimte om deze door aanraken van het scherm weer te kunnen sluiten.

max-width: none;

De voor smallere browservensters opgegeven maximumbreedte van 90% is hier niet meer nodig.

#li-bui, #re-bui

Voor deze elementen 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.)

div {max-width: 100%; margin: auto; position: absolute; top: 0; right: 0; bottom: 0;}

#li-bui, #re-bui {width: 360px; height: 360px; margin: 10px auto 0; position: relative;}

De elementen met id="li-bui" en id="re-bui". Dit zijn de twee <div>'s, waarbinnen de twee afbeeldingen staan die al bij openen van de pagina zijn te zien. 'li-bui' is de linker-<div>, 're-bui' is de rechter‑<div>.

float: left;

Een <div> komt normaal genomen op een nieuwe regel te staan. Door ze naar links te floaten, komen ze naast elkaar te staan.

#tekst

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

p {padding: 0 5px;}

Het element met id="tekst". Dit is de eerste <p> met tekst, gelijk onder de afbeeldingen.

clear: both; Afbeelding 5: paragrafen met tekst zichtbaar gemaakt

Bij #li-bui, #re-bui zijn de buitenste twee <div>'s naar links gefloat. Dit heeft gevolgen voor de blok-elementen die na de gefloate elementen komen. Hier is dat de eerste <p> met tekst.

Bij gefloate elementen komt de inhoud van het erop volgende blok-element naast of onder de gefloate elementen te staan. Hier is dat de tekst binnen de eerste <p>.

Maar het blok-element zelf, dat na de gefloate elementen komt, negeert de gefloate elementen volledig. Het komt onder de gefloate elementen te staan, alsof die er niet zijn. Op de afbeelding is de eerste <p> even rood gemaakt, zodat te zien is dat die volledig onder de gefloate <div>'s doorloopt. De marge die een <p> van zichzelf aan de bovenkant heeft, steekt boven de gefloate <div>'s uit.

Maar de inhoud van de <p>, de tekst, staat netjes onder de gefloate <div>'s. Dat is ook de reden dat de <p> zo hoog is: de <p> zelf negeert de gefloate elementen, maar de tekst in de <p> niet, waardoor de <p> heel hoog wordt.

Als je nu 'n padding in de <p> gaat aanbrengen voor wat afstand tussen afbeeldingen en tekst, begint die padding helemaal bovenin de <p>, want dat doet een padding nou eenmaal. 'Bovenin de <p>' is in dit geval boven de gefloate <div>'s. Waardoor je 'n onwijs grote padding nodig hebt. Die bovendien bij een gewijzigde hoogte van de gefloate <div>'s weer aangepast moet worden.

Door de eerste <p> clear: both; te geven, komt de <p> op de normale manier ónder de gefloate elementen te staan en werkt de padding ook op de normale manier.

(Je zou hier kunnen volstaan met clear: left;, omdat beide <div>'s naar links zijn gefloat. Maar het is een goede gewoonte om, als dat ook maar enigszins kan, both te gebruiken. Als er later ergens een float: right; wordt toegevoegd, kan het anders leiden tot moeilijk te vinden fouten, waar je schuimbekkend dol van kunt worden. Daar worden alleen fabrikanten van kalmerende middelen blij van, dus als je niet toevallig aandelen in de farmaceutische maffia hebt, kun je kunt beter clear: both; gebruiken.)

padding-top: 10px;

Kleine afstand tussen afbeeldingen en tekst.

JavaScript

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

<script> document.getElementsByTagName("body")[0].addEventListener("touchstart", function () {return null; }); </script>

iOS heeft nogal moeite met het omzetten van :hover en dergelijke naar aanrakingen op een touchscreen. Applefans zullen ongetwijfeld zeggen dat het veel beter werkt dan op andere systemen, maar normale mensen worden er knettergestoord van.

Zonder deze code is het, behalve in Firefox, heel moeilijk op iOS de pop-ups weer te sluiten. Pas als een ander element focus heeft gekregen, of als de pagina opnieuw wordt geladen, worden de pop-ups weer gesloten. Door toevoegen van deze code sluiten de pop-ups ook op iOS bij het aanraken van een willekeurige plaats van het scherm (wel buiten de pop-ups natuurlijk).

Zonder deze code openen de pop-ups wel gewoon, alleen het sluiten levert problemen op.

<script> en </script>

Dit is gewone html: het zijn de openings- en sluittag voor het script. In html5 is de toevoeging type="text/javascript" niet meer nodig.

document.getElementsByTagName("body")

Zoek naar de elementen met de tag <body>. Jij en ik weten dat er maar één <body> is, maar een browser is nou eenmaal niet zo slim, dus die zoekt trouwhartig naar álle <body>'s. En vindt er uiteraard maar eentje.

[0]

De gevonden tags worden geretourneerd in de vorm van een lijst. Als er bijvoorbeeld honderd <div>'s zouden worden gevonden, heeft deze lijst honderd ingangen. Zo'n ingang kun je aanspreken door het volgnummer te gebruiken. En omdat computers dol zijn op '0', is het volgnummer van de eerste ingang '0', en geen '1'.

Uiteraard is er maar één <body> gevonden. Het volgnummer van die <body> is dus '0', de eerste ingang.

document.getElementsByTagName("body")[0]

Beide samen: doe iets met het element <body>.

addEventListener

Voeg aan <body> een 'eventlistener' toe. Dat is een ding dat luistert, of er iets gebeurt. Zo'n gebeurtenis kan een aanraking van het scherm zijn, een liefdevolle aai van de muis, een ram op het toetsenbord, van alles.

"touchstart"

In dit geval wordt naar het begin van een aanraking van het touchscreen geluisterd. Dat is nog niet zo interessant, het wordt pas echt opwindend wat er ná die eerste, inleidende aanraking gaat gebeuren... Vinden zij elkaar, of wordt het moord- en doodslag?

function () {return null; }

Helaas, ze vinden elkaar niet én het wordt geen moord- en doodslag.

function() is gewoon een soort aankondiging dat er iets gaat gebeuren. Erachter tussen de accolades staat, wat er gaat gebeuren: return null;. Doe niets. Helemaal niets. Vanavond niet, schat, ik heb hoofdpijn. Of, afhankelijk van opvoeding, omgeving, enz.: blijf met je gore rotpoten van me af, viespeuk.

Bij de uitleg van deze code zijn allerlei haakjes en dergelijke weggelaten, want dat voert hier te ver. Als je je in dat soort dingen wilt verdiepen, kun je beter naar sites gaan die meer voor JavaScript zijn bedoeld.