Pop-up met externe link en tekst op achtergrond-afbeelding - uitleg
Laatst aangepast: .

Korte omschrijving
Bij aanraken of -klikken van, hoveren over of tabben naar het vraagteken opent een pop-up met link en tekst over een achtergrond-afbeelding.
BELANGRIJK
Deze uitleg hoort bij het voorbeeld dat in de download zit. Het voorbeeld uit de download verschilt iets van het voorbeeld hier op de site. In de download ontbreekt bijvoorbeeld de navigatie voor de site. Ook in de kopregels zit vaak wat verschil. Daarnaast kunnen er nog andere (meestal kleine) verschillen zijn.
Als je deze uitleg leest naast de broncode van het voorbeeld op de site, kan het dus bijvoorbeeld zijn dat 'n <h1> uit de css bij 'n <h2> uit de html hoort. Maar het gaat niet om hele grote, fundamentele afwijkingen.
Als je dit lastig vindt, kun je bovenaan de pagina de hele handel downloaden. In de download zit 'n voorbeeld dat wel naadloos aansluit op de uitleg in de download.
Alles op deze site kan vrij worden gebruikt, met drie beperkingen:
* Je gebruikt het materiaal op deze site volledig op eigen risico. Het kan prima zijn dat er fouten in de hier verstrekte info zitten. Voor eventuele schade die door gebruik van materiaal van deze site ontstaat, in welke vorm dan ook, zijn www.css-voorbeelden.nl en medewerkers daarvan op geen enkele manier verantwoordelijk.
* Deze uitleg wordt regelmatig bijgewerkt. Het is daarom niet toegestaan deze uitleg op welke manier dan ook te verspreiden, zonder daarbij duidelijk te vermelden dat de uitleg afkomstig is van www.css-voorbeelden.nl en dat daar altijd de nieuwste versie is te vinden. Dit is om te voorkomen dat er verouderde versies worden verspreid.
* Het kan zijn dat materiaal is gebruikt dat van anderen afkomstig is. Dat materiaal kan onder een bepaalde licentie vallen, waardoor het mogelijk niet onbeperkt gebruikt mag worden. Als dat zo is, wordt dat vermeld onder Inhoud van de download en licenties.
Een link naar www.css-voorbeelden.nl wordt trouwens altijd op prijs gesteld.
Alle code is geschreven in een afwijkende
lettersoort en -kleur. De code die te maken heeft met de basis van dit voorbeeld (essentiële code), is in de hele uitleg onderstippeld blauw
. Alle niet-essentiële code is bruin
. (In de inhoudsopgave staat alles vanwege de leesbaarheid in een gewone letter.)
Opmerkingen
- Het achtergrondplaatje is afkomstig van www.wpclipart.com.
-
Belangrijke informatie moet nooit alleen in een pop-up of zoiets worden gezet. Als om een of andere reden die pop-ups niet (kunnen) worden geopend, is de informatie volstrekt onzichtbaar.
In dit voorbeeld wordt tegen deze regel gezondigd. Op forums werd soms gevraagd om 'n pop-up met 'n link. Als je zo'n constructie wilt maken, dan kan het het best op deze manier. In een aantal browsers wordt echter niet eerst de pop-up geopend, maar wordt gelijk de link gevolgd. Deze browsers tonen dus niet de tekst en de afbeelding uit de pop-up.
Ook in sommige schermlezers opent de pop-up niet altijd, waardoor de tekst in de link niet is te zien. De tekst wordt wel altijd voorgelezen.
In beide gevallen worden tekst en afbeelding uit de pop-up niet getoond, dus eventuele belangrijke informatie is in deze gevallen gewoon niet te zien. Meer over beide problemen is te vinden bij Bekende problemen (en oplossingen).
Links in deze uitleg, vooral links naar andere sites, kunnen verouderd zijn. Op de pagina met links vind je steeds de meest recente links.
Dit voorbeeld is gemaakt op een systeem met Linux (Kubuntu). Daarbij is vooral gebruik gemaakt van Komodo Edit, GIMP en Firefox met extensies. De pdf-bestanden zijn gemaakt met LibreOffice.
Vragen of opmerkingen? Fout gevonden? Ga naar het forum.
Achterliggend idee
Sinds de eerste versie van dit voorbeeld is er nogal wat veranderd. Schermlezers en dergelijke zijn sterk verbeterd, waardoor het makkelijker wordt dingen toegankelijk te maken. Touchscreens zijn alledaagse voorwerpen geworden, terwijl dit bij de vorige versie nog redelijk exotische apparaten waren.
Toen er nog geen touchscreens waren, was een pop-up simpel te maken (even los van de 666 aanpassingen die voor de door een reïncarnatie van Beëlzebub zelve ontworpen Internet Explorer 6 nodig waren). Als je ergens met de muis over hoverde, opende een pop-up. Vervolgens een klik en hoppa, de link werd gevolgd. Ook voor gebruikers van de Tab-toets was een pop-up relatief simpel toegankelijk te maken.
Op alle systemen is hoveren op een of andere manier te simuleren. Dat moest ook wel, want vele miljoenen bestaande sites gebruikten deze techniek. Helaas is de manier waarop dit gebeurt verschillend bij Android, Windows en Apple. (Dat geldt trouwens ook als je JavaScript gebruikt om hoveren te simuleren.)
Voor touchscreens moesten dus aanpassingen worden aangebracht, waardoor de pop-up ook door aanraking sluit of opent. En met – als dat enigszins kon – gebruikmaking van alleen css. En als het dan toch wordt herschreven, is dat een mooie gelegenheid ook de toegankelijkheid te verbeteren.
Eerst een bekentenis: de pop-up is helemaal geen pop-up. Het gaat om iets wat altijd op het scherm staat, maar verstopt. Door bepaalde handelingen wordt dat 'iets' vergroot en zichtbaar. Maar omdat dit er net zo uitziet als een 'echte' JavaScript-pop-up, wordt ook dit soort constructies meestal gewoon 'pop-up' of 'css-pop-up' genoemd.
Deze pop-up valt eigenlijk in twee delen uiteen. Bij hoveren over of aanraken of -klikken van het vraagteken moet de pop-up openen. Als daarna de pop-up wordt aangeraakt of -geklikt, moet de link worden gevolgd. Sluiten gebeurt door het scherm buiten de pop-up aan te raken of -klikken of, bij hoveren, door de cursor weer buiten het vraagteken te plaatsen.
Voor gebruikers van de Tab-toets werkt het op een soortgelijke manier. De Tab-toets opent en sluit de pop-up, als de pop-up is geopend laat een Enter de link volgen.
De hele constructie bestaat in feite maar uit vier onderdelen. Een <input type="checkbox">, twee bij die <input> behorende <label>'s en de <a> met de eigenlijke pop-up.
De <input> is eigenlijk niet nodig, maar de <label>'s hebben die nodig, omdat ze anders niet overal goed werken. De specificatie is wat vaag over hoe <label>'s zonder <input> of iets soortgelijks horen te werken met dingen als 'op de voor het systeem gebruikelijke manier'. Daarom is het zekere voor het onzekere genomen en gewoon een <input> gebruikt, die dus feitelijk alleen maar de dienstdoende Jan Joker loopt te spelen.
De drie belangrijke elementen zijn de eerste <label>, de daaropvolgende <a>, en de daarop weer volgende tweede <label>.
In de eerste <label> staat het vraagteken in een wit vierkant.
De <a> met de pop-up is normaal genomen heel klein en wordt verborgen onder de <label> met het vraagteken, waardoor deze onzichtbaar is. Verbergen met display: none;
kan niet, want dan zien schermlezers de link niet.
Normaal genomen verberg je iets door het links buiten het scherm te positioneren. Schermlezers kunnen het dan gewoon lezen. Hier kan dat niet, want in TalkBack op Android blijkt de link alleen te werken, als deze op het scherm staat. Het simpelste zou dan zijn om de link 0 x 0 px te maken met overflow: hidden;
en nog wat van dat soort dingen. De link blijkt echter ook minstens 1 x 1 px groot te moeten zijn.
Daarom is de link normaal genomen 1 x 1 px en wordt verborgen onder het vraagteken. Pas als de pop-up moet worden getoond, wordt de link vergroot en worden achtergrond-afbeelding en tekst zichtbaar.
Eerst het hoveren, dat is simpel. Bij hoveren over de <label> met het vraagteken wordt de <a> met de pop-up vergroot en daardoor zichtbaar. Als op de <a> met de pop-up wordt geklikt, wordt de link gevolgd. Als dat niet gebeurt en de cursor buiten het vraagteken wordt geplaatst, verdwijnt de pop-up weer onder het vraagteken. Hiermee is de hele pop-up wat betreft de muis afgehandeld.
Ook voor gebruikers van de Tab-toets is het niet al te ingewikkeld. Normaal genomen wordt bij indrukken van de Tab-toets ook de <input> bezocht, maar dat is hier overbodig en wordt voorkomen door de <input> het attribuut tabindex"-1"
te geven. De <a> met de pop-up wordt wel gewoon bezocht. Als de <a> focus krijgt, wordt deze vergroot en daardoor wordt de erin zittende pop-up zichtbaar. Door het indrukken van Enter wordt de link gevolgd, net zoals dat normaal het geval is. Als dat niet gebeurt, verliest de <a> weer de focus door het nogmaals indrukken van de Tab-toets, waardoor de <a> weer klein wordt en onder het vraagteken verdwijnt.
Het lastige deel wordt gevormd door de touchscreens.
Een <label> die op een touchscreen wordt aangeraakt, reageert net alsof erop wordt geklikt: het bijhorende aankruisvakje (de <input>) wordt uit- of aangevinkt. Omdat die <input> hier verder niet wordt gebruikt, is dat niet van belang.
De <label> met het vraagteken reageert ook op een touchscreen op hoveren. Dat werkt op een touchscreen ongeveer hetzelfde als een klik, alleen net even anders en – uiteraard – op elk systeem op een net iets andere manier.
Op alle systemen volgt een aantal browsers altijd gelijk de link, zonder de pop-up te tonen, als het vraagteken wordt aangeraakt. Door de <a> pas na een kleine vertraging te tonen, wordt dit in vrijwel alle browsers voorkomen.
Op Windows gaat het meestal goed. Je raakt het vraagteken aan en de <a> wordt vergroot en daardoor zichtbaar. Als je de pop-up nogmaals aanraakt, wordt de link gevolgd. Als je het scherm buiten de <a> met de pop-up aanraakt, wordt de <a> weer klein en verdwijnt weer onder het vraagteken.
'Meestal' stond er dus. In Internet Explorer 11 en Edge op touchscreens opent de pop-up bij aanraking niet. Of hij opent pas na een hele tijd. Of het contextuele menu wordt geopend. 'n Soort loterij. Er zal vast enige logica in zijn te ontdekken, maar die heb ik niet kunnen ontdekken. Als je echter aan de <label> met het vraagteken de WAI-ARIA-code aria-haspopup="true"
toevoegt, werkt het goed.
Op Android opent de pop-up bij aanraking van het vraagteken. Als je de pop-up aanraakt, wordt de link gevolgd. Als het scherm buiten de pop-up wordt aangeraakt, wordt de <a> weer klein en verdwijnt onder het vraagteken. (Nog niet gaan juichen over Android, want de schermlezer TalkBack had hier behoorlijke kuren, waarover later meer.)
Op iOS wordt de <a> met de pop-up bij aanraking van het vraagteken vergroot en daardoor zichtbaar. Bij nogmaals aanraken van de pop-up wordt de link gevolgd. Hoveren wordt op iOS omgezet in 'n soort focus: zolang het vraagteken focus heeft, blijft de <a> en daarmee de pop-up zichtbaar. Pas door het aanraken van een knop, tekstveld, link, of ander element dat focus kan krijgen, verliest de <label> met het vraagteken de focus en wordt de <a> weer klein genoeg om onder het vraagteken te verdwijnen. Gewoon het scherm aanraken ergens buiten de pop-up werkt niet, je moet echt 'n element aanraken dat focus kan krijgen.
Daarvoor wordt de tweede <label> gebruikt. Op het moment dat de eerste <label> met het vraagteken wordt aangeraakt, wordt de tweede <label> even groot gemaakt als het venster van de browser, zodat het hele scherm wordt afgedekt (behalve de <a> met de pop-up). Als je deze tweede <label> aanraakt, verliest de eerste <label> met het vraagteken de focus, en verdwijnt de <a> met de pop-up weer onder het vraagteken.
De reden om <label>'s te gebruiken en geen gewone <span>'s of <p>'s of zo, heeft ook met iOS te maken. Als je op iOS een <span> of zoiets gebruikt, moet je de <span> twee keer aanraken, voordat de pop-up opent. Dat kan alleen worden voorkomen door JavaScript te gebruiken. Bij gebruik van een <label> hoeft dit niet.
(In Firefox op iOS verdwijnt de <a> trouwens wel weer onder het vraagteken, als het scherm buiten de pop-up wordt aangeraakt, ook zonder deze extra <label>.)
De schermlezer TalkBack op Android heeft ook nog wat kuren. Oorspronkelijk stond de <a. met de pop-up links buiten het scherm, als deze onzichtbaar moest zijn. Het blijkt echter onmogelijk om in TalkBack een link te volgen, als die buiten het scherm staat. Vandaar de constructie met de <a> die onder het vraagteken wordt verborgen.
De <a> werd dus onder het vraagteken gezet en onzichtbaar gemaakt door deze een breedte en hoogte van 0 px te geven. Dat kon echter ook niet, want om in TalkBack te werken blijkt de link minstens 1 x 1 px groot te moeten zijn.
De tekst in de link is voor schermlezers iets minder handig: 'Klik of raak plaatje aan om naar site van wpclipart.com te gaan'. Deze tekst was dan ook eerst verborgen voor schermlezers en vervangen door het attribuut aria-labelledby="Naar site van wpclipart.com"
. Ook dit had echter als resultaat dat de link in TalkBack niet gevolgd kon worden. Hij wordt netjes voorgelezen, maar kan niet worden gevolgd.
Waarom TalkBack zo weerzinwekkend kieskeurig is, is onbekend. Normaal genomen zou een link in een schermlezer gewoon moeten werken, ook al staat die buiten het scherm. In de andere geteste schermlezers is dat ook het geval, alleen TalkBack gedraagt zich zo tegendraads.
Om alles helemaal goed werkend te krijgen, was er ook nog enig gegoochel met z-index
, WAI-ARIA-codes, en dergelijke nodig. Dat wordt op de betreffende plaatsen verder besproken.
De voorvoegsels -moz-, -ms- en -webkit-
Voordat een nieuwe css-eigenschap wordt ingevoerd, is er in de regel een experimentele fase. Browsers passen het dan al toe, maar met een aangepaste naam. Tijdens deze fase kunnen problemen worden opgelost en worden veldslagen uitgevochten, over hoe de standaard precies moet worden toegepast.
Als iedereen het overal over eens is en alle problemen zijn opgelost, wordt de officiële naam uit de standaard gebruikt.
De belangrijkste browsers hebben elk een eigen voorvoegsel:
Firefox: -moz-
, naar de maker: Mozilla.
Op webkit gebaseerde browsers, zoals Google Chrome, Opera, Safari en Android browser: -webkit-
.
(Google Chrome is van webkit overgestapt op een eigen weergave-machine: Blink. Blink gaat geen voorvoegsels gebruiken. Het is echter een aftakking van webkit, dus het zal nog wel even duren voor -webkit-
hier helemaal uit is verdwenen. Ook Opera gebruikt Blink.)
Internet Explorer: -ms-
, naar de maker: Microsoft. (Edge gebruikt geen voorvoegsels, maar vanwege compatibiliteit met oudere sites kunnen er nog wat aanwezig zijn.)
Zodra de experimentele fase voorbij is, wordt het voorvoegsel weggelaten. Omdat dat moment niet bij alle browsers hetzelfde is, zet je nu ook al de officiële naam erbij. Deze wordt als laatste opgegeven. Bijvoorbeeld Android browser herkent -webkit-linear-gradient
. Zodra Android browser linear-gradient
gaat herkennen, zal dit -webkit-linear-gradient
overrulen, omdat het er later in staat. Dat ze er beide in staan, is dus geen enkel probleem.
In dit voorbeeld worden -ms-user-select
en transition-delay
gebruikt.
ms-user-select
Vanwege het voorvoegsel -ms-
werkt dit alleen in Internet Explorer en Edge. Normaal genomen zou je de vormen met de voorvoegsels voor andere browsers gebruiken, en als laatste user-select
zonder voorvoegsel. Hier is dit echter niet nodig, omdat user-select
wordt gebruikt voor een probleem dat alleen in Internet Explorer en Edge speelt. Maar normaal genomen is het een absoluut slecht idee om een eigenschap te gebruiken, die niet in alle browsers werkt.
Meer over dit probleem is te vinden bij -ms-user-select: none;.
transition-delay
Op dit moment moet je nog het volgende schrijven:
{-webkit-transition-delay: ...; transition-delay: ...;}
In de toekomst kun je volstaan met:
{transition-delay: ...;}
Inmiddels is de algemene mening dat 'vendor prefixes', zoals deze voorvoegsels in het Engels heten, geen groot succes zijn. Eén van de grootste problemen: veel sitemakers gebruiken alleen de -webkit-
variant. Daar kwamen ze in het verleden nog mee weg, omdat Apple op mobiel zo'n beetje 'n monopolie had. Inmiddels is dat niet meer zo, maar deze gewoonte bestaat nog steeds. Waardoor 'n site alleen in op webkit georiënteerde browsers goed is te bekijken.
Dit is zo'n groot probleem dat andere browsers soms de variant met -webkit-
ook maar zijn gaan implementeren, naast de standaard. Want als 'n site het niet goed doet in 'n bepaalde browser, krijgt in de regel niet de site maar de browser de schuld.
Vanwege alle problemen met 'vendor prefixes' worden deze door steeds meer browsers niet meer gebruikt. Nieuwe, experimentele css-eigenschappen zitten inmiddels in bijvoorbeeld Firefox, Google Chrome en Safari achter een zogenaamde vlag: de gebruiker moet iets veranderen in de instellingen, waarna de eigenschap gebruikt (en getest) kan worden. Als alles werkt, zoals het hoort te werken, schakelt de browsermaker de vlag standaard in.
Voorlopig zijn we echter nog niet van deze voorvoegsels af. Als je ze gebruikt, gebruik dan álle varianten, en eindig met de variant zonder voorvoegsel, zoals die uiteindelijk ooit gebruikt gaat worden. Als je alleen de -webkit-
variant gebruikt, ben je in feite 'n onbetaalde reclamemaker voor Apple. (Dit geldt dus niet voor het hierboven genoemde -ms-user-select
, want dit wordt alleen gebruikt om een probleem in Internet Explorer en Edge op te lossen.)
Semantische elementen en WAI-ARIA
Deze twee onderwerpen zijn samengevoegd, omdat ze veel met elkaar te maken hebben.
Semantische elementen
De meeste elementen die in html worden gebruikt, hebben een semantische betekenis. Dat wil zeggen dat je aan de gebruikte tag al (enigszins) kunt zien, wat voor soort inhoud er in het element staat. In een <h1> staat een belangrijke kop. In een <h2> staat een iets minder belangrijke kop. In een <p> staat een alinea. In een <table> staat een tabel (en geen lay-out, als het goed is!). Enzovoort.
Door het op de goede manier gebruiken van semantische elementen, kunnen zoekmachines, schermlezers, enzovoort de structuur van een pagina begrijpen. De spider van een zoekmachine is redelijk te vergelijken met een blinde. Het is dus ook in je eigen belang om semantische elementen zo goed mogelijk te gebruiken. Een site die toegankelijk is voor mensen met een handicap, is in de regel ook goed te verwerken door een zoekmachine en maakt dus een grotere kans gevonden en bezocht te worden.
Als het goed is, wordt het uiterlijk van de pagina bepaald met behulp van css. Het uiterlijk staat hierdoor (vrijwel) los van de semantische inhoud van de pagina. Met behulp van css kun je een <h1> heel klein weergeven en een <h6> heel groot, terwijl schermlezers, zoekmachines, en dergelijke nog steeds weten dat de <h1> een belangrijke kop is.
Slechts enkele elementen, zoals <div> en <span>, hebben geen semantische betekenis. Daardoor zijn deze elementen uitstekend geschikt om met behulp van css het uiterlijk van de pagina aan te passen: de semantische betekenis verandert niet, maar het uiterlijk wel. Voor een schermlezer of zoekmachine verandert er (vrijwel) niets, voor de gemiddelde bezoeker krijgt het door de css een heel ander uiterlijk.
(De derde laag, naast html voor de inhoud en css voor het uiterlijk, is JavaScript. Die zorgt voor de interactie tussen site en bezoeker. De min of meer strikte scheiding tussen css en html aan de ene kant en JavaScript aan de andere kant is met de komst van css3 en html5 veel vager geworden. Je kunt nu bijvoorbeeld ook met css dingen langzaam verplaatsen en met html deels de invoer in formulieren controleren.)
Html5 heeft een aantal nieuwe elementen, die speciaal zijn bedoeld om de opbouw van een pagina aan te geven. In dit voorbeeld wordt hiervan alleen <main> gebruikt. <main> gedraagt zich als een gewone <div>, maar dan een <div> met een semantische betekenis. Hierdoor kunnen schermlezers, zoekmachines, en dergelijke beter zien, hoe de pagina is samengesteld.
<main>
Hierbinnen staat de belangrijkste inhoud van de pagina (in dit voorbeeld is dat voornamelijk de pop-up met toebehoren).
Met behulp van dit soort nieuwe semantische elementen kan bijvoorbeeld een schermlezer in één keer een heel menu passeren en gelijk naar de echte inhoud gaan. Alleen hadden deze nieuwe elementen tot voor kort één probleem: ze hadden in de praktijk nog weinig nut, omdat schermlezers en dergelijke ze nog niet herkenden. Daarom werd een zogenaamde WAI-ARIA-code toegevoegd aan deze elementen. Dat is een al veel langer bestaande code, die schermlezers en dergelijke wel herkennen. Voor <main> ziet dat er zo uit:
<main role="main">
Inmiddels is dit behoorlijk veranderd. Het advies is nu om deze speciale toevoeging niet meer te gebruiken, omdat de meeste schermlezers en dergelijke dit soort nieuwe elementen inmiddels herkennen.
WAI-ARIA-codes
WAI-ARIA wordt vaak ingekort tot ARIA. Voluit betekent het Web Accessibility Initiative – Accessible Rich Internet Applications.
Er worden in dit voorbeeld twee WAI-ARIA-codes gebruikt: aria-hidden
en aria-haspopup
.
aria-hidden
De <input> en de twee bijbehorende <label>'s hebben geen enkel nut voor schermlezers, maar zijn alleen verwarrend. Daarom worden deze met behulp van het attribuut aria-hidden="true"
voor schermlezers verborgen:
<input id="open" type="checkbox" tabindex="-1" aria-hidden="true">
<label id="vraagteken" for="open" aria-haspopup="true" aria-hidden="true">?</label>
<label id="sluit" for="open" aria-hidden="true"></label>
aria-haspopup
In de <label> met het vraagteken staat nog een andere WAI-ARIA-code, aria-haspopup
:
<label id="vraagteken" for="open" aria-haspopup="true" aria-hidden="true">?</label>
In Internet Explorer 11 en Edge op touchscreens opent de pop-up bij aanraking niet. Of hij opent pas na een hele tijd. Of het contextuele menu wordt geopend. 'n Soort loterij. Kortom: enorme kommer en kwel. Door het toevoegen van aria-haspopup="true"
opent de pop-up gewoon.
Volgens de WAI-ARIA-specificatie 1.0 kan met aria-haspopup="true"
worden aangegeven dat het element een contextueel menu of een submenu heeft. Microsoft gebruikt dit attribuut dus voor iets, waar het niet voor is bedoeld.
In de ontwerp-specificatie versie 1.1 is de waarde 'true' bij aria-haspopup
vervallen, maar wordt vanwege terugwaartse compatibiliteit met versie 1.0 nog wel gedefinieerd op eenzelfde wijze als in versie 1.0. Hiermee lijken mogelijke toekomstige problemen voor dit oneigenlijke gebruik te worden voorkomen.
Tabindex en Tab-toets
Links, invoervelden in formulieren, en dergelijke kunnen met behulp van de Tab-toets (of een soortgelijke toets) één voor één worden bezocht, in de volgorde waarin ze in de html voorkomen. Shift+Tab-toets keert de volgorde van de Tab-toets om. Dit is een belangrijk hulpmiddel voor mensen die om een of andere reden de muis niet kunnen of willen gebruiken. (En het is vaak ook veel sneller dan de muis, vooral in formulieren.)
In sommige browsers en/of besturingssystemen is dit vreemd genoeg standaard uitgeschakeld en is een zoektocht in de instellingen nodig om dit aan te zetten. Maar gebruikers van de Tab-toets zullen dit al hebben gedaan.
Als je met behulp van de Tab-toets een element hebt bereikt, heeft dit 'focus': als het een link is en je drukt op Enter, wordt de link gevolgd. Bij een tekstveld kun je tekst gaan invoeren. Enzovoort.
De Tab-toets volgt normaal genomen de volgorde van de elementen in de html. Het maakt niet uit, in welke volgorde ze op het scherm staan. Als je met behulp van css de elementen van plaats verwisselt op het scherm, wordt toch gewoon de volgorde in de html gevolgd.
De volgorde van de Tab-toets kan worden veranderd met behulp van het tabindex
-attribuut: <div tabindex="3">
. Deze <div> zal nu als derde worden bezocht, ook al krijgt een simpele <div> normaal genomen nooit bezoek van de Tab-toets.
Normaal genomen is het gebruik van een tabindex niet nodig. Het is zeker niet bedoeld om de bezoeker als een kangoeroe op een hindernisbaan van onder via links over rechts naar boven te laten springen. Maar soms kan het handig zijn voor kleinere correcties, als de normale volgorde in de html niet optimaal is. Of om een element bereikbaar te maken voor de Tab-toets, zoals de hierboven genoemde <div>.
Schermlezers blijven altijd de volgorde van de html volgen, dus als de tabindex sterk afwijkt van de volgorde in de html, kan dat behoorlijk verwarrend zijn.
De tabindex kan drie verschillende waarden hebben: -1, 0 of een positief getal.
In principe is de volgorde bij gebruik van de Tab-toets als volgt: eerst worden alle positieve getallen in volgorde afgewerkt. Als twee tabindexen dezelfde waarde hebben, wordt de volgorde in de html aangehouden. Een waarde van '0' wordt, afhankelijk van browser en besturingssysteem, verschillend behandeld, waarover iets hieronder bij Tabindex="0" meer.
tabindex="-1"
Een negatieve waarde van -1 zorgt ervoor dat het element volledig wordt genegeerd door de Tab-toets. Zelfs een link met een negatieve tabindex wordt volledig genegeerd. Normaal genomen heeft een tabindex="-1"
maar één nut: je kunt dan met behulp van JavaScript toch focus aan het element geven, zonder dat gebruikers van de Tab-toets erdoor worden gehinderd.
In dit voorbeeld wordt tabindex="-1"
voor iets anders gebruikt. Als de Tab-toets wordt gebruikt en a#linkje
met de pop-up de focus krijgt, wordt a#linkje
vergroot, waardoor de pop-up zichtbaar wordt. Omdat de <a> focus heeft, wordt de link gevolgd als op Enter wordt gedrukt. Als nogmaals op de Tab-toets wordt gedrukt, verliest de <a> de focus weer en wordt de <a> met de pop-up weer verkleind en verborgen onder het vraagteken.
De hele constructie met <input> en <label>'s is daarom niet nodig voor gebruikers van de Tab-toets, omdat de <a> rechtstreeks wordt aangedaan door de Tab-toets. In dit geval werken <input> en <label>'s alleen maar verwarrend voor gebruikers van de Tab-toets. Daarom krijgt de <input> een negatieve tabindex, waardoor <input> (en <label>'s) worden genegeerd bij gebruik van de Tab-toets:
<input id="open" type="checkbox" tabindex="-1" aria-hidden="true">
Verder blijkt de schermlezer VoiceOver op iOS, als je van element naar element gaat, de <a> met de pop-up wel te tonen, als deze wordt voorgelezen, maar niet meer te verbergen, als naar het vorige of volgende element wordt gegaan. Door het geven van een negatieve tabindex aan het element gelijk voor de <input> (dat is p#uitleg
) en het element gelijk na de tweede <label> (dat is de <div> met de Latijnse opvultekst), wordt de <a> wel weer verborgen:
<p id="uitleg" tabindex="-1">Als je met de cursor (...) op wpclipart.com.</p>
<div tabindex="-1">
tabindex="0"
Volgens de specificatie van html 4.01 moest een tabindex="0"
pas worden bezocht, nadat tabindexen met een positief nummer waren bezocht. Sommige browsers hielden zich hier echter niet aan: een tabindex="0"
werd gewoon tussen de positieve tabindexen gezet.
In html5 is de situatie nog fijner. Nu staat er alleen dat, wat betreft de volgorde, de gewoonte van het platform wordt gevolgd. Oftewel: doe maar raak. Maar hoe dan ook: als je tabindex="0"
gebruikt, kan een element focus krijgen met behulp van de Tab-toets. Ook als dat element normaal genomen geen focus kan krijgen.
Deze waarde wordt in dit voorbeeld niet gebruikt.
tabindex="..."
Op de plaats van de puntjes moet een positief getal worden ingevuld: het volgnummer. Positieve tabindexen worden in dit voorbeeld niet gebruikt.
Muis, toetsenbord, touchpad en touchscreen
Vroeger, toen het leven nog mooi was en alles beter, waren er alleen monitors. Omdat kinderen daar niet af konden blijven met hun tengels, besloten fabrikanten dan maar touchscreens te gaan maken, omdat je die mag aanraken. Het bleek makkelijker te zijn om volwassenen ook te leren hoe je 'n scherm vies maakt, dan om kinderen te leren met hun vingers van de monitor af te blijven.
Zo ontstonden touchscreens en kreeg het begrip ellende een geheel nieuwe lading. In de perfecte wereld van vroeger, waarin alleen desktops bestonden, werkten dingen als hoveren, klikken en slepen gewoon. Zonder dat je eerst 'n cursus hogere magie op Zweinstein hoefde te volgen. Zelfs in JavaScript was het nog wel te behappen, ook voor mensen zoals ik die toevallig niet Einstein heten.
Op dit moment kun je computerschermen ruwweg in twee soorten indelen: schermen die worden aangeraakt, en schermen die worden bediend met hulpmiddelen als een toetsenbord, muis of touchpad. Omdat ook computerschermen zich kennelijk vermengen, bestaan er inmiddels ook schermen die zowel van aanraken als van muizen houden.
Hieronder staat een lijstje met dingen die zijn aangepast voor de verschillende soorten schermen, zodat dit voorbeeld overal werkt.
:hover
Omdat :hover
mogelijk niet werkt, als css uitstaat, ontbreekt of onvolledig is geïmplementeerd, moet je nooit belangrijke informatie alleen met behulp van :hover
tonen.
In dit voorbeeld wordt tegen deze regel gezondigd. Op forums werd soms gevraagd om 'n pop-up met 'n link. Als je zo'n constructie wilt maken, dan kan het het best op deze manier. In een aantal browsers wordt echter niet eerst de pop-up geopend, maar wordt gelijk de link gevolgd. Deze browsers tonen dus niet de tekst en de afbeelding uit de pop-up. Ook niet alle schermlezers tonen de pop-up altijd. De informatie uit de pop-up is dus niet voor iedereen bereikbaar. Meer hierover is te vinden bij Bekende problemen (en oplossingen).
Je hovert over een element, als je met behulp van muis of touchpad de cursor boven dat element brengt. Hoveren kan over álle elementen. Het wordt veel gebruikt om iets van uiterlijk te laten veranderen, een pop-up te laten verschijnen, en dergelijke.
Bij gebruik van een muis zit er een verschil tussen hoveren en klikken, maar op een touchscreen is dat verschil er niet: je raakt een touchscreen aan of niet. Dit levert problemen op in iOS en in Edge op een touchscreen.
Internet Explorer en Edge op een touchscreen hebben problemen met het openen van de pop-up. Om dat op te lossen, is aan label#vraagteken
het attribuut aria-haspopup="true"
toegevoegd. Meer hierover is te vinden bij WAI-ARIA-codes.
Op iOS opent de pop-up wel goed, maar is juist het sluiten een probleem. Na aanraken van de <label> met het vraagteken, gedraagt dit <label> zich, alsof het focus heeft. Pas na aanraking van een ander element dat focus kan krijgen, zoals een link, tekstveld of knop, wordt de focus weer weggehaald bij de <label> met het vraagteken. Pas dan verdwijnt de <a> met de pop-up weer.
Daarom is na de <a> nog een <label id="sluit: > toegevoegd. Zodra de pop-up wordt geopend, bedekt label#sluit
het volledige venster van de browser. Oftewel: waar je het scherm ook aanraakt, je raakt label#sluit
aan. En omdat een <label> op aanraking reageert, sluit de pop-up nu. Normaal genomen is label#sluit
verborgen, het dekt het scherm pas af, als de pop-up zichtbaar is. Zodra de pop-up weg is, verdwijnt label#sluit
ook weer.
:focus
Omdat :focus
mogelijk niet werkt, als css uitstaat, ontbreekt of onvolledig is geïmplementeerd, moet je nooit belangrijke informatie alleen met behulp van :focus
tonen.
In dit voorbeeld wordt tegen deze regel gezondigd. Op forums werd soms gevraagd om 'n pop-up met 'n link. Als je zo'n constructie wilt maken, dan kan het het best op deze manier. In een aantal browsers wordt echter niet eerst de pop-up geopend, maar wordt gelijk de link gevolgd. Deze browsers tonen dus niet de tekst en de afbeelding uit de pop-up. Ook niet alle schermlezers tonen de pop-up altijd. De informatie uit de pop-up is dus niet voor iedereen bereikbaar. Meer hierover is te vinden bij Bekende problemen (en oplossingen).
De meeste mensen gaan met een muis naar een link, invoerveld, en dergelijke. Waarna ze vervolgens klikken om de link te volgen, tekst in te voeren, of wat ze ook maar willen doen.
Er is echter 'n tweede manier om naar links, invoervelden, en dergelijke te gaan: met behulp van de Tab-toets (sommige browsers gebruiken andere toetsen, maar het principe is hetzelfde). Met behulp van de Tab-toets kun je naar links, invoervelden, en dergelijke 'springen'.
Waar je staat, wordt door alle browsers aangegeven met een of ander kadertje. De link en dergelijke met het kadertje eromheen 'heeft focus'. Dat wil zeggen dat je die link volgt, als je op de Enter-toets drukt, of dat je in dat veld tekst kunt gaan invoeren, enzovoort.
Het kadertje dat de focus aangeeft, moet nooit zonder meer worden weggehaald. Gebruikers van de Tab-toets hebben dan geen idee meer, waar ze zijn.
De pop-up zit in een gewone <a> en kan dus door het gebruiken van de Tab-toets focus krijgen. Zodra de <a> door gebruik van de Tab-toets focus heeft gekregen, wordt de pop-up vergroot en daarmee zichtbaar.
Op iOS kan het wat ingewikkeld worden als een element selectors met :focus
én :hover
heeft. Dat is hier niet het geval, want alleen de a#linkje
heeft :focus
in de selector.
:active
Omdat :active
mogelijk niet werkt, als css uitstaat, ontbreekt of onvolledig is geïmplementeerd, moet je nooit belangrijke informatie alleen met behulp van :active
tonen.
Een element is actief, als de muis wordt ingedrukt boven dat element. Op sommige touchscreens is het element actief, als het wordt aangeraakt. In dit voorbeeld wordt :active
niet gebruikt.
De code aanpassen aan je eigen ontwerp
- Als je dit voorbeeld gaat aanpassen voor je eigen site, houd het dan in eerste instantie zo eenvoudig mogelijk. Ga vooral geen details invullen.
-
Gebruik vooral geen FrontPage, Publisher of Word (alle drie van Microsoft). Deze programma's maken niet-standaard code die alleen goed te bekijken is in Internet Explorer. In alle andere browsers zie je grotendeels bagger, áls je al iets ziet.
Publisher en Word zijn niet bedoeld om websites mee te maken. FrontPage is zwaar verouderd en wordt niet meer onderhouden door Microsoft.
Ook OpenOffice en LibreOffice leveren een uiterst beroerd soort html af. Tekstverwerkers met al hun toeters en bellen zijn gewoon niet geschikt om websites mee te bouwen.
Je kunt natuurlijk ook een goed gratis programma gebruiken. Links naar dat soort programma's vind je op de pagina met links onder Gereedschap → wysiwyg-editor.
Maar het allerbeste is om gewoon zelf html, css, enzovoort te leren, omdat zelfs het allerbeste programma het nog steeds zwaar verliest van 'n op de juiste manier met de hand gemaakte pagina.
-
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.
-
Ik maak zelf het liefst een site in Firefox. Als je 'n site maakt in Firefox, Opera, Safari, Google Chrome of Edge, is er 'n hele grote kans dat hij in alle browsers werkt. Ik geef de voorkeur aan Firefox, omdat het de enige grote browser is die niet bij een bedrijf hoort dat vooral op je centen of je data uit is.
Google Chrome wordt ook door veel mensen gebruikt, maar ik heb dus wat moeite met hoe Google je hele surfgedrag, je schoenmaat en de kleur van je onderbroek vastlegt. Daarom gebruik ik Google Chrome zelf alleen om in te testen.
-
Het allereerste dat je moet invoeren, is het doctype, vóór welke andere code dan ook. Een lay-out met een missend of onvolledig doctype ziet er totaal anders uit dan een lay-out met een geldig doctype. Wát er anders is, verschilt ook nog 'ns tussen de diverse browsers. Als je klaar bent en dan nog 'ns 'n doctype gaat invoeren, weet je vrijwel zeker dat je van voren af aan kunt beginnen met de lay-out.
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.
-
Gebruik een 'strict' doctype of (beter!) het doctype voor html5. Deze zijn bedoeld voor nieuwe sites. Het transitional doctype is bedoeld voor al bestaande sites, niet voor nieuwe.
Het transitional doctype staat talloze tags toe, die in html5 zijn verboden. Deze tags worden al zo'n tien jaar afgeraden. Het transitional doctype is echt alleen bedoeld om de puinhoop van vroeger, toen niet volgens standaarden werd gewerkt, enigszins te herstellen.
Het strict doctype staat verouderde tags niet toe. Daardoor kan met 'n strict doctype, of het nu html of xhtml is, probleemloos worden overgestapt naar html5. Met een transitional doctype en het gebruik van afgekeurde tags kun je niet overstappen naar html5. Je moet dan eerst alle verouderde tags verwijderen, wat echt ontzettend veel werk kan zijn.
Het doctype voor html5 is uiterst simpel:
<!DOCTYPE html>
. Omdat het doctype voor html5 in alle browsers werkt, zelfs in de gelukkig vrijwel uitgestorven nachtmerrie Internet Explorer 6, is er geen enkele reden dit uiterst simpele doctype niet te gebruiken. - Als tweede voer je de charset in. Dit vertelt de browser, welke tekenset er gebruikt moet worden, zodat letters met accenten en dergelijke overal goed worden weergegeven. Het beste kun je utf-8 nemen. Als je later van charset verandert, loop je 'n grote kans dat je alle aparte tekens als letters met accenten weer opnieuw moet gaan invoeren. In html5 is het simpele
<meta charset="utf-8">
voldoende. - Test vanaf het allereerste begin in zoveel mogelijk verschillende browsers in 'n aantal resoluties (schermgroottes). Onder het kopje Getest in kun je in deze uitleg vinden, waar dit voorbeeld in is getest. Ook van Internet Explorer kun je meerdere versies naast elkaar draaien. Op de pagina met links staan onder de kopjes Gereedschap → Meerdere versies van Internet Explorer draaien en Gereedschap → Weergave testen 'n aantal links die daarbij kunnen helpen. De compatibiliteitsweergave in Internet Explorer is niet geschikt om in te testen, omdat deze enigszins verschilt van de weergave in échte browsers.
- Voor alle voorbeelden geldt: breng veranderingen stapsgewijs aan. Als je bijvoorbeeld foto's wilt laten weergeven, begin dan met het alleen veranderen van de namen van de foto's, zodat je eigen foto's worden weergegeven. Maakt niet uit als de maten niet kloppen en de teksten fout zijn. Als dat werkt, ga dan bijvoorbeeld de maten aanpassen. Dan de teksten. En controleer steeds, of alles nog goed werkt.
-
Als het om een lay-out of iets dergelijks gaat: zorg eerst dat header, kolommen, footer, menu, en dergelijke staan en bewegen, zoals je wilt. Ga daarna pas details binnen die blokken invullen. In eerste instantie gebruik je dus bijvoorbeeld 'n leeg blok op de plaats, waar uiteindelijk het menu komt te staan.
Als je begint met allerlei details, is er 'n heel grote kans dat die de werking van de blokken gaan verstoren. Bouw eerst het huis, en ga dan pas de kamers inrichten. Zorg eerst dat de blokken werken, zoals je wilt. Dan zul je het daarna gelijk merken, als 'n toegevoegd detail als tekst of 'n afbeelding iets gaat verstoren. Daarvoor moet je natuurlijk wel regelmatig controleren in verschillende browsers, of alles nog wel goed werkt.
Je kunt de blokken tijdens het aanpassen opvullen met bijvoorbeeld <br>1<br>2<br>3 enzovoort, tot ze de juiste hoogte hebben. Het is handig om aan het einde even iets toe te voegen als 'laatste', zodat je zeker weet dat er niet ongemerkt drie regels onderaan naar 't virtuele walhalla zijn verhuisd.
Om de breedte te vullen, kun je het best 'n kort woord als 'huis' duizend keer of zo herhalen. Ook hier is het handig om aan 't eind (en hier ook aan 't begin) 'n herkenningsteken te maken, zodat je zeker weet dat je de hele tekst ziet.
- Zolang je in grotere dingen zoals 'n lay-out aan 't wijzigen bent, zou ik je aanraden de verschillende delen een achtergrondkleur te geven. Je ziet dan goed, waar 'n deel precies staat. Een achtergrondkleur heeft – anders dan bijvoorbeeld een border – verder geen invloed op de lay-out, dus die is hier heel geschikt voor.
- Als je instellingen verandert in de style, verander er dan maar één, hooguit twee tegelijk. Als je er zeventien tegelijk verandert, is de kans groot dat je niet meer weet, wat je hebt gedaan. En dat je 't dus niet meer terug kunt draaien.
-
margin, padding en border worden bij de hoogte en breedte van het element opgeteld. Hier worden vaak fouten mee gemaakt. Als je bijvoorbeeld in een lay-out 'n border toevoegt aan een van de 'hoofdvakken' (header, footer, kolommen), dan wordt deze er bij opgeteld. Bij 'n border van 2 px rondom de linkerkolom wordt deze dus plotseling 4 px breder (2 aan beide kanten), en 4 px hoger. Zoiets kan je hele lay-out verstoren, omdat iets net te breed of te hoog wordt. Je moet dan elders iets 4 px kleiner maken. Dat zal vaak zo zijn: als je één maat verandert, zul je vaak ook 'n andere moeten aanpassen.
Css geeft de mogelijkheid om met behulp van
box-sizing
padding en border bínnen de breedte en hoogte van de inhoud te zetten, als je dat handiger vindt. -
In plaats van een absolute eenheid als
px
kun je ook een relatieve eenheid gebruiken, met nameem
. Voordeel vanem
is dat een lettergrootte, regelhoogte, en dergelijke inem
in alle browsers kan worden veranderd. Nadeel is dat het de lay-out sneller kan verstoren dan bijvoorbeeldpx
. Dit moet je gewoon van geval tot geval bekijken. Voor weergave in mobiele apparaten zijn relatieve eenheden alsem
vrijwel altijd beter dan vaste eenheden alspx
.Zoomen kan trouwens altijd, ongeacht welke eenheid je gebruikt.
-
Valideren, valideren, valideren en dan voor 't slapen gaan nog 'ns valideren.
Valiwie???
Valideren is het controleren van je html en css op 'n hele serie fouten. Computers zijn daar vaak veel beter in dan mensen. Als je 300 keer <h2> hebt gebruikt en 299 keer </h2> vindt 'n computer die ene missende </h2> zonder enig probleem. Jij ook wel, maar daarna ben je misschien wel aan vakantie toe.
Valideren kan helpen om gekmakende fouten te vinden. Valide code garandeert ook dat de weergave in verschillende browsers (vrijwel) hetzelfde is. En valide code is over twintig jaar ook nog te bekijken.
Valideren moet trouwens ook niet worden overdreven. Het is een hulpmiddel om echte fouten te vinden, meer niet. Het gaat erom dat je site goed werkt, niet dat je het braafste kind van de klas bent. Als de code niet valideert, maar daar is een goede reden voor, is daar niets op tegen.
Op deze site is alle css en html gevalideerd. Als de code niet helemaal valide is (wat regelmatig voorkomt), staat daar onder Bekende problemen (en oplossingen) de reden van.
Je kunt je css en html valideren als 't online staat, maar ook als het nog in je computer staat.
html kun je valideren op: validator.w3.org/nu.
css kun je valideren op: jigsaw.w3.org/css-validator.
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:
-
Gebruik altijd een alt-beschrijving bij een afbeelding. De alt-tekst wordt gebruikt, als afbeeldingen niet kunnen worden getoond of gezien (dat geldt dus ook voor zoekmachines). Als je iets wilt laten zien, als je over de afbeelding hovert, gebruik daar dan het title-attribuut voor, niet de alt-beschrijving.
Als een afbeelding alleen maar voor de sier wordt gebruikt, zet je daarbij
alt=""
, om aan te geven dat de afbeelding niet belangrijk is voor het begrijpen van de tekst of zo. Dat kun je ook doen, als uit de tekst bij de afbeelding al duidelijk wordt, wat de afbeelding is. Een alt-tekst zou dan 'n beetje dubbelop zijn. - Als uit de tekst bij een link niet duidelijk blijkt, waar de link naartoe leidt, gebruik dan een title bij de link. Een tekst als 'pagina met externe links' is waarschijnlijk duidelijk genoeg, een tekst als alleen 'links' mogelijk niet. Een duidelijke zwart-witregel is niet te geven, omdat dit ook van tekst en dergelijke in de omgeving van de link afhangt.
-
Accesskeys (sneltoetsen) kun je beter niet gebruiken, deze geven te veel problemen, omdat ze vaak dubbelop zijn met sneltoetsen voor de browser of andere al gebruikte sneltoetsen. Bovendien is voor de gebruiker meestal niet duidelijk, welke toetsen het zijn.
Op zichzelf zijn accesskeys een heel goed idee. Maar helaas zijn ze ook in html5 volstrekt onvoldoende gedefinieerd. Er is nog steeds geen standaard voor de meest gebruikelijke accesskeys, zoals Zoek of Home.
Er is nog steeds niet vastgelegd, hoe accesskeys zichtbaar gemaakt kunnen worden. Voor de makers van browsers zou dit 'n relatief kleine moeite zijn, voor de makers van 'n site is het bergen extra werk.
Voor mij redenen om accesskeys (vrijwel) niet te gebruiken. Ik kan me wel voorstellen dat ze, op sites die gericht zijn op 'n specifieke groep gebruikers, nog enig nut kunnen hebben. Maar voor algemene sites zou ik zeggen: normaal genomen niet gebruiken.
-
Met behulp van de Tab-toets (of op 'n soortgelijke manier) kun je in de meeste browsers door links, invoervelden, en dergelijke lopen. Elke tab brengt je één link, invoerveld, en dergelijke verder, Shift+Tab één plaats terug. Met behulp van het attribuut
tabindex
kun je de volgorde aangeven, waarin de Tab-toets werkt. Zondertabindex
wordt de volgorde van de html aangehouden bij gebruik van de Tab-toets, maar soms is een andere volgorde logischer.In principe is het beter, als
tabindex
niet nodig is, maar gewoon de volgorde van de html wordt aangehouden. Bij verkeerd gebruik kantabindex
heel verwarrend zijn. Het is niet bedoeld om van de pagina een hindernisbaan voor kangoeroes te maken, waarop van beneden via links over rechts naar boven wordt gesprongen. - Als, zoals hierboven beschreven, een gebruiker van de Tab-toets bij een link, invoerveld, en dergelijke is aangekomen, wordt dit aangegeven door de link, invoerveld, en dergelijke extra te markeren met een kadertje. Dat kadertje mag je alleen weghalen, als op een andere manier wordt duidelijk gemaakt, welk element 'focus' heeft. Een gebruiker van de Tab-toets kan anders niet zien, waar zij of hij zit, en welk element gaat reageren op bijvoorbeeld een Enter.
- In het verleden werd vaak aangeraden de volgorde van de code aan te passen. Een menu bijvoorbeeld kon in de html onderaan worden gezet, terwijl het op het scherm met behulp van css bovenaan werd gezet. Inmiddels zijn schermlezers en dergelijke zo sterk verbeterd dat dit niet meer wordt aangeraden. De volgorde in de html kan tegenwoordig beter hetzelfde zijn als die op het scherm, omdat het anders juist verwarrend kan werken.
-
Een zogenaamde skip-link is wel vaak nog zinvol. Dat is een link die je buiten het scherm parkeert met behulp van css, zodat hij normaal genomen niet te zien is. Zo'n link is wel gewoon zichtbaar in speciale programma's zoals tekstbrowsers en schermlezers, want die kijken gewoon naar wat er in de broncode staat.
Een skip-link staat boven menu, header, en dergelijke en linkt naar de eigenlijke inhoud van de pagina, zodat mensen met één toetsaanslag naar de eigenlijke inhoud van de pagina kunnen gaan.
Een skip-link is vooral nuttig voor gebruikers van de Tab-toets. Zodra de normaal genomen onzichtbare link door het indrukken van de Tab-toets focus krijgt, kun je hem op het scherm plaatsen, waardoor hij zichtbaar wordt. Bij een volgende tab wordt hij dan weer buiten het scherm geplaatst en is dus niet meer zichtbaar, zodat de lay-out niet wordt verstoord.
Op pagina's en in voorbeelden waar dat nuttig is, wordt op deze site een skip-link gebruikt. (Althans: nog niet in alle voorbeelden die daarvoor in aanmerking komen, zit een skip-link. Maar geleidelijk aan worden dat er steeds meer.)
-
Van oorsprong is html een taal om wetenschappelijke documenten weer te geven, pas later is hij gebruikt voor lay-out. Maar daar is hij dus eigenlijk nooit voor bedoeld geweest. Het gebruiken van html voor lay-out leidt tot enorme problemen voor gehandicapten en tot een lage plaats in zoekmachines.
De html hoort alleen inhoud te bevatten, lay-out doe je met behulp van css. Die css moet in een externe stylesheet staan of, als hij alleen voor één bepaalde pagina van toepassing is, in de <head> van die pagina.
-
Breng een logische structuur aan in je document. Gebruik een <h1> voor de belangrijkste kop, een <h2> voor een subkop, enzovoort. Schermlezers en dergelijke kunnen van kop naar kop springen. En een zoekmachine gaat ervan uit dat <h1> belangrijke tekst bevat.
Dit geldt voor al dit soort structuurbepalende tags.
Als een <h1> te grote letters geeft, maak daar dan met behulp van je css 'n kleinere letter van, maar blijf die <h1> gewoon gebruiken. Op dezelfde manier kun je al dit soort dingen oplossen.
- <table> is fantastisch, maar alleen als die wordt gebruikt om een echte tabel weer te geven, niet als hij voor opmaak wordt misbruikt. In het verleden is dat op grote schaal gebeurd bij gebrek aan andere mogelijkheden. Een tabel is, als je niet heel erg goed oplet, volstrekt ontoegankelijk voor gehandicapten en zoekmachines. Het lezen van een tabel is ongeveer te vergelijken met het lezen van een krant van links naar rechts: niet per kolom, maar per regel. Dat gaat dus alleen maar goed bij een echte tabel, zoals een spreadsheet. In alle andere gevallen garandeert 'n tabel volstrekte ontoegankelijkheid voor schermlezers en dergelijke en als extra bonus vaak 'n lagere plaats in een zoekmachine.
-
Frames horen bij een volstrekt verouderde techniek, die heel veel nadelen met zich meebrengt. <iframe>'s hebben voor een deel dezelfde nadelen. Eén van die nadelen is dat de verschillende frames voor zoekmachines, schermlezers, en dergelijke als los zand aan elkaar hangen, omdat ze los van elkaar worden weergegeven. Ze staan wel naast elkaar op het scherm, maar er zit intern geen verband tussen.
Als je 'n stuk code vaker wilt gebruiken, zoals 'n menu dat op elke pagina hetzelfde is, voeg dat dan in met PHP of SSI. Dan wordt de pagina niet pas in de browser, maar al op de server samengesteld. Hierdoor zien zoekmachines, schermlezers, en dergelijke één pagina, net zoals wanneer je maar één pagina met html zou hebben geschreven.
(Je kunt beter PHP dan SSI gebruiken, omdat SSI min of meer aan het uitsterven is en PHP veel meer mogelijkheden heeft. Op deze site wordt in enkele voorbeelden nog SSI gebruikt, maar zodra die worden bijgewerkt, gaat dat vervangen worden door PHP.)
- Geef de taal van het document aan, en bij woorden en dergelijke die afwijken van die taal de afwijkende taal met behulp van
lang="..."
. Op deze site gebeurt dat maar af en toe, omdat de tekst (en vooral de code) een mengsel is van Engels, Nederlands en eigengemaakte namen. Dat soort teksten is gewoon niet goed in te delen in een taal. Maar bij enigszins 'normale' teksten hoor je een taalwisseling aan te geven. - Gebruik de tag <abbr> bij afkortingen. Doe dat de eerste keer op een pagina samen met de title-eigenschap:
<abbr title="ten opzichte van">t.o.v.</abbr>
. Daarna kun je op dezelfde pagina volstaan met<abbr>t.o.v.</abbr>
. Doe je dit niet, dan is er 'n grote kans dat 'n schermlezer 't.o.v.' uit gaat spreken als 'tof', en 'n zoekmachine kan er ook geen chocola van maken. -
De spider van 'n zoekmachine, schermlezers, en dergelijke kunnen geen plaatjes 'lezen'. Het is soms verbazingwekkend om te zien hoe veel, of eigenlijk: hoe weinig tekst er overblijft op een pagina, als de plaatjes worden weggehaald. Hetzelfde geldt voor die fantastisch mooie flash-pagina's, als daarbij geen voorzieningen voor dit soort programma's zijn aangebracht.
Op Linux kun je met Lynx kijken, hoe je pagina eruitziet zonder plaatjes en dergelijke, als echt alleen de tekst overblijft. Een installatie-programma voor Lynx op Windows is te vinden op invisible-island.net/lynx.
Ook kun je in Windows het gratis programma WebbIE installeren. WebbIE laat de pagina zien, zoals een tekstbrowser en dergelijke hem zien. WebbIE is te downloaden vanaf www.webbie.org.uk.
-
Ten slotte kun je je pagina nog online laten controleren op 'n behoorlijk aantal sites, zoals:
lowvision.support Laat zien hoe een kleurenblinde de site ziet. Engelstalig.
wave.webaim.org Deze laat grafisch zien hoe de toegankelijkheid is. Engelstalig.
Op de pagina met links kun je onder Toegankelijkheid links naar testen en dergelijke vinden.
Specifiek voor dit voorbeeld
JavaScript
Er wordt geen JavaScript gebruikt, dus het aan- of uitstaan van JavaScript heeft geen invloed.
CSS
Zonder css zie je de tekst uit de uitleg bovenin, een (overbodig) aankruisvakje, het vraagteken, de link en ten slotte de Latijnse tekst.
In de link staat de tekst die op de achtergrond-afbeelding in de pop-up is te zien, want dat is gewoon de tekst uit de link. Maar de achtergrond-afbeelding zelf ontbreekt.
Afbeeldingen
Zonder afbeeldingen werkt alles gewoon, alleen – je zult het niet geloven – mist de achtergrond-afbeelding.
Gebruikers Tab-toets
Omdat de pop-up in een gewone <a> staat, kan de pop-up worden getoond als de <a> focus krijgt. De <a> werkt verder zoals elke gewone <a>: een Enter laat de link volgen, het indrukken van de Tab-toets laat de <a> de focus weer verliezen (en laat daarmee de pop-up weer verdwijnen).
Tekstbrowsers
Lynx toont de pagina op dezelfde manier als iets hierboven bij CSS is beschreven. Voor WebbIE geldt hetzelfde, maar die laat aankruisvakje en vraagteken niet zien.
Schermlezers
De link wordt in alle schermlezers aangekondigd, kan worden gevolgd en de tekst uit de link wordt voorgelezen. De pop-up wordt niet in alle schermlezers getoond. Een vollediger overzicht van problemen staat bij Schermlezers.
Voor VoiceOver op iOS is bij label#uitleg
en main div
een negatieve tabindex aangebracht, omdat de pop-up anders moeilijk is te sluiten. Meer daarover is te vinden bij Verder blijkt de schermlezer...
input#open
, label#vraagteken
en label#sluit
zijn met behulp van de WAI-ARIA-code aria-hidden="true"
verborgen voor schermlezers.
TalkBack op Android is nogal kieskeurig. De link moet op het scherm staan, minstens 1 x 1 px groot zijn, en nog wat dingen. Het hele verhaal staat bij De schermlezer TalkBack...
Getest in
Laatst gecontroleerd op 31 juli 2017.
Onder dit kopje staat alleen maar, hoe en waarin is getest. Eventuele problemen, ook die met betrekking tot zoomen en lettergroottes, staan hieronder bij Bekende problemen (en oplossingen). Het is belangrijk dat deel te lezen, want uit een test kan ook prima blijken dat iets totaal niet werkt!
Eventuele opmerkingen over de toegankelijkheid specifiek voor dit voorbeeld staan hierboven bij Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.
Dit voorbeeld is getest op de volgende systemen:
Desktopcomputers
Windows 7 (1280 x 1024 px, resolution: 96 dpi):
Firefox, UC Browser, Google Chrome en Internet Explorer 11, in grotere en kleinere browservensters.
OS X 10.11.6 ('El Capitan') (1680 x 1050 px, resolution: 96: dpi, device-pixel-ratio: 1):
Firefox, Safari en Google Chrome, in grotere en kleinere browservensters.
Linux (Kubuntu 14.04 LTS, 'Trusty Tahr') (1280 x 1024 px, resolution: 96 dpi):
Firefox en Google Chrome, in grotere en kleinere browservensters.
Laptops
Windows 8.1 (1366 x 768 px, resolution: 96 dpi):
Bureaublad-versie: Firefox, UC Browser, Google Chrome en Internet Explorer 11, in grotere en kleinere browservensters.
Startscherm-versie: Internet Explorer 11.
Windows 10 (1600 x 900 px, resolution: 96 dpi):
Firefox, UC Browser, Google Chrome, Internet Explorer 11, Edge, in grotere en kleinere browservensters.
Tablets
iPad met iOS 9.3.5 (1024 x768 px, device-pixel-ratio: 1):
Safari, Chrome for iOS, UC Browser, Firefox (alle portret en landschap).
Opera Mini (Opera Turbo) portret en landschap.
iPad met iOS 10.3.3 (2048 x 1536 px, device-pixel-ratio: 2 ('retina'):
Safari, Chrome for iOS, UC browser, Firefox (alle portret en landschap).
Opera Mini (Opera Turbo) portret en landschap.
Android 4.4.2 ('Kitkat') (1280 x 800 px, resolution: 96 dpi):
Android browser, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.
Android 4.4.2 ('Kitkat') (2560 x 1600 px, resolution: 192 dpi):
Android browser, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.
Android 6 ('Marshmallow') (1920 x 1200 px, resolution: 144 dpi):
Dolphin, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.
Android 7.0 ('Nougat') (1920 x 1200 px, resolution: 144 dpi):
Dolphin, Samsung Internet, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.
Smartphones
Windows Phone 8.1 (800 x 480 px, resolution: 136 dpi):
Internet Explorer en UC browser (portret en landschap).
Windows 10 Mobile (1280 x 720 px, resolution: 192 dpi):
Edge en UC browser (portret en landschap).
Android 4.1.2 ('Jelly Bean') (800 x 480 px, resolution: 144 dpi):
Chrome, Android browser, UC Browser en Firefox (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.
Android 7.0 ('Nougat') (1280 x 720 px, resolution: 192 dpi):
Dolphin, Samsung Internet, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (besparingen uitgeschakeld) portret en landschap.
Er is op de aan het begin van dit hoofdstukje genoemde controledatum getest in de meest recente versie van de browser, die op het betreffende besturingssysteem kon draaien. Het aantal geteste browsers en systemen is al tamelijk fors, en als ook nog rekening gehouden moet worden met (zwaar) verouderde browsers, is het gewoon niet meer te doen. Surfen met een verouderde browser is trouwens vragen om ellende, want updates van browsers hebben heel vaak met beveiligingsproblemen te maken.
In- en uitzoomen en – voor zover de browser dat kan – een kleinere en grotere letter zijn ook getest. Er is ingezoomd en vergroot tot zover de browser kan, maar niet verder dan 200%.
Er is getest met behulp van muis en toetsenbord, behalve op de iPad, Android, Windows Phone en Windows 10 Mobile, waar een touchscreen is gebruikt. Op Windows 8.1 en 10 is getest met een touchscreen, met een combinatie van toetsenbord en touchpad, en met een combinatie van toetsenbord en muis.
Als dat relevant is, is op de desktop ook getest, als JavaScript uitstaat. Eventuele problemen staan hierboven bij Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld. (Op iOS, Android, Windows Phone en Windows 10 Mobile is niet getest zonder JavaScript, omdat je JavaScript in een toenemend aantal mobiele browsers niet uit kunt zetten. Bovendien is een mobiel apparaat zonder JavaScript niet veel meer dan een duur en groot uitgevallen horloge.)
Schermlezers en dergelijke
Naast deze 'gewone' browsers is ook getest in Lynx, WebbIE, NVDA, TalkBack, VoiceOver en ChromeVox.
Lynx is een browser die alleen tekst laat zien en geen css gebruikt. Er is getest op Linux.
WebbIE is een browser die gericht is op mensen met een handicap. Er is getest op Windows 7.
NVDA is een schermlezer, zoals die door blinden wordt gebruikt. Er is getest op Windows 7 in combinatie met Firefox, Google Chrome en Internet Explorer, en op Windows 10 in combinatie met Firefox, Google Chrome en Edge.
TalkBack is een in Android ingebouwde schermlezer. Er is getest in combinatie met Chrome op Android 4.4,2, 5.0.1 en 7.0.
VoiceOver is een in iOS en OS X ingebouwde schermlezer. Er is getest in combinatie met Safari op iOS (9.3.5 en 10.3.2) en OS X 10.11.6.
ChromeVox is een schermlezer in de vorm van een extensie bij Google Chrome. Er is getest op een systeem met Kubuntu Linux 14.04.
Als het voorbeeld in deze programma's toegankelijk is, zou het in principe toegankelijk moeten zijn in alle aangepaste browsers en dergelijke. En dus ook voor zoekmachines, want een zoekmachine is redelijk vergelijkbaar met een blinde. Eventuele opmerkingen over de toegankelijkheid specifiek voor dit voorbeeld staan hierboven bij Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.
Alleen op de hierboven genoemde systemen en browsers is getest. Er is dus niet getest op bijvoorbeeld 'n Blackberry. De kans is (heel erg) groot dat dit voorbeeld niet (volledig) werkt op niet-geteste systemen en apparaten. Om het wel (volledig) werkend te krijgen, zul je vaak (kleine) wijzigingen en/of (kleine) aanvullingen moeten aanbrengen, bijvoorbeeld met JavaScript.
Er is ook geen enkele garantie dat iets werkt in een andere tablet of smartphone dan hierboven genoemd, omdat fabrikanten in principe de software kunnen veranderen. Dit is anders dan op de desktop, waar browsers altijd (vrijwel) hetzelfde werken, zelfs op verschillende besturingssystemen. Iets wat in Android browser werkt, zal in de regel overal werken in die browser, maar een garantie is er niet. De enige garantie is het daadwerkelijk testen op een fysiek apparaat. En aangezien er duizenden mobiele apparaten zijn, is daar eigenlijk geen beginnen aan.
De html is gevalideerd met de validator van w3c, de css ook. Als om een of andere reden niet volledig gevalideerd kon worden, wordt dat bij Bekende problemen (en oplossingen) vermeld.
Nieuwe browsers worden pas getest, als ze uit het bèta-stadium zijn, omdat er anders 'n redelijke kans is dat je tegen 'n bug zit te vechten, die voor de uiteindelijke versie nog gerepareerd wordt. Dit voorbeeld is alleen getest in de hierboven met name genoemde browsers. Vragen over niet-geteste browsers kunnen niet worden beantwoord, en het melden van fouten in niet-geteste browsers heeft ook geen enkel nut. (Melden van fouten, problemen, enzovoort in wel geteste browsers: graag!)
Bekende problemen (en oplossingen)
Waarop en hoe is getest, kun je gelijk hierboven vinden bij Getest in.
Als je hieronder geen oplossing vindt voor een probleem dat met dit voorbeeld te maken heeft, kun je op het forum proberen een oplossing te vinden voor je probleem. Om forumspam te voorkomen, moet je je helaas wel registreren, voordat je op het forum een probleem kunt aankaarten.
Opera Mini op iOS, Dolphin op Android voor versie 6, Opera Mini en sommige versies van Android Browser op Android 4
De link wordt gelijk gevolgd, waardoor de pop-up niet of heel kort is te zien.
(De 'sommige versies' van Android browser op Android 4: op de tablet met 96 dpi werkt het niet goed, op de tablet met 192 dpi werkt het wel goed.)
Als het vraagteken wordt aangeraakt, komt de link met de pop-up boven het vraagteken te staan. In een aantal browsers wordt deze link gelijk gevolgd. Kennelijk wordt op een of andere manier de aanraking van de <p> met het vraagteken doorgegeven aan de gelijk daarna op dezelfde plek verschijnende <a> met de pop-up.
Met behulp van transition-delay: 0.25s; opent de link met de pop-up met een vertraging van 'n kwart seconde. Dat is zo kort, dat je het nauwelijks merkt. Voor de meeste browsers is deze vertraging voldoende. (Voor Edge bijvoorbeeld is zelfs 'n vertraging van 0,01 seconde al genoeg).
Voor de hierboven genoemde browsers is deze vertraging niet voldoende. Voor Opera Mini op iOS is 'n vertraging van 'n halve seconde nodig, en voor de andere browsers zelfs 0,7 seconde. Dat is te lang, want dat levert echt 'n hinderlijk lange vertraging op.
De enige oplossing zou zijn de <a> met de pop-up niet over de <p> met het vraagteken te openen, maar eronder of ernaast. In dat geval werkt het in alle browsers, zelfs als er helemaal geen vertraging zou zijn.
(Overigens opent de pop-up wel, als je het vraagteken langer aanraakt. Maar dat is natuurlijk geen echte oplossing, want alleen telepathisch hoogbegaafden weten dat.)
Dit illustreert ook weer, waarom je geen belangrijke informatie in een pop-up moet verstoppen.
Schermlezers
Op welke combinaties van browsers en schermlezers precies is getest, is iets hierboven te vinden bij Getest in.
In alle schermlezers wordt de link aangekondigd en wordt de tekst uit de link voorgelezen.
ChromeVox
Alles werkt, zoals het is bedoeld, zowel bij het lezen van de hele pagina als bij het van element naar element gaan. De pop-up wordt gesloten en geopend en de link kan worden gevolgd.
NVDA
Als de hele pagina wordt gelezen, opent de pop-up niet. De link kan wel worden gevolgd, met uitzondering van NVDA in combinatie met Edge (de sneltoetsen om naar een link te gaan werken wel). Als element voor element wordt gelezen, wordt de pop-up getoond en verborgen en kan de link worden gevolgd.
TalkBack
In TalkBack kan de link altijd worden gevolgd, maar de pop-up wordt nooit getoond.
VoiceOver op iOS
Bij het lezen van de hele pagina wordt de pop-up niet getoond en kan de link niet worden gevolgd. De pop-up wordt wel getoond en de link kan wel worden gevolgd, als je van element naar element gaat.
VoiceOver op OS X
Als van element naar element wordt gegaan, werkt alles, zoals het is bedoeld. De pop-up wordt gesloten en geopend en de link kan worden gevolgd.
Bij lezen van de hele pagina wordt de pop-up geopend en kan de link worden gevolgd, maar de pop-up wordt niet gesloten. Als Enter wordt ingedrukt, wordt de link gevolgd, ook als de Latijnse tekst al wordt voorgelezen. Door het indrukken van de Tab-toets wordt de pop-up gesloten en wordt de link niet meer gevolgd.
Wijzigingen
Alleen grotere wijzigingen worden hier vermeld, geen dingen als een link die is geüpdatet.
:
Nieuw opgenomen.
31 juli 2017:
Omdat de code en de uitleg volledig zijn herschreven, zijn eerdere wijzigingen weggehaald. De wijzigingen zijn zelf ook weer overherverwijzigd, waardoor de lijst met wijzigingen vrij nutteloos is geworden.
- De code is fors aangepast, waardoor het nu ook werkt op touchscreens.
- Alle aanpassingen voor Internet Explorer 10 en eerder verwijderd.
- Tig kleine veranderingen in de tekst.
- Doctype veranderd van xhtml naar html5.
- Toegankelijkheid verbeterd ('n overzichtje staat bij Specifiek voor dit voorbeeld).
- Aantal nieuwe hoofdstukken, vooral over touchscreens en toegankelijkheid.
- Latijnse opvultekst en korte uitleg bovenaan toegevoegd.
- Openen en sluiten van de pop-up wordt nu geregeld met behulp van een <input> met twee bijbehorende <label>'s, omdat dit beter werkt op iOS.
- Link en pop-up zijn nu bij openen van de pagina beide onzichtbaar. Pas na activeren van het vraagteken, zijn ze zichtbaar. De pop-up staat niet meer links buiten het scherm, maar wordt verborgen onder het vraagteken. (Als de link buiten het scherm staat, blijkt de link niet te werken in de schermlezer TalkBack op Android.)
Inhoud van de download en licenties
De inhoud van deze download kan vrij worden gebruikt, met drie beperkingen:
* Sommige onderdelen die van 'n andere site of zo afkomstig zijn, vallen mogelijk onder een of andere licentie. Dat is hieronder bij het betreffende onderdeel te vinden.
* Je gebruikt het materiaal uit deze download volledig op eigen risico. Het kan prima zijn dat er fouten in de hier verstrekte code en dergelijke zitten. Voor eventuele schade die door gebruik van materiaal uit deze download ontstaat, in welke vorm dan ook, zijn www.css-voorbeelden.nl en medewerkers daarvan op geen enkele manier verantwoordelijk.
* Dit voorbeeld (en de bijbehorende uitleg en dergelijke) wordt regelmatig bijgewerkt. Het is daarom niet toegestaan dit voorbeeld (en de bijbehorende uitleg en dergelijke) op welke manier dan ook te verspreiden, zonder daarbij duidelijk te vermelden dat voorbeeld, uitleg, en dergelijke afkomstig zijn van www.css-voorbeelden.nl en dat daar altijd de nieuwste versie is te vinden. Dit is om te voorkomen dat er verouderde versies worden verspreid.
Een link naar www.css-voorbeelden.nl wordt trouwens altijd op prijs gesteld.
pop-up-026-dl.html: de pagina met het voorbeeld.
pop-up-026.pdf: deze uitleg (aangepast aan de inhoud van de download).
pop-up-026-inhoud-download-en-licenties.txt: een kopie van de tekst onder dit kopje (Inhoud van de download en licenties).
026-css-dl:
pop-up-026-dl.css: stylesheet voor pop-up-026-dl.html.
026-pics:
026-pics: rapunzel.jpg: de gebruikte achtergrond-afbeelding. De afbeelding is afkomstig van wpclipart.com en mag zonder beperking worden gebruikt.
HTML
De code is geschreven in een afwijkende
lettersoort. De code die te maken heeft met de basis van dit voorbeeld (essentiële code), is in de hele uitleg onderstippeld blauw
. 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, kun je bovenaan de pagina de hele handel 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 (ä
en dergelijke) te gebruiken, maar kun je bijvoorbeeld gewoon ä gebruiken.
Deze regel moet zo hoog mogelijk komen te staan, als eerste regel binnen de <head>, omdat hij anders door sommige browsers niet wordt gelezen.
In html5 hoeft deze regel niet langer te zijn, dan wat hier staat.
<meta name="viewport" content="width=device-width, initial-scale=1">
Mobiele apparaten variëren enorm in breedte. En dat is een probleem. Sites waren, in ieder geval tot voor kort, gemaakt voor desktopbrowsers. En die hebben, in vergelijking met bijvoorbeeld een smartphone, heel brede browservensters. Hoe moet je op 'n smartphone een pagina weergeven, die is gemaakt voor de breedte van een desktop? Je kunt natuurlijk wachten tot álle sites zijn omgebouwd voor smartphones, tablets, enzovoort, maar dan moet je waarschijnlijk heel erg lang wachten.
Mobiele browsers gokken erop dat een pagina een bepaalde breedte heeft. Safari voor mobiel bijvoorbeeld gaat ervan uit dat een pagina 980 px breed is. De pagina wordt vervolgens zoveel versmald dat hij binnen het venster van het apparaat past. Op een iPhone wordt de pagina dus veel smaller dan op een iPad. Vervolgens kan de gebruiker inzoomen op het deel van de pagina dat hij of zij wil zien.
Dit betekent ook dat bij het openen van de pagina de tekst meestal heel erg klein wordt weergegeven. (Meestal, want niet alle browsers en apparaten doen het op dezelfde manier.) Niet erg fraai, maar bedenk maar 'ns 'n betere oplossing voor bestaande sites.
Nieuwe sites of pagina's kunnen echter wel rekening houden met de veel kleinere vensters van mobiele apparaten. In dit voorbeeld wordt de tekst nooit breder dan het venster. Maar die stomme mobiele browser weet dat niet, dus die gaat ervan uit dat ook deze pagina 980 px breed is, en verkleint die dan. Dat is ongeveer even behulpzaam als de gedienstige kelner die behulpzaam de stoel naar achteren trekt, net als jij wilt gaan zitten.
Om de door de browser aangeboden hulp vriendelijk maar beslist te weigeren, wordt deze tag gebruikt. Hiermee geef je aan dat de pagina is geoptimaliseerd voor mobiele apparaten.
Een iPad in portretstand bijvoorbeeld is 768 px breed. De kreet width=device-width
zegt tegen de mobiele browser dat de breedte van de weer te geven pagina gelijk is aan de breedte van het apparaat. Voor een iPad in portretstand dus 768 px.
Er staat nog een tweede deel in de tag: initial-scale=1
. Sommige mobiele apparaten zoomen een pagina gelijk in of uit. Ook weer in een poging behulpzaam te zijn. Ook dat is hier niet nodig. Er is ook een instructie om zoomen helemaal onmogelijk te maken, maar die gebruik ik niet. De bezoeker kan zelf nog gewoon zoomen, wat belangrijk is voor mensen die wat slechter zien.
<link rel="stylesheet" href="026-css-dl/pop-up-026-dl.css">
Dit is een koppeling naar een externe stylesheet (stijlbestand), waarin de css staat. In html5 is de toevoeging type="text/css"
niet meer nodig, omdat dit standaard al zo staat ingesteld. Je moet uiteraard de naam van en het pad naar de stylesheet aanpassen aan de naam en plaats, waar je eigen stylesheet staat.
Voordeel van een externe stylesheet is onder andere dat deze geldig is voor alle pagina's, waaraan deze is gelinkt. 'n Verandering in de lay-out hoef je dan maar in één enkele stylesheet aan te brengen, in plaats van in elke pagina apart. Op een grotere site kan dit ontzettend veel werk schelen. Bovendien hoeft de browser zo'n externe stylesheet maar één keer te downloaden, ongeacht hoeveel pagina's er gebruik van maken. Zou je de css in elke pagina opnieuw aanbrengen, dan worden de te downloaden bestanden veel groter.
In dit voorbeeld heeft een extern stylesheet eigenlijk geen nut, omdat er maar één pagina is die dit stylesheet gebruikt. In dit geval kun je de css beter in de <head> van de html-pagina zelf zetten. Voor de omvang maakt het hier niets uit, want de css wordt hoe dan ook altijd precies één keer gedownload, en nooit vaker. Voor het onderhoud maakt het ook geen verschil, want ook hier hoef je de css maar op één plaats te wijzigen. Maar het scheelt wel een extra aanroep naar de server, omdat geen apart stylesheet hoeft te worden gedownload.
Dat opnemen in de <head> gaat heel simpel: je kopieert gewoon het hele stylesheet en zet die bovenin de <head>, tussen <style> en </style>:
<style>
body {color: black;}
(...) rest van de css (...)
div {color: red;}
</style>
Maar zodra een stylesheet op meerdere pagina's wordt gebruikt, wat meestal het geval zal zijn, is een extern stylesheet beter.
(De reden dat er toch een extern stylesheet is, terwijl hierboven omstandig wordt beweerd dat dat in dit voorbeeld eigenlijk geen nut heeft: overzichtelijkheid. Nu kun je html en css los van elkaar bekijken.)
<p id="uitleg" tabindex="-1">Als je met de cursor boven het vraagteken gaat hangen, het vraagteken aanraakt, of de Tab-toets gebruikt, verschijnt een link naar en voorbeeld van een afbeelding op wpclipart.com.</p>
Dit is de <p> bovenaan de pagina, waarin een kleine uitleg staat.
Als je in de schermlezer VoiceOver op iOS van element naar element gaat, opent de pop-up als a#linkje
wordt bereikt. Als je dan echter weer naar het vorige element gaat, sluit de pop-up niet meer.
Het eerste element boven a#linkje
is p#uitleg
, want de tussenliggende input#open
en label#vraagteken
zijn met behulp van de WAI-ARIA-code aria-hidden="true"
voor schermlezers verborgen. Als aan p#uitleg
een negatieve tabindex wordt gegeven, blijkt hierdoor a#linkje
met de pop-up ook in VoiceOver op iOS weer te sluiten, als je naar het vorige element gaat.
<input id="open" type="checkbox" tabindex="-1" aria-hidden="true">
Dit is de <input> die bij de twee <label>'s hoort, waarmee de pop-up wordt geopend en gesloten.
Deze <input> is eigenlijk niet echt nodig. Zichtbaar is hij niet, want hij wordt verborgen onder het vraagteken en wordt uit- en aangevinkt via de bijbehorende twee <label>'s. Van dat uit- en aanvinken (:checked
) wordt geen enkel gebruikt gemaakt, vandaar dat de <input> eigenlijk overbodig is.
<label>'s zonder bijbehorende <input> of iets soortgelijks kunnen zich echter wat onvoorspelbaar gedragen. De specificatie is er wat vaag over. Om problemen te voorkomen, is daarom voor de zekerheid gewoon een <input> gebruikt.
Deze <input> heeft geen enkel nut voor schermlezers en is daarom met behulp van de WAI-ARIA-code aria-hidden="true"
voor schermlezers verborgen.
Ook voor gebruikers van de Tab-toets heeft deze <input> geen nut, daarom is deze voor de Tab-toets verborgen met behulp van het attribuut tabindex="-1"
. Dit verbergt tevens de bij deze <input> horende label#vraagteken
en label#sluit
voor de Tab-toets.
<label id="vraagteken" for="open" aria-haspopup="true" aria-hidden="true">?</label>
De <label> waarin het vraagteken zit. Door aanraken of -klikken van of hoveren over deze <label> opent de pop-up. Met behulp van for="open"
is de <label> gekoppeld aan input#open
.
Aan deze <p> is aria-haspopup="true"
toegevoegd, omdat de pop-up anders niet goed opent in Internet Explorer en Edge op touchscreens. Meer hierover bij WAI-ARIA-codes.
Deze <label> heeft geen enkel nut voor schermlezers en is daarom met behulp van de WAI-ARIA-code aria-hidden="true"
voor schermlezers verborgen.
<label id="sluit"></label>
Met behulp van for="open"
is de <label> gekoppeld aan input#open
. Deze <label> is helemaal leeg en normaal genomen onzichtbaar. De <label> is nodig om de pop-up in Safari, UC browser en Chrome op iOS te kunnen sluiten. Er is meer over te vinden bij :hover.
<div tabindex="-1">
De <div> waarin de <p>'s met de Latijnse tekst zitten.
Als je in de schermlezer VoiceOver op iOS van element naar element gaat, opent de pop-up als a#linkje
wordt bereikt. Als je dan echter verder naar het volgende element gaat, sluit de pop-up niet meer.
Het eerste element na a#linkje
is deze <div>, want de tussenliggende label#sluit
is met behulp van de WAI-ARIA-code aria-hidden="true"
voor schermlezers verborgen. Als aan deze <div> een negatieve tabindex wordt gegeven, blijkt hierdoor a#linkje
met de pop-up ook in VoiceOver op iOS weer te sluiten, als je naar het volgende element gaat.
<p lang="la">Lorem ipsum dolor (...) Aenean massa.</p>
Als opvultekst is Latijnse tekst gebruikt. De taal is van belang voor schermlezers, automatisch afbreken, automatisch genereren van aanhalingstekens, juist gebruik van decimale punt of komma, en dergelijke. Daarom wordt met lang="la"
aangegeven dat de tekst binnen deze <p> Latijn is. (En tot mijn niet geringe verbazing blijkt een schermlezer als NVDA dat dan, voor zover ik dat kan beoordelen, op de juiste manier voor te lezen.)
CSS
De code is geschreven in een afwijkende
lettersoort. De code die te maken heeft met de basis van dit voorbeeld (essentiële code) is in de hele uitleg onderstippeld blauw
. 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, kun je bovenaan de pagina de hele handel downloaden. In de download zit 'n voorbeeld dat wel naadloos aansluit op de uitleg in de download.
Technisch gezien is er geen enkel bezwaar om de css in de stylesheet allemaal achter elkaar op één regel te zetten:
div#header-buiten {position: absolute; right: 16px; width: 100%; height: 120px; background: yellow;} div p {margin-left 16px; height: 120px; text-align: center;}
Maar als je dat doet, garandeer ik je hele grote problemen, omdat het volstrekt onoverzichtelijk is. Beter is het om de css netjes in te laten springen:
div#header-buiten {
position: absolute;
right: 16px;
width: 100%;
height: 120px;
background: yellow;
}
div p {
margin-left: 16px;
height: 120px;
text-align: center;
}
Hiernaast is het heel belangrijk voldoende commentaar (uitleg) in de stylesheet te schrijven. Op dit moment weet je waarschijnlijk (hopelijk...), waarom je iets doet. Maar over vijf jaar kan dat volstrekt onduidelijk zijn. Op deze site vind je nauwelijks commentaar in de stylesheets, maar dat heeft een simpele reden: deze uitleg is in feite één groot commentaar.
Op internet zelf is het goed, als de stylesheet juist zo klein mogelijk is. Dus voor het uploaden kun je normaal genomen het beste het commentaar weer verwijderen. Veel mensen halen zelfs alles wat overbodig is weg, voordat ze de stylesheet uploaden. Inspringingen bijvoorbeeld zijn voor mensen handig, een computer heeft ze niet nodig.
Je hebt dan eigenlijk twee stylesheets. De uitgebreide versie waarin je dingen uitprobeert, verandert, enzovoort, met commentaar, inspringingen, en dergelijke. Dat is de mensvriendelijke versie. Daarnaast is er dan een stylesheet die je op de echte site gebruikt: een gecomprimeerde versie.
Dat comprimeren kun je met de hand doen, maar er bestaan ook hulpmiddelen voor. Op de pagina met links kun je onder Gereedschap → Snelheid, testen, gzip, comprimeren links naar sites vinden, waar je bestanden kunt comprimeren.
(Stylesheets op deze site zijn niet gecomprimeerd. Omdat het vaak juist om de css gaat, wil ik dat mensen zonder al te veel moeite de css kunnen bekijken.)
css voor alle vensters
/* pop-up-026-dl.css */
Om vergissingen te voorkomen is het een goede gewoonte bovenaan het stijlbestand even de naam neer te zetten. Voor je het weet, zit je anders in het verkeerde bestand te werken.
body
Het element waarbinnen de hele pagina staat. Veel instellingen die hier worden opgegeven, worden geërfd door de nakomelingen van <body>. Ze gelden voor de hele pagina, tenzij ze later worden gewijzigd. Dit geldt bijvoorbeeld voor de lettersoort, de lettergrootte en de voorgrondkleur.
background: #ff9;
Achtergrondkleurtje.
color: black;
Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.
Hoewel dit de standaardkleur is, wordt deze toch specifiek opgegeven. Hierboven is een achtergrondkleur opgegeven. Sommige mensen hebben zelf de voorgrond‑ en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als nu de achtergrondkleur wordt veranderd, maar niet de voorgrondkleur, loop je het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.
Door beide op te geven, is redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important
heeft gebruikt in een eigen stylesheet, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.
font-family: Arial, Helvetica, sans-serif;
Als Arial is geïnstalleerd op de machine van de bezoeker, wordt deze gebruikt, anders Helvetica. Als die ook niet wordt gevonden, wordt in ieder geval een schreefloze letter (zonder dwarsstreepjes) gebruikt.
margin: 0; padding: 0;
Slim om te doen vanwege verschillen tussen browsers.
#uitleg
Het element met id="uitleg". Dit is de <p>, waarbinnen de korte uitleg bovenaan de pagina zit.
background: white;
Witte achtergrond.
color: black;
Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.
Hoewel dit de standaardkleur is, wordt deze toch specifiek opgegeven. Hierboven is een achtergrondkleur opgegeven. Sommige mensen hebben zelf de voorgrond‑ en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als nu de achtergrondkleur wordt veranderd, maar niet de voorgrondkleur, loop je het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.
Door beide op te geven, is redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important
heeft gebruikt in een eigen stylesheet, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.
Dit is ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.
width: 300px;
300 px breed. Dit past in zo'n beetje elk browservenster, of het moet echt absurd smal zijn. Hierdoor hoeven er geen aanpassingen voor bredere en smallere vensters gemaakt te worden.
Omdat de <p> een blok-element is, wordt de hoogte automatisch hoog genoeg om de erin zittende tekst weer te geven.
text-align: center;
Tekst horizontaal centreren.
margin: 10px auto 0;
Omdat voor links geen waarde is ingevuld, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 10px auto 0 auto
in de volgorde boven – rechts – onder – links.
Kleine afstand tussen de bovenkant van het browservenster en de bovenkant van de <p>. Links en rechts auto
, wat hier hetzelfde betekent als evenveel. Hierdoor staat de <p> altijd horizontaal gecentreerd binnen z'n ouder <main>. <main> is een blok-element en wordt daarom normaal genomen even breed als z'n ouder <body>, ook een blok-element. Dat dus normaal genomen weer even breed wordt als z'n ouder <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster.
Uiteindelijk wordt <main> dus ook even breed als het venster van de browser en staat de <p> horizontaal gecentreerd binnen het venster, ongeacht de breedte van het venster.
Deze manier van horizontaal centreren van een blok-element werkt alleen, als het te centreren element een breedte heeft.
border: black solid 1px;
Zwart randje.
padding: 3px;
Kleine afstand tussen rand van en tekst in <p>.
#open
Het element met id="open". De <input> die hoort bij de twee <label>'s die openen en sluiten van de pop-up regelen.
display: block;
Een <input> is van zichzelf een inline-element. Daardoor werkt de hier gelijk onder gebruikte marge niet. Door van de <input> een blok-element te maken, kan de marge wel worden gebruikt.
margin: 20px auto 0;
Omdat voor links geen marge is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 20px auto 0 auto
in de volgorde boven – rechts – onder – links.
Aan de bovenkant een kleine marge voor wat afstand tot p#uitleg
erboven. Bij #vraagteken wordt de <label> met het vraagteken met een negatieve marge 20 px omhoog gezet, waardoor de <input> onder het vraagteken verdwijnt.
Aan de onderkant geen marge.
Links en rechts auto
, wat hier hetzelfde betekent als evenveel. Hierdoor staat de <input> altijd horizontaal gecentreerd binnen z'n ouder, ongeacht de breedte van die ouder.
De ouder van deze <input> is <main>, een blok-element. Een blok-element wordt normaal genomen even breed als z'n ouder, dat is het blok-element <body>. Ook <body> wordt normaal genomen even breed als z'n ouder <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster van de browser. Hierdoor staat uiteindelijk de <input> altijd horizontaal gecentreerd binnen het venster, ongeacht de breedte van het venster. Dat komt goed uit, want hierdoor kan hij makkelijk onder de ook horizontaal gecentreerde label#vraagteken
met het vraagteken worden verborgen.
Normaal genomen kan een blok-element alleen op deze manier horizontaal worden gecentreerd, als het een breedte heeft. Een <input type="checkbox">, zoals hier is gebruikt, is echter een zogenaamd 'replaced element', en die hebben een soort ingebouwde impliciete breedte. Die breedte verschilt iets in de verschillende browsers, maar dat maakt voor het centreren niets uit. (Een bekendere vorm van een 'replaced element' is een <img>.)
#vraagteken
Het element met id="vraagteken". De <label> waar het vraagteken in zit. Deze <label> zorgt voor het tonen van de pop-up (behalve voor gebruikers van de Tab-toets, want die hebben een eigen manier.)
background: white;
Achtergrond wit.
color: black;
Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.
Hoewel dit de standaardkleur is, wordt deze toch specifiek opgegeven. Hierboven is een achtergrondkleur opgegeven. Sommige mensen hebben zelf de voorgrond‑ en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als nu de achtergrondkleur wordt veranderd, maar niet de voorgrondkleur, loop je het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.
Door beide op te geven, is redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important
heeft gebruikt in een eigen stylesheet, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.
Dit is ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.
cursor: pointer;
Als, bij gebruik van een muis, over de <p> met het vraagteken wordt gehoverd, houdt de cursor z'n standaardvorm. Als de pop-up wordt geopend, verandert de cursor in een handje, omdat de pop-up in een <a>, een link, zit.
In sommige browsers duurt het heel even, voordat de cursor bij hoveren over de <a> in een handje verandert. Daardoor zie je de cursor met een kleine vertraging verspringen van de standaardvorm naar het handje. Door de cursor al in een handje te veranderen bij hoveren over de <p>, voorkom je dit verspringen. 'n Kleinigheidje, maar het staat wat netter.
display: block;
Van zichzelf is een <label> een inline-element. Daardoor kunnen eigenschappen als breedte en hoogte niet worden gebruikt. Door de <label> te veranderen in een blok-element, kan dat wel.
width: 3rem;
Breedte.
De <p> met het vraagteken moet een vierkante vorm krijgen. Iets hieronder wordt de regelhoogte ook 3 rem. Omdat er geen gewone hoogte is, wordt de regelhoogte ook de hoogte van de <p>. Waardoor de <p> 3 x 3 rem is.
De eenheid rem
is vrijwel hetzelfde als de eenheid em
. Alleen is de rem
, de 'root em', gebaseerd op de lettergrootte van het <html>-element. Daardoor is de rem
altijd even groot. Ongeacht de lettergrootte van het element, een rem
is altijd even groot. De grootte van de em
varieert, want deze is afhankelijk van de lettergrootte van het element, waarin de em
wordt gebruikt.
Als de gebruiker de lettergrootte van de browser aanpast, wordt feitelijk de grootte van de rem
veranderd. Maar ook in dat geval is de rem
nog steeds overal even groot, want de verandering is overal hetzelfde.
Hier gelijk onder wordt een lettergrootte van 3 rem aan het vraagteken gegeven. Breedte, hoogte en lettergrootte gebruiken dus alle drie de rem
als eenheid. Als de lettergrootte van de browser door de gebruiker wordt veranderd, veranderen breedte, hoogte en lettergrootte hierdoor evenveel.
Maar datzelfde gebeurt ook bij gebruik van de meer gangbare em
als eenheid. Toch is de rem
hier beter.
#linkje
, de <a> met de pop-up, wordt gelijk gezet met de bovenkant van de <p> met het vraagteken. Daarvoor krijgt #linkje
bij #linkje aan de bovenkant een negatieve marge van 3 rem. Omdat de rem
altijd even groot is, is dat precies de hoogte van label#vraagteken
.

Als je de <p> een hoogte en een lettergrootte van 3 em zou geven en #linkje
een negatieve marge aan de bovenkant van 3 em, zouden dat twee totaal verschillende groottes zijn. label#vraagteken
heeft een lettergrootte van 3 em, en #linkje
heeft een lettergrootte van 1 em. De em
van label#vraagteken
is drie keer zo groot als de em
van #linkje
. Omdat de rem
altijd even groot is, ongeacht de lettergrootte van het element, speelt dit probleem bij een rem
niet.
Op de afbeelding is de css helemaal hetzelfde, alleen is als eenheid bij de breedte, regelhoogte en lettergrootte van label#vraagteken
en bij de negatieve marge aan de bovenkant van #linkje
niet de eenheid rem
, maar de eenheid em
gebruikt. Omdat de lettergrootte in label#vraagteken
3 em is en in #linkje
slechts 1 em, is de em
in label#vraagteken
drie keer zo groot als in #linkje
.
Op de afbeelding is de achtergrond-afbeelding in #linkje
is doorzichtig gemaakt, waardoor beter is te zien dat #linkje
inderdaad maar een derde van de hoogte van label#vraagteken
terug naar boven wordt gezet.
font-size: 3rem;
Lettergrootte.
Als eenheid wordt de relatieve eenheid rem
gebruikt, omdat bij gebruik van een absolute eenheid zoals px
niet alle browsers de lettergrootte kunnen veranderen. Zoomen kan wel altijd, ongeacht welke eenheid voor de lettergrootte wordt gebruikt.
De rem
lijkt erg op de meer bekende em
. Waarom hier rem
wordt gebruikt, staat hier gelijk boven bij width: 3rem;
.
line-height: 3rem;
Regelhoogte.
Omdat geen aparte hoogte aan de <p> is gegeven, is dit tevens de hoogte van de <p>. Tekst wordt normaal genomen automatisch halverwege de regelhoogte geplaatst. Hierdoor staat het vraagteken netjes verticaal gecentreerd.
Als eenheid wordt de relatieve eenheid rem
gebruikt, omdat bij gebruik van een absolute eenheid zoals px
de regelhoogte niet mee verandert met de lettergrootte.
De rem
lijkt erg op de meer bekende em
. Waarom hier rem
wordt gebruikt, staat iets hierboven bij width: 3rem;
.
text-align: center;
Vraagteken horizontaal centreren.
margin: -20px auto 0;
Omdat voor links geen waarde is ingevuld, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 10px auto 0 auto
in de volgorde boven – rechts – onder – links.
Kleine afstand tussen de uitleg aan de bovenkant van het browservenster en de bovenkant van de <p>. Links en rechts auto
, wat hier hetzelfde betekent als evenveel. Hierdoor staat de <p> altijd horizontaal gecentreerd binnen z'n ouder <main>. <main> is een blok-element en wordt daarom normaal genomen even breed als z'n ouder <body>, ook een blok-element. Dat dus normaal genomen weer even breed wordt als z'n ouder blok-element <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster.
Uiteindelijk wordt <main> dus ook even breed als het venster van de browser en staat de <p> horizontaal gecentreerd binnen het venster, ongeacht de breedte van het venster.
Deze manier van horizontaal centreren van een blok-element werkt alleen, als het te centreren element een breedte heeft.
border: black solid 1px;
Zwart randje.
position: relative;
Dit is alleen nodig, omdat hier gelijk onder een z-index aan de <p> wordt gegeven. Omdat verder niets wordt opgegeven bij top
e, heeft dit verder geen invloed op de <p>.
z-index: 10;
Om een of andere reden opent de pop-up niet in Edge op een touchscreen, als label#vraagteken
geen z-index heeft. Dat is het enige nut van deze z-index.
Als #linkje
met de pop-up wordt geopend, komt deze boven het vraagteken te staan. Door deze z-index zou het vraagteken zichtbaar blijven boven de pop-up. Daarom krijgt #linkje bij #linkje een hogere z-index, zodat het vraagteken toch onder de pop-up verdwijnt.
Een z-index werkt alleen in bepaalde omstandigheden. Eén van die omstandigheden is een relatieve positie. Die is gelijk hierboven gegeven, dus dat is geregeld.
-ms-user-select: none;
user-select
staat nog niet in een standaard, daarom is nog een vorm nodig met het voorvoegsel -ms-
. Normaal genomen zouden ook de vormen voor andere browsers (en het uiteindelijke user-select
) worden opgenomen, maar in dit geval wordt het alleen gebruikt om een probleem in Internet Explorer en Edge op te lossen en zijn de vormen voor andere browsers niet nodig. Meer over hoe dit werkt is te vinden bij De voorvoegsels -moz-, -ms- en -webkit-.
Als in Internet Explorer en Edge op een touchscreen het vraagteken wordt aangeraakt, selecteren deze browsers gelijk het vraagteken. Hoe kort je het vraagteken ook aanraakt. Deze eigenschap schakelt het selecteren van tekst uit, waardoor dit wordt voorkomen.
Nadeel is dat je de tekst nu ook niet meer kunt kopiëren. Maar totdat Microsoft dit eindelijk heeft opgelost, zit er weinig anders op dan deze eigenschap te gebruiken. (Overigens staat hier alleen een vraagteken, dus dat je dat niet kunt kopiëren zal waarschijnlijk niet tot grootscheepse opstanden en revoluties leiden.)
#linkje
Het element met id="linkje". Dit is de <a>, waarbinnen de link en de pop-up zitten.
Normaal genomen zou a#linkje
, en daarmee de erin zittende pop-up, links buiten het scherm worden geparkeerd en pas op het scherm worden gezet, als de link zichtbaar moet worden. Voor schermlezers en dergelijke is de link dan bereikbaar, terwijl de lay-out niet wordt verstoord.
Maar in de schermlezer TalkBack op Android blijkt de link niet te werken, als deze buiten het scherm staat. Bovendien moet de link voor TalkBack minimaal 1 x 1 px groot zijn, anders werkt hij ook niet.
Normaal genomen zou a#linkje
hier al helemaal worden opgemaakt, maar dat kan dus niet. Breedte, hoogte, linkermarge, border en z-index kunnen vanwege bovenstaande redenen pas worden opgemaakt, als de pop-up wordt getoond.
background: url(../026-pics/rapunzel.jpg);
Achtergrond-afbeelding.
color: black;
Voorgrondkleur zwart. Dit is ook de kleur van de tekst.
Om aan te geven dat het een link is, heeft de tekst in een link normaal genomen een afwijkende kleur. Hier wordt uit de tekst al duidelijk dat het een link is, dus de tekst mag hier gewoon zwart zijn.
width: 1px; height: 1px;
Breedte en hoogte.
Als de link niet minimaal 1 x 1 px groot is, blijkt deze niet te werken in TalkBack op Android. Met deze kleine breedte en hoogte is de link prima te verbergen onder het vraagteken. Pas als de pop-up getoond moet worden, worden breedte en hoogte groot genoeg gemaakt voor de achtergrond-afbeelding.
text-align: center;
Tekst horizontaal centreren.
text-decoration: none;
Normaal genomen wordt tekst in een link onderstreept. Dat is hier niet nodig, omdat uit de tekst al duidelijk wordt dat dit een link is.
margin-top: -3rem;
Hier gelijk onder staat deze marge nogmaals op een iets andere manier: bij de marge aan de bovenkant wordt daar calc()
gebruikt. Sommige oudere browsers ondersteunen dat niet en negeren daarom de hier gelijk onder opgegeven marge. Die oudere browsers gebruiken deze regel.
De pop-up staat onder label#vraagteken
en zou normaal genomen daaronder komen te staan. label#vraagteken
heeft bij #vraagteken een hoogte van 3 rem gekregen. Door de pop-up 3 rem terug naar boven te zetten, komt de bovenkant van de pop-up gelijk te staan met de bovenkant van de <label> met het vraagteken. Niet helemaal, want #linkje
en #label#vraagteken
hebben beide een border van 1 px breedte aan de bovenkant. Daardoor komt de pop-up 2 px lager dan label#vraagteken
te staan. (Om dat te corrigeren wordt gelijk hieronder calc()
gebruikt, maar die 2 px is niet het einde van de wereld. Er zal wel vaker iets afwijken in die oudere browsers.)
Als eenheid wordt rem
gebruikt, wat vrijwel hetzelfde werkt als het bekendere em
. In dit geval is rem
geschikter, omdat de pop-up nu ook op de juiste hoogte staat, als de gebruiker de lettergrootte verandert. Een uitgebreider verhaal over waarom de eenheid rem
hier beter is dan de eenheid em
is te vinden bij width: 3rem;.
margin-top: calc(-3rem - 2px);
Deze marge werkt vrijwel hetzelfde als die gelijk hierboven. De uitleg is ook vrijwel hetzelfde. Het enige verschil: hier wordt bij de marge aan de bovenkant calc()
gebruikt. Oudere browsers die dat niet ondersteunen negeren deze regel en gebruiken de gelijk hierboven opgegeven marge zonder calc()
. Voor nieuwere browsers overrulet deze regel de eerdere, omdat hij later in de css staat.

Met behulp van calc()
kunnen berekeningen worden gemaakt. De marge aan de bovenkant is hier calc(-3rem – 2px)
. Die 3 rem werkt precies hetzelfde als bij de marge hier gelijk boven: zet de pop-up 3 rem naar boven terug, zodat de bovenkant van de pop-up op dezelfde hoogte staat als label#vraagteken
. Maar eigenlijk moet de pop-up nog 2 px meer naar boven worden gezet, omdat zowel de pop-up als label#vraagteken
aan de bovenkant een border van 1 px breed hebben. Op de afbeelding is de pop-up 3 rem naar boven teruggezet. Omdat dat eigenlijk 2 px te weinig is, zie je in het midden nog een klein stukje van label#vraagteken
boven de pop-up uitsteken.
Met behulp van calc()
kun je verschillende eenheden combineren. De pop-up wordt met behulp van calc()
niet 3 rem, maar 3 rem en nog 2 px terug naar boven gezet. Nu staat de pop-up precies op de juiste hoogte.
position: absolute;
Om de <a> met de pop-up op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Als die er niet is, zoals hier het geval is, wordt gepositioneerd ten opzichte van het venster van de browser.
Een <a> is van zichzelf een inline-element. Daardoor zijn eigenschappen als breedte en hoogte niet te gebruiken. Door de <a> absoluut te positioneren, verandert deze in een soort blok-element, waardoor deze eigenschappen wel zijn te gebruiken.
Nog een ander voordeel: een absoluut gepositioneerd element trekt zich niets aan van andere elementen. Als de pop-up wordt getoond, komt deze gewoon over de Latijnse tekst heen te staan. Bij bijvoorbeeld een relatieve positie zou de Latijnse tekst een eind omlaag schuiven, als de pop-up wordt getoond.
left: 50%;
De linkerkant van a#linkje
, en daarmee van de daarin zittende pop-up, horizontaal halverwege het browservenster zetten, ongeacht de breedte van het venster.
-webkit-transition-delay: 0.001s; transition-delay: 0.001s;
Hier staat in feite twee keer hetzelfde: transition-delay: 0.001s;
. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
Als op een touchscreen het vraagteken wordt aangeraakt, wordt de pop-up getoond. Pas als de pop-up wordt aangeraakt, moet de link worden gevolgd. In een aantal browsers wordt echter bij aanraking van het vraagteken gelijk de link gevolgd. Het touchscreen 'onthoudt' de aanraking even en geeft die vervolgens ook nog door aan de <a> met de pop-up. Door de pop-up met een kleine vertraging te openen, wordt dit voorkomen.
De pop-up kan op twee manieren worden geopend: met :hover
en met :focus
.
Een link zoals a#linkje
kan alleen focus krijgen door de link aan te raken of aan te klikken, of door de Tab-toets te gebruiken. Omdat de link wordt afgedekt door label#vraagteken
, is klikken of aanraken onmogelijk. Alleen door de Tab-toets te gebruiken, kan de link focus krijgen. Daarom is deze vertraging niet nodig bij :focus
, want dan speelt het probleem niet. Dat is de reden dat :focus
apart, zonder vertraging, wordt afgehandeld bij #linkje:focus.
Bij :hover
is de vertraging wel nodig. Bij #vraagteken:hover + #linkje, #linkje:hover wordt de pop-up zichtbaar gemaakt door breedte, hoogte, en dergelijke te veranderen. Normaal genomen zou deze verandering ogenblikkelijk plaatsvinden, maar omdat bij #vraagteken:hover + #linkje, #linkje:hover ook transition-delay: 0.25s;
is opgegeven, vindt de verandering pas na 0,25 seconde plaats. Dat is een vertraging die nauwelijks merkbaar is, maar wel in vrijwel alle browsers het gelijk volgen van de link voorkomt.
(In Opera Mini op iOS, Dolphin op Android 6 en eerder, Opera Mini en Android Browser op Android 4 wordt de link toch gelijk gevolgd. Meer daarover bij Bekende problemen (en oplossingen).)
Als de pop-up weer moet worden verborgen, gebeurt dat normaal genomen met dezelfde vertraging, als waarmee de pop-up werd getoond. Bij het weer verdwijnen van de pop-up is de vertraging echter niet nodig. Als je transition-delay
ook hier bij #linkje
gebruikt en niet alleen bij #vraagteken:hover + #linkje, #linkje:hover, wordt de hier opgegeven waarde gebruikt om de pop-up weer te verbergen. Het tonen gebeurt dan met een vertraging van 0,25 seconde, het weer verbergen met een vertraging van 0,001 seconde.
Een vertraging van 0,001 seconde? Alleen Lucky Luke ziet dat, en die is vast lang geleden al overleden.
Eigenlijk zou de waarde hier 0s
, 0 seconde, moeten zijn, maar dan blijkt de hele pop-up niet getoond te worden in Internet Explorer 11 en UC browser op Windows, Windows Phone 8.1 en Windows 10 Mobile. De flauwekul-waarde van 0,001 seconde lost deze kennelijke bug op.
transition-delay
is een van de transition
-eigenschappen. Met behulp van andere transition
-eigenschappen kun je opgeven, bij welke eigenschappen er een vertraging moet optreden. Dat kan nodig zijn, als er meerdere eigenschappen veranderen bij :focus
, :hover
, en dergelijke, die met een verschillende (of geen) vertraging moeten beginnen. In dit geval is dat niet nodig, omdat de verandering bij alle bij het tonen te veranderen eigenschappen 0,25 seconde vertraagd moet worden.
#linkje span
De <span>'s binnen het element met id="linkje". De <span>'s binnen a#linkje
. Dat is hier maar één <span>, waarin de boven de achtergrond-afbeelding staande tekst zit. Door de tekst in een aparte <span> te zetten, kan de tekst eigenschappen krijgen, zonder dat die voor de hele a#linkje
gelden.
background: rgba(255, 255, 255, 0.7);
De tekst in de link staat boven een achtergrond-afbeelding, waardoor deze lastig leesbaar is. Door aan de <span> met de tekst een achtergrondkleur te geven, is de tekst toch goed leesbaar.
Vaak wordt voor 'n kleur de hexadecimale notatie gebruikt, iets als color: #33ab01;
. Daarbij worden niet alleen cijfers, maar ook letters gebruikt. 0 tot en met 9 werken precies hetzelfde als altijd, maar na de 9 komen nog A, B, C, D, E en F.
Als je telt, is 't dus: 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12, enzovoort. Daarbij is A gelijk aan het tientallige 10, B aan 11, enzovoort. Op deze manier kun je met twee cijfers en/of letters 256 mogelijkheden aangeven: van 00 tot en met FF.
De eerste drie getallen bij rgba()
geven de kleur aan. Deze lopen van 0 tot en met 255, dus ook hiermee kun je 256 mogelijkheden aangeven. En omdat er drie getallen zijn levert dat 256 x 256 x 256 = 16.777.216 mogelijke kleuren op, net iets meer dan het aantal kleurpotloden in de gemiddelde kleurdoos van 'n kind.
De notatie bij rgba()
geeft dus precies evenveel mogelijkheden als de hexadecimale.
Het eerste getal staat voor rood, het tweede voor groen en het derde voor blauw (feitelijk de Engelse namen, maar de eerste letter is toevallig in het Nederlands hetzelfde). Uit deze drie kleuren zijn alle kleuren op een monitor opgebouwd.
255 wil zeggen volledig aanwezig, 0 wil zeggen helemaal ontbrekend.
255, 255, 255 levert wit op, 0 , 0 , 0 zwart.
In plaats van getallen mag je ook percentages gebruiken, bijvoorbeeld: rgba(10%, 20%, 100%, 0.3)
.
Omdat in dit voorbeeld drie keer 255 is opgegeven, levert dit een witte kleur op.
Het vierde getal staat voor het alfa-kanaal. Hiermee wordt de doorzichtigheid aangegeven. Dit getal loopt van 0 naar 1. Volledig doorzichtig is 0, volledig ondoorzichtig is 1.
Het getal voor het alfa-kanaal wordt als decimale breuk aangegeven, dus bijvoorbeeld 0.5 wil zeggen halfdoorzichtig. Let erop dat je 'n punt gebruikt, de Amerikaanse manier om breuken aan te geven. Als je 'n komma gebruikt, denkt de browser dat er twee verschillende getallen staan.
In dit voorbeeld is deze achtergrondkleur enigszins doorzichtig: 0.7
. Hierdoor zie je de achtergrond-afbeelding van a#linkje
nog enigszins door de achtergrondkleur van de <span> heen, maar is de tekst toch goed te lezen.
margin-left: -20000px;
De tekst boven de achtergrond-afbeelding zit binnen a#linkje
. Normaal genomen zou je a#linkje
links buiten het scherm parkeren, totdat deze zichtbaar moet worden. Maar dan blijkt de link niet te werken in TalkBack op Android. Daarom is bij #linkje de link met de pop-up 1 x 1 px groot gemaakt, zodat deze verborgen kan worden onder het vraagteken.

De tekst binnen deze <span> is 'Klik of raak plaatje aan om naar site van wpclipart.com te gaan.'. Dit past uiteraard niet binnen een ruimte van 1 x 1 px. Daarom moet deze tekst worden verborgen, totdat de pop-up zichtbaar moet worden.
Op de afbeelding hiernaast is te zien, wat er gebeurt, als de tekst niet wordt verborgen. De pop-up zelf is verborgen onder het vraagteken, maar de tekst uit de pop-up is wel te zien. (Om de tekst duidelijker zichtbaar te maken, is de achtergrond even rood gemaakt.)
Je zou kunnen denken aan overflow: hidden;
bij #linkje
, Wat niet binnen de 1 x 1 px van #linkje
past, wordt dan gewoon afgekapt. Maar helaas blijkt ook dan de link niet te werken in TalkBack op Android. De tekst moet dus op op een andere manier worden verborgen.
Voor het verbergen is display: none;
niet bruikbaar. De pop-up wordt bij #vraagteken:hover + #linkje, #linkje:hover met een vertraging van 0,25 seconde getoond. display
kan echter niet vertraagd worden. Hierdoor zou de tekst 0,25 seconde eerder zichtbaar zijn dan de rest van de pop-up. Dat lijkt heel weinig tijd, maar het ziet er echt niet uit.
visibility: hidden;
kan wel worden vertraagd, maar de tekst blijft dan gewoon z'n ruimte innemen, ook al zie je geen tekst. Omdat #linkje
, waar deze <span> in zit, absoluut is gepositioneerd, verplaatst dit andere elementen op de pagina niet, dus in principe zou dit kunnen. Maar het is niet helemaal duidelijk, hoe dit op een aanraking of klik zou moeten reageren. Er is dan een risico dat een argeloze ziel volkomen te goeder trouwe een lege plek in de buurt van het vraagteken aanraakt en gelijk naar de hartbewaking kan, omdat uit het niets een pop-up met ene Rapunzel opduikt.
Daarom wordt voor de tekst teruggevallen op het links buiten het scherm parkeren met een grote negatieve linkermarge. Ook TalkBack blijkt zowaar hiermee te kunnen leven. Nu is in ieder geval zeker dat in geen enkele browser of systeem een aanraking of klik in de buurt van het vraagteken de pop-up voortijdig doet openen.
-ms-user-select: none;
user-select
staat nog niet in een standaard, daarom is nog een vorm nodig met het voorvoegsel -ms-
. Normaal genomen zouden ook de vormen voor andere browsers (en het uiteindelijke user-select
) worden opgenomen, maar in dit geval wordt het alleen gebruikt om een probleem in Internet Explorer en Edge op te lossen en zijn de vormen voor andere browsers niet nodig. Meer over hoe dit werkt, is te vinden bij De voorvoegsels -moz-, -ms- en -webkit-.
Als in Internet Explorer en Edge op een touchscreen het vraagteken wordt aangeraakt, wordt de <a> met de pop-up boven het vraagteken gezet. Als je niet met een onmenselijke snelheid je vinger terugtrekt na de aanraking, selecteren deze browsers de tekst in de pop-up. Deze eigenschap schakelt het selecteren van tekst uit, waardoor dit wordt voorkomen.
Nadeel is dat je de tekst nu ook niet meer kunt kopiëren. Omdat het hier maar om 'n heel kort tekstje gaat, zal dat niet zo'n probleem zijn.
#vraagteken:hover + #linkje, #linkje:hover
Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.
#linkje {background: url(../026-pics/rapunzel.jpg); color: black; width: 1px; height: 1px; text-align: center; text-decoration: none; margin-top: -3rem; margin-top: calc(-3rem – 2px); position: absolute; left: 50%; -webkit-transition-delay: 0.001s; transition-delay: 0.001s;}
Dit zijn twee selectors, gescheiden door een komma.
De selector voor de komma #vraagteken:hover + #linkje
zorgt voor het openen van de pop-up:
#vraagteken:hover
: als over label#vraagteken
wordt gehoverd, of als deze wordt aangeraakt.
+
: het element achter de +
moet in de html direct volgen op het element voor de +
. In dit geval gaat het om een element met id="linkje", dat gelijk op een element met id="vraagteken" volgt.
#linkje
: het element met id="linkje". De <a> met de pop-up.
In gewone mensentaal: doe iets met a#linkje
, als over label#vraagteken
wordt gehoverd, of als dit wordt aangeraakt. In dit geval moet a#linkje
met de pop-up worden vergroot, zodat de pop-up zichtbaar wordt.
De selector na de komma #linkje:hover
zorgt voor het openblijven van de pop-up:
#linkje:hover
: als over a#linkje
met de pop-up wordt gehoverd. Bij de eerste selector gelijk hierboven is geregeld dat a#linkje
met de pop-up zichtbaar wordt, als over label#vraagteken
wordt gehoverd, of als deze wordt aangeraakt. Bij hoveren levert dat echter problemen op.
Op het moment dat de pop-up opent, wordt a#linkje
boven label#vraagteken
gezet. Daardoor wordt niet meer over label#vraagteken
gehoverd, maar over a#linkje
. En verdwijnt a#linkje
met de pop-up dus weer. Nu wordt er weer over label#vraagteken
gehoverd, waardoor a#linkje
weer verschijnt. En label#vraagteken
weer afdekt en dus weer verdwijnt. Oftewel: de pop-up verschijnt en verdwijnt in een razend tempo.
Door ook a#linkje
zelf te laten reageren op hoveren, wordt dit voorkomen. Eerst wordt, door de eerste selector, hoveren over label#vraagteken
geregeld. Zodra a#linkje
verschijnt, neemt deze tweede selector het over.
Alles bij elkaar: doe iets met a#linkje
als over label#vraagteken
wordt gehoverd (of als die wordt aangeraakt), of als over a#linkje
wordt gehoverd.
width: 186px; height: 254px;
Een achtergrond-afbeelding heeft van zichzelf geen breedte en hoogte, maar vult alleen de achtergrond van het element, waarin hij zit. Door de <a> even groot te maken als de afbeelding, wordt precies hele afbeelding getoond.
(Normaal genomen zou de <a> met de pop-up al bij #linkje deze afmetingen hebben gekregen en buiten het scherm zijn geparkeerd, tot de <a> zichtbaar moet worden. Dan geef je de hele opmaak op één plek. Omdat dat echter in TalkBack op Android problemen geeft, heeft a#linkje
bij #linkje een breedte en hoogte van 1 px gekregen, zodat deze verborgen kan worden onder label#vraagteken
. Pas hier kunnen de uiteindelijke breedte en hoogte worden weergegeven, want met deze breedte en hoogte kan de pop-up niet worden verborgen onder het vraagteken.)
In deze <a> staat ook tekst. Die tekst heeft geen lettergrootte gekregen, waardoor de lettergrootte wordt geërfd van de voorouders van de <a>. In browservensters smaller dan 760 px is geen lettergrootte opgegeven aan de voorouders, waardoor de standaardlettergrootte van 1 em wordt gebruikt. In bredere vensters is de lettergrootte 110%, wat hetzelfde is als 1,1 em.

Omdat em
een relatieve eenheid is en geen absolute eenheid zoals px
, kan de gebruiker de lettergrootte veranderen. Maar als de letters worden vergroot, veranderen de hier opgegeven breedte en hoogte niet mee, omdat deze wel in de absolute eenheid px
zijn opgegeven.
Normaal genomen is dat geen goed idee, omdat de tekst hierdoor buiten het element kan komen te staan. In dit geval is dat geen probleem, omdat er maar heel weinig tekst is. Op de afbeelding is de tekst tot 200% vergroot, en alleen de letter 'm' van 'wpclipart.com' komt buiten de pop-up te staan. Omdat de tekst in de link bij #linkje span een doorzichtig witte achtergrondkleur heeft gekregen, is ook die letter 'm' nog duidelijk te zien.
margin-left: -94px;
Bij #linkje is de linkerkant van a#linkje
met left: 50%;
horizontaal in het midden van het browservenster gezet. De pop-up is 188 px breed (een breedte van 186 px en een border van 1 px links en rechts). Door de pop-up 94 px ,de helft van die breedte, terug naar links te zetten, komt de pop-up echt in het midden van het venster te staan.
(Normaal genomen zou de <a> met de pop-up deze marge al bij #linkje hebben gekregen en buiten het scherm zijn geparkeerd, tot de <a> zichtbaar moet worden. Dan geef je de hele opmaak op één plek. Omdat dat buiten het scherm parkeren echter in TalkBack op Android problemen geeft, kan de negatieve linkermarge niet eerder worden gegeven. a#linkje
wordt onder label#vraagteken
verborgen, en met zo'n negatieve marge zou a#linkje
niet onder, maar links van het vraagteken komen te staan.)
border: black solid 1px;
Zwart randje.
(Normaal genomen zou de <a> met de pop-up deze border al bij #linkje hebben gekregen en buiten het scherm zijn geparkeerd, tot de <a> zichtbaar moet worden. Dan geef je de hele opmaak op één plek. Omdat dat buiten het scherm parkeren echter in TalkBack op Android problemen geeft, kan de border pas hier worden opgegeven.
Als de border eerder zou worden opgegeven, zou de border voortdurend aanwezig zijn. a#linkje
heeft bij #linkje een grootte van 1 x 1 px gekregen. De border zou dus heel klein zijn, 'n soort stip. De pop-up wordt met een vertraging van 0,25 seconde geopend. Hierdoor is die stip heel even zichtbaar. Op deze manier wordt dat voorkomen. Dat kan ook nog op andere manieren, maar deze manier is redelijk simpel.)
z-index: 20;

De <a> met de pop-up komt over label#vraagteken
te staan. Normaal genomen komen elementen die later in de html staan boven eerdere elementen te staan. Normaal genomen zou a#linkje
daarom boven label#vraagteken
komen te staan. Maar omdat label#vraagteken
bij #vraagteken een z-index heeft gekregen, komt label#vraagteken
toch boven a#linkje
met de pop-up te staan. Dat ziet eruit zoals op de afbeelding: de <label> met het vraagteken verbergt een groot deel van de bovenkant van de pop-up.
Om dit te voorkomen, krijgt de <a> met de pop-up een hogere z-index dan label#vraagteken
. De z-index van label#vraagteken
heeft een waarde van 10, de z-index van a#linkje
krijgt een waarde van 20. De getallen sluiten niet op elkaar aan, waardoor het makkelijk is er later eventueel nog elementen met een z-index tussen te voegen. (Als je ooit 300 z-indexen hebt moeten hernummeren, omdat er helemaal aan het begin eentje bij moest komen, vergeet je nooit meer, waarom dat overslaan van nummers handig is...)
Een z-index werkt alleen in bepaalde omstandigheden. Twee van die omstandigheden zijn een absolute positie en transform
. De absolute positie is gelijk hierboven gegeven, transform
wordt gelijk hieronder gebruikt, dus dat is hier zelfs dubbelop geregeld.
(Normaal genomen zou de <a> met de pop-up deze z-index al bij #linkje hebben gekregen en buiten het scherm zijn geparkeerd, tot de <a> zichtbaar moet worden. Dan geef je de hele opmaak op één plek. Omdat dat buiten het scherm parkeren echter in TalkBack op Android problemen geeft, kan de z-index niet eerder worden opgegeven. De <a> heeft bij #linkje een grootte van 1 x 1 px gekregen. Als de <a> boven de <label> met het vraagteken zou staan en je zou precies die ene pixel aanraken, zou de link gelijk worden gevolgd. Nu wordt de <a> afgeschermd door de <label> met het vraagteken.)
-webkit-transition-delay: 0.25s; transition-delay: 0.25s;
Hier staat in feite twee keer hetzelfde: transition-delay: 0.25s;
. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
Voordat de pop-up zichtbaar wordt, is er een vertraging van 0,25 seconde. a#linkje
met de pop-up komt boven het vraagteken te staan. Veel browsers op touchscreens blijken, na aanraken van label#vraagteken
, gelijk de link te volgen. Deze kleine vertraging voorkomt dat in de meeste browsers. Meer over hoe dit precies werkt is te vinden bij -webkit-transition-delay: 0.001s; transition-delay: 0.001s;.
vraagteken:hover + #linkje span, #linkje:hover span
Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.
#linkje span {background: rgba(255, 255, 255, 0.7); margin-left: -20000px; -ms-user-select: none;}
Dit zijn twee selectors, gescheiden door een komma.
De selector voor de komma #vraagteken:hover + #linkje span
zorgt voor het verschijnen van de tekst boven de achtergrond-afbeelding in de pop-up:
#vraagteken:hover
: als over label#vraagteken wordt gehoverd, of als dit wordt aangeraakt.
+
: het element achter de +
moet in de html direct volgen op het element voor de +
. In dit geval gaat het om een element met id="linkje", dat gelijk op een element met id="vraagteken" volgt.
#linkje span
: de <span>'s in het element met id="linkje". Dit is de <span>, waarbinnen de tekst in a#linkje
zit.
In gewone mensentaal: doe iets met de <span> in a#linkje
, als over label#vraagteken
wordt gehoverd, of als dit wordt aangeraakt. In dit geval moet de tekst in a#linkje
binnen het scherm worden gezet.
De selector na de komma #linkje:hover span
zorgt dat de tekst boven de achtergrond-afbeelding in de pop-up blijft staan.
#linkje:hover
: als over a#linkje
met de pop-up wordt gehoverd. Bij de eerste selector gelijk hierboven is geregeld dat de tekst in de <span> in a#linkje
zichtbaar wordt, als over label#vraagteken
wordt gehoverd, of als deze wordt aangeraakt. Maar op het moment dat dat gebeurt, wordt a#linkje
boven label#vraagteken
gezet. Daardoor wordt niet meer over label#vraagteken
gehoverd, maar over a#linkje
. En verdwijnt de <span> met de tekst dus weer. Oftewel: de tekst verschijnt, om daarna op vrijwel hetzelfde moment weer te verdwijnen.
Door ook a#linkje
zelf te laten reageren op hoveren, wordt dit voorkomen. Eerst wordt, door de eerste selector, hoveren over label#vraagteken
geregeld. Zodra a#linkje
verschijnt, neemt deze tweede selector het over.
Alles bij elkaar: doe iets met de <span> in a#linkje
als over label#vraagteken
wordt gehoverd (of als die wordt aangeraakt), of als over a#linkje
wordt gehoverd.
margin-left: 0;
Bij #linkje span is de <span> met margin-left: -20000px;
links buiten het scherm geparkeerd. Waarom dat nodig is, staat daar beschreven. Hier wordt de <span>, en daarmee de erin zittende tekst, weer binnen het scherm gezet en daardoor zichtbaar.
-webkit-transition-delay: 0.25s; transition-delay: 0.25s;
Hier staat in feite twee keer hetzelfde: transition-delay: 0.25s;. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
a#linkje
met de pop-up wordt met een vertraging van 0,25 seconde getoond. Omdat de tekst in de <span> op de achtergrond-afbeelding in a#linkje
moet komen te staan, moet ook de tekst pas na een vertraging van 0,25 seconde worden getoond. Meer over de reden van deze vertraging is te vinden bij -webkit-transition-delay: 0.001s; transition-delay: 0.001s;.
#linkje:focus
Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.
#linkje {background: url(../026-pics/rapunzel.jpg); color: black; width: 1px; height: 1px; text-align: center; text-decoration: none; margin-top: -3rem; margin-top: calc(-3rem – 2px); position: absolute; left: 50%; -webkit-transition-delay: 0.001s; transition-delay: 0.001s;}
Als het element met id="linkje" focus heeft. Als a#linkje
met de pop-up focus heeft.
Sommige mensen gebruiken niet de muis, maar de Tab-toets om links, tekstvelden, knoppen, en dergelijke langs te lopen. Vanwege een handicap, of omdat dat soms gewoon veel handiger is. Omdat de pop-up in een gewone <a> staat, kan deze focus krijgen, als de Tab-toets wordt gebruikt.
Deze selector heeft hetzelfde effect als #vraagteken:hover + #linkje, #linkje:hover iets hierboven, maar die selector is voor :hover
. Je zou deze en die selector kunnen combineren, maar bij de selector voor :hover
is met transition-delay
een kleine vertraging ingebouwd. Die vertraging is niet hinderlijk bij :hover
, maar wel bij gebruik van de Tab-toets. En omdat die vertraging ook niet nodig is bij de Tab-toets, krijgt :focus
een eigen selector, zonder transition-delay
.
width: 186px; height: 254px; margin-left: -94px; border: black solid 1px; z-index: 20;
De css voor deze selector werkt precies hetzelfde als die voor #vraagteken:hover + #linkje, #linkje:hover iets hierboven. De beschrijving is daar te vinden.
#linkje:focus span
Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.
#linkje span {background: rgba(255, 255, 255, 0.7); margin-left: -20000px; -ms-user-select: none;}
Als het element met id="linkje" focus heeft, doe dan iets met de <span> 's die in #linkje
zitten. Dat is hier maar één <span>: de tekst in de link zit erin.
Sommige mensen gebruiken niet de muis, maar de Tab-toets om links, tekstvelden, knoppen, en dergelijke langs te lopen. Vanwege een handicap, of omdat dat soms gewoon veel handiger is. Omdat de pop-up in een gewone <a> staat, kan deze focus krijgen, als de Tab-toets wordt gebruikt.
Deze selector heeft hetzelfde effect als #vraagteken:hover + #linkje span, #linkje:hover span iets hierboven, maar die selector is voor :hover
. Je zou deze en die selector kunnen combineren, maar bij de selector voor :hover
is met transition-delay
een kleine vertraging ingebouwd. Die vertraging is niet hinderlijk bij :hover
, maar wel bij gebruik van de Tab-toets. En omdat die vertraging ook niet nodig is bij de Tab-toets, krijgt :focus
een eigen selector, zonder transition-delay
.
margin-left: 0;
Bij #linkje span is de <span> met margin-left: -20000px;
links buiten het scherm geparkeerd. Waarom dat nodig is, staat daar beschreven. Hier wordt de <span>, en daarmee de erin zittende tekst, weer binnen het scherm gezet en daardoor zichtbaar.
#sluit
Het element met id="sluit". Dit is een <label> die speciaal voor iOS is aangebracht, omdat sluiten van de pop-up in Safari, UC browser en Chrome op iOS anders lastig is. De pop-up sluit in deze browsers alleen, als een ander voor aanraking gevoelig element, zoals een <label>, wordt aangeraakt. Zodra de pop-up opent, bedekt deze <label> het hele browservenster. Alleen de pop-up staat boven deze <label>. Waar je het venster ook buiten de pop-up aanraakt, je raakt deze <label> aan, waardoor de pop-up weer sluit (en deze <label> ook weer verdwijnt.)
display: none;
Verbergen. Normaal genomen wordt deze <label> niet weergegeven, pas als de pop-up is geopend wordt hij bij #vraagteken:hover ~ #sluit, #linkje:hover + #sluit, #linkje:focus + #sluit met display: block;
zichtbaar gemaakt.
background: rgba(0, 0, 0, 0.7);
Dit levert een zwarte, doorzichtige achtergrond op. Hoe rgba()
precies werkt, is te vinden bij background: rgba(255, 255, 255, 0.7);. Het enige verschil is dat hier de eerste drie getallen niet 255, maar 0 zijn. Dit levert daarom geen doorzichtig wit, maar doorzichtig zwart op. Verder is het verhaal precies hetzelfde.
Omdat de achtergrondkleur enigszins doorzichtig is, zie je de pagina nog enigszins door de achtergrond heen, maar is wel goed duidelijk dat eerst de pop-up weer moet worden gesloten.
position: fixed;
Positioneren ten opzichte van het venster van de browser.
top: 0; right: 0; bottom: 0; left: 0;
De <span> moet het volledige browservenster bestrijken.
#vraagteken:hover ~ #sluit, #linkje:hover + #sluit, #linkje:focus + #sluit
Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat.
#sluit {background: rgba(0, 0, 0, 0.7); display: none; position: fixed; top: 0; right: 0; bottom: 0; left: 0;}
Dit zijn drie selectors, gescheiden door een komma. Alle drie de selectors doen iets met label#sluit
. Dit is een tweede <label> bij input#open
dat nodig is om op iOS de pop-up weer te laten verdwijnen. Zodra de pop-up wordt getoond, dekt deze <label> het hele browservenster af, behalve de pop-up. Door het aanraken van de <label> verdwijnt de pop-up weer. Over de werking op iOS is meer te vinden bij :focus.
Omdat deze <label> toch aanwezig is, wordt hij daarnaast ook gebruikt om het browservenster – met uitzondering van de pop-up – donkerder te maken, als de pop-up wordt getoond.
De selector voor de eerste komma #vraagteken:hover ~ #sluit
:
#vraagteken:hover
: als over label#vraagteken
wordt gehoverd, of als dit wordt aangeraakt.
~
: het hierachter staande element moet ergens in de html staan, na het voor de ~
staande element. Het hoeft er, anders dan bij de +
, niet gelijk op te volgen, als het maar ergens na het eerste element in de html staat.
De enige voorwaarde is verder dat het voor en na de ~
staande element dezelfde ouder hebben. Dat is hier het geval: #vraagteken
voor de ~
en #sluit
na de ~
hebben beide als ouder <main>.
#sluit
: het element met id="sluit". De tweede <label> bij input#open
.
In gewone mensentaal: doe iets met label#sluit, als over label#vraagteken wordt gehoverd, of als dit wordt aangeraakt.
De selector tussen de komma's #linkje:hover + #sluit
:
#linkje:hover
: als over a#linkje
met de pop-up wordt gehoverd, of als dit wordt aangeraakt.
+
: het element achter de +
moet in de html direct volgen op het element voor de +
. In dit geval gaat het om een element met id="sluit", dat gelijk op een element met id="linkje" volgt.
#sluit
: het element met id="sluit". De tweede <label> bij input#open
.
In gewone mensentaal: doe iets met label#sluit
, als over a#linkje
met de pop-up wordt gehoverd, of als dit wordt aangeraakt. (In de praktijk heeft dit alleen effect bij hoveren, want als #linkje
wordt aangeraakt, wordt de link gevolgd.)
De selector achter de tweede komma #linkje:focus + #sluit
;
#linkje:focus
: als a#linkje
focus heeft.
+
: het element achter de +
moet in de html direct volgen op het element voor de +
. In dit geval gaat het om een element met id="sluit", dat gelijk op een element met id="linkje" volgt.
#sluit
: het element met id="sluit". De tweede <label> bij input#open
.
In gewone mensentaal: doe iets met label#sluit
, als a#linkje
focus heeft.
De drie selectors samen in gewone mensentaal: doe iets met label#sluit
, als over label#vraagteken
of over a#linkje
wordt gehoverd, of als deze worden aangeraakt, of als a#linkje
focus heeft.
display: block;
Alle eerdere css is al bij sluit opgegeven. Daar is label#sluit
ook verborgen met display: none;
. Nu moet de <label> worden getoond.
main div
De <div>'s binnen <main>. Dat is hier maar één <div>, waarbinnen de Latijnse tekst staat.
background: white;
Witte achtergrond.
color: black;
Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.
Hoewel dit de standaardkleur is, wordt deze toch specifiek opgegeven. Hierboven is een achtergrondkleur opgegeven. Sommige mensen hebben zelf de voorgrond‑ en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als nu de achtergrondkleur wordt veranderd, maar niet de voorgrondkleur, loop je het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.
Door beide op te geven, is redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important
heeft gebruikt in een eigen stylesheet, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.
Dit is ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.
width: 800px;
Breedte.
max-width: 90%;
Hier gelijk boven is een breedte van 800 px opgegeven. In smallere browservensters is dat te breed. Daarom wordt hier een maximumbreedte opgegeven.
Een breedte in procenten is normaal genomen ten opzichte van de ouder van het element. Dat is hier het blok-element <main>. Een blok-element wordt normaal genomen even breed als z'n ouder, hier het blok-element <body>. Ook dit blok-element wordt normaal genomen even breed als z'n ouder <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster van de browser. Uiteindelijk wordt hierdoor de <div> niet breder dan 90% van het venster.
margin: 10px auto 0;
Omdat voor links geen waarde is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 10px auto 0 auto
in de volgorde boven – rechts – onder – links. Boven een kleine afstand tot het vraagteken erboven. Onder geen marge. Links en rechts auto
, wat hier evenveel betekent. Hierdoor staat de <div> altijd horizontaal gecentreerd binnen z'n ouder <main>, ongeacht hoe breed <main> is.
<main> is een blok-element en wordt daarom normaal genomen even breed als z'n ouder, hier het blok-element <body>. Ook dit blok-element wordt normaal genomen even breed als z'n ouder <html>. Omdat <html> het buitenste element is, wordt dit normaal genomen even breed als het venster van de browser. Uiteindelijk staat de <div> hierdoor altijd horizontaal gecentreerd binnen het venster.
border: black solid 1px;
Zwart randje.
padding: 5px;
Kleine ruimte tussen rand om en inhoud van de <div>.
css voor vensters minimaal 760 px breed
@media screen and (min-width: 760px)
De css die hier tot nu toe staat, geldt voor alle browservensters.
De css die binnen deze media query staat, geldt alleen voor vensters die minimaal 760 px breed zijn. In deze bredere vensters worden de letters iets vergroot.
@media
: geeft aan dat het om css gaat die alleen van toepassing is, als aan bepaalde voorwaarden wordt voldaan. Al langer bestond de mogelijkheid om met behulp van zo'n @media-regel css voor bijvoorbeeld printers op te geven. css3 heeft dat uitgebreid tot bepaalde fysieke eigenschappen, zoals de breedte en hoogte van het venster van de browser.
screen
: deze regel geldt alleen voor schermweergave.
and
: er komt nog een voorwaarde, waaraan moet worden voldaan.
(min-width: 760px)
: het venster moet minimaal 760 px breed zijn. Is het venster smaller, dan wordt de css die binnen deze media-regel staat genegeerd.
Gelijk na deze regel komt een {
te staan, en aan het einde van de css die binnen deze regel valt een bijbehorende afsluitende }
. Die zijn in de regel hierboven weggevallen, maar het geheel ziet er zo uit:
@media screen and (min-width: 760px) {
body {color: silver;}
(...) rest van de css voor deze @media-regel (...)
footer {color: gold;}
}
Voor de eerste css binnen deze media-regel staat dus een extra {
, en aan het eind staat een extra }
.
Als je nou 'n mobieltje hebt met een resolutie van – ik roep maar wat – 1024 x 768 px, dan geldt deze media query toch niet voor dat mobieltje. Terwijl dat toch echt meer dan 760 px breed is. Een vuig complot van gewetenloze multinationals? Voordat je je gaat beklagen bij Radar, zou ik eerst even verder lezen.
Steeds meer mobiele apparaten, maar ook steeds meer gewone beeldschermen, hebben een hogere resolutiedichtheid. Dat wil zeggen dat ze kleinere pixels hebben, die dichter bij elkaar staan. Daardoor zijn foto's, tekst, en dergelijke veel scherper weer te geven. Hoe kleiner de puntjes (de pixels) zijn, waaruit een afbeelding is opgebouwd, hoe duidelijker het wordt.
Er ontstaat alleen één probleem: als je de pixels twee keer zo klein maakt, wordt ook wat je ziet twee keer zo klein. En inmiddels zijn er al apparaten met pixels die meer dan vier keer zo klein zijn. Een lijntje van 1 px breed zou op die apparaten minder dan 'n kwart van de oorspronkelijke breedte krijgen en vrijwel onzichtbaar zijn. Een normale foto zou in een thumbnail veranderen. Kolommen zouden heel smal worden. Tekst zou onleesbaar klein worden. Allemaal fantastisch scherp, maar je hebt 'n vergrootglas nodig om 't te kunnen zien.
Om dit te voorkomen wordt een verschil gemaakt tussen css-pixels en schermpixels (in het Engels 'device-pixels'). De css-pixels zijn gebaseerd op de – tot voor kort – normale beeldschermen van de desktop. 1 css-pixel is op zo'n beeldscherm 1 pixel. Het aantal schermpixels is het werkelijk op het apparaat aanwezige aantal pixels (dat is het aantal pixels, waarvoor je hebt betaald).
Dat eerder genoemde mobieltje van 1024 x 768 px heeft wel degelijk het aantal pixels, waarvoor je hebt betaald. Maar die zitten dichter bij elkaar. Op een gewoon beeldscherm zitten 96 pixels per inch, wat wordt uitgedrukt met de eenheid dpi ('dots per inch'). Als dat mobieltje een resolutie van 192 dpi heeft, 192 pixels per inch, zijn de pixels ervan twee keer zo klein als op een origineel beeldscherm. Er zijn per inch twee keer zoveel schermpixels aanwezig.
Om nu te voorkomen dat alles op dat mobieltje twee keer zo klein wordt, geeft het mobieltje niet het echte aantal schermpixels (1024 x 768), maar een lager aantal css-pixels door bij een media query. De 192 dpi van het mobieltje is twee keer zo veel als de 96 dpi van een normaal beeldscherm. Het aantal css-pixels is dan het aantal schermpixels gedeeld door 2. 1024 x 768 gedeeld door 2 is 512 x 384 px. Het aantal css-pixels is 512 x 384 px en zit daarmee dus ruim onder de 760 px van deze media query. Je bent dus niet opgelicht, of in ieder geval niet wat betreft het aantal pixel.
Door deze truc is een lijn van 1 px breed op een normaal beeldscherm ook op het mobieltje nog steeds 1 px breed, alleen wordt die ene (css-)pixel opgebouwd uit twee schermpixels (feitelijk vier, want het verhaal geldt voor breedte én hoogte). De dikte van het lijntje is hetzelfde, maar het is veel fijner opgebouwd. Bij lijntjes is dat verschil bijvoorbeeld in bochten goed te zien.
Hetzelfde verhaal geldt voor hogere resoluties, Een tablet met een breedte van 4096 schermpixels en een dpi van 384 (vier keer de originele dichtheid) geeft 4096 gedeeld door 4 = 1024 css-pixel door. Het lijntje van 1 px breedte op de originele monitor is nog steeds 1 css-pixel breed op de tablet, maar die ene css-pixel is nu opgebouwd uit zestien schermpixel.
(Overigens kun je met behulp van media query's ook testen op de resolutie met gebruik van het sleutelwoord 'resolution'. Apple gebruikt het niet-standaard 'device-pixel-ratio', maar het idee is hetzelfde. Dit kan bijvoorbeeld handig zijn om te bepalen, hoe groot een foto moet zijn.)
Kort samengevat: omdat niet het aantal schermpixels (waarvoor je hebt betaald), maar het aantal css-pixels (de door de ontwerper bedoelde afmeting) wordt doorgegeven, wordt voorkomen dat een hogeresolutiescherm onleesbaar klein wordt.
body
Voor dit element is eerder css opgegeven. Deze wordt binnen dit blokje herhaald in de volgorde, waarin deze in de stylesheet staat, zodat alles hier overzichtelijk bij elkaar staat. (Alleen wat binnen deze media query geldig is, wordt binnen dit blokje herhaald.)
body {background: #ff9; color: black; font-family: Arial, Helvetica, sans-serif; margin: 0; padding: 0;}
Het element waarbinnen de hele pagina staat. Veel instellingen die hier worden opgegeven, worden geërfd door de nakomelingen van <body>. Ze gelden voor de hele pagina, tenzij ze later worden gewijzigd. Dit geldt bijvoorbeeld voor de lettersoort, de lettergrootte en de voorgrondkleur.
font-size: 110%;
Iets groter dan standaard. 't Zal de leeftijd zijn, maar ik vind de standaardgrootte wat te klein.
Als eenheid wordt de relatieve eenheid %
gebruikt, omdat bij gebruik van een absolute eenheid zoals px
niet alle browsers de lettergrootte kunnen veranderen. Zoomen kan wel altijd, ongeacht welke eenheid voor de lettergrootte wordt gebruikt.