Uitleg menu voor kinderen met tekening en pop-ups. Elk puzzelstukje is een link
Laatst aangepast: .
Korte omschrijving
Achter elk puzzelstukje zitten een link naar een andere pagina en een – voor (de meeste) kinderen – grappige pop-up. Link en pop-up worden pas zichtbaar bij hoveren over of aanraken van een puzzelstukje.
BELANGRIJK
Alles op deze site kan vrij worden gebruikt, met twee beperkingen:
* Je gebruikt het materiaal op deze site volledig op eigen risico. Het kan prima zijn dat er fouten in de hier verstrekte info zitten. Voor eventuele schade die door gebruik van materiaal van deze site ontstaat, in welke vorm dan ook, zijn www.css-voorbeelden.nl en medewerkers daarvan op geen enkele manier verantwoordelijk.
* Deze uitleg wordt regelmatig bijgewerkt. Het is daarom niet toegestaan deze uitleg op welke manier dan ook te verspreiden, zonder daarbij duidelijk te vermelden dat de uitleg afkomstig is van www.css-voorbeelden.nl en dat daar altijd de nieuwste versie is te vinden. Dit is om te voorkomen dat er verouderde versies worden verspreid.
Een link naar www.css-voorbeelden.nl wordt trouwens altijd op prijs gesteld.
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 in een gewone letter vanwege de leesbaarheid.)
Opmerkingen
-
Het invullen van een nieuw puzzelstukje kan, afhankelijk van wat je wilt, heel erg lastig zijn. Zo blijkt een touchscreen in Internet Explorer 11 nogal op hol te slaan bij gebruik van een afbeelding in een pop-up: de pop-up blijft niet zonder meer open, als deze een afbeelding bevat. Bij drie verschillende pop-ups met afbeeldingen waren drie verschillende oplossingen nodig, omdat geen van de oplossingen bij élke pop-up werkte.
Dat betekent dus, dat je echt heel grondig moet testen.
-
Het plaatje van de mailbox komt van de niet meer bestaande site www.hellasmultimedia.com.
De achtergrond van het menu komt van karenswhimsy.com/public_domain_images. Het puzzelpatroon is aangebracht met Gimp.
De dansende letters komen van calendarofupdates.com. Deze site bestaat helaas niet meer, daarom zijn in de download de niet in het voorbeeld gebruikte letters ook bijgesloten. Mocht iemand ze willen gebruiken, dan kan dat nu.
De krokodil en de olifant komen van de helaas niet meer bestaande site www.davidpye.com. Het wolkje bij de krokodil is aangebracht met Gimp.
-
Op de site staat op de pagina met het puzzelmenu ook nog het navigatiemenu voor de site zelf. In lage browservensters staat dit menu over de bovenkant van het puzzelmenu heen. De plaatsing over de puzzel is niet erg fraai, maar is gedaan omdat er in een klein venster nou eenmaal heel weinig ruimte is. 'In het echt' zet je natuurlijk geen navigatieknoppen over zo'n puzzel heen, maar los je dit op 'n andere manier op.
Vanwege de plaatsing van de navigatie voor de site aan de bovenkant op de puzzel, is op de site de positie van enkele pop-ups en knoppen iets aangepast en dus anders dan die in de download.
Op de site zelf staat de <h1> in lage browservensters aan de onderkant over de afbeelding met de puzzel heen. Aan de onderkant, omdat daar geen links zitten die kunnen worden geblokkeerd door de <h1>. De tekst van de <h1> is ook nogal anders dan die van de <h1> in de download, omdat het op de site de titel van de pagina is. Ook hier geldt weer: 'in het echt' zet je natuurlijk de titel van een pagina niet pontificaal over het belangrijkste onderdeel van die pagina heen.
-
Het gaat hier om een menu voor kinderen, waarbij de pop-ups niet echt onmisbaar zijn. Normaal genomen moet je nooit belangrijke informatie verstoppen onder een pop-up, omdat je nooit helemaal zeker kunt weten of zo'n pop-up wel goed werkt. Mensen kunnen css uit hebben staan, of de benodigde css kan niet of foutief zijn geïmplementeerd in de browser.
De links onder het menu, in principe de belangrijkste onderdelen, werken ook zonder css. (Hoewel dat er niet echt fraai uitziet.)
-
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 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.
-
Er worden nogal wat afbeeldingen aangeroepen: elke bewegende letter is er eentje. En dan zijn er nog de bewegende krokodil en mailbox. Dat is voor elke afbeelding een aanroep naar de server. In een aanpassing enige tijd geleden schreef ik dat ik daar nu een sprite voor zou gebruiken: één grote afbeelding waar de andere afbeeldingen op worden geplaatst. Die afbeelding kost maar één aanroep naar de server. Met behulp van
background-position
zet je dan het juiste deel van de grote afbeelding op de juiste plaats, zodat je alleen het stukje ziet dat je wilt zien.Dat heb ik kennelijk in staat van grote opwinding of zo geschreven, want dat kan helemaal niet. De bewegende afbeeldingen zijn gifs. In werkelijkheid beweegt een gif helemaal niet, maar bestaat uit een hele serie afbeeldingen. Elke afbeelding zit op een eigen laag. Door de afbeelding op zo'n laag steeds iets te veranderen ten opzichte van de eerdere of latere laag en die lagen snel achter elkaar te laten zien, ontstaat de illusie van beweging. Inderdaad, je wordt belazerd waar je bij staat.
Elke gif bestaat uit een aantal lagen. Om meerdere gifs in een sprite samen te voegen, zou je elk van die lagen naast elkaar moeten monteren. Elke gif moet dan ook nog exact hetzelfde aantal lagen hebben, wat niet zo is.
Er zijn 21 gifs en deze regering bezuinigt schandalig op de geestelijke gezondheidszorg.
Die combinatie zorgt ervoor dat ik dit niet doe, want dat samenvoegen – als het al lukt – leidt gegarandeerd tot een intieme kennismaking met de Crisisdienst.
Je zou de olifant en de uitgang kunnen samenvoegen, want die bewegen niet, maar dat is nauwelijks de moeite waard. Bovendien werkt een sprite alleen bij achtergrond-afbeeldingen, en een gewone afbeelding werkt hier makkelijker.
Links in deze uitleg, vooral links naar andere sites, kunnen verouderd zijn. Op de pagina met links vind je steeds de meest recente links.
Alles op deze site is gemaakt op een systeem met Linux (Kubuntu). Daarbij is vooral gebruik gemaakt van Komodo Edit, GIMP en Firefox met extensies. De pdf-bestanden zijn gemaakt met LibreOffice.
Vragen of opmerkingen? Fout gevonden? Ga naar het forum.
Achterliggend idee
Boven een afbeelding van een puzzel wordt een ongeordende lijst <ul> geplaatst. Elk lijst-item <li> binnen die <ul> wordt even groot gemaakt als een puzzelstukje. Hierdoor ontstaat een rooster, waarvan elk vakje precies één puzzelstukje bestrijkt.
Binnen elke <li> staat een link naar een achterliggende pagina. (Ik overdrijf: dat geldt maar voor vier <li>'s, want de andere acht zijn nooit afgemaakt.) Gelijk na deze link staat een <span>, waarbinnen een pop-up staat. Link en pop-up zijn normaal genomen niet zichtbaar. De <span> wordt op verschillende manieren verborgen, de <a> wordt links buiten het scherm geparkeerd. Omdat de <a> gewoon aanwezig is, kunnen schermlezers en dergelijke de links gewoon voorlezen.
Als er over de <li> wordt gehoverd of als deze wordt aangeraakt, opent de in de <li> zittende <span> met de pop-up. Als je de Tab-toets gebruikt om van link naar link te gaan, verschijnt de bij de <a> horende <span> met pop-up, zodra de de <a> focus heeft. Ook de <a> zelf verschijnt, zodra deze focus heeft. De <a> ziet eruit als een knop.
Deze beschrijving is tamelijk simpel, de praktische uitwerking was wat lastiger, omdat elk systeem z'n eigen geniale allerbeste fantastische manier heeft om hover en dergelijke af te handelen. Bovendien blijkt Internet Explorer nogal van slag te raken, als er een afbeelding in de pop-up zit. Voor elke pop-up moest een eigen oplossing worden gevonden, want geen enkele oplossing werkte voor elke pop-up. iOS is een geval apart, want dat systeem begint te niezen als het 'hover' hoort. Daar was dus weer een andere oplossing voor nodig met een minieme hoeveelheid JavaScript.
Kortom: zodra je met pop-ups gaat werken en geen JavaScript wilt gebruiken (of althans zo weinig mogelijk), dan is uitgebreid testen op verschillende systeem absoluut noodzakelijk. Alsmede het in bezit hebben van een ruime hoeveelheid scheldwoorden, kalmerende middelen, alcohol en huisgenoten of op z'n minst huisdieren om de schuld te kunnen geven.
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 en Safari: -webkit-
.
(Google Chrome is van webkit overgestapt op een eigen weergave-machine: blink. Blink zou geen voorvoegsels gaan 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 inmiddels Blink, inclusief het daar nog in gebruikte -webkit-
. Hierdoor is het tot voor kort door Opera gebruikte voorvoegsel -o-
niet meer nodig.)
Internet Explorer: -ms-
, naar de maker: Microsoft.
In dit voorbeeld worden hyphens
, linear-gradient
, transform
en transition-delay
gebruikt.
Zodra de experimentele fase voorbij is, wordt het voorvoegsel weggelaten. Omdat dat moment niet bij alle browsers hetzelfde is, zet je nu ook al de officiële naam erbij. Deze wordt als laatste opgegeven. Bijvoorbeeld Android browser herkent -webkit-linear-gradient
. Zodra Android browser linear-gradient
gaat herkennen, zal dit -webkit-linear-gradient
overrulen, omdat het er later in staat. Dat ze er beide in staan, is dus geen enkel probleem.
hyphens
Op dit moment moet je nog het volgende schrijven:
{-moz-hyphens: ...; -ms-hyphens: ...; -webkit-hyphens: ...; hyphens: ...;}
In de toekomst kun je volstaan met:
{hyphens: ...;}
linear-gradient:
Op dit moment moet je nog het volgende schrijven:
{-webkit-linear-gradient: ...; linear-gradient: ...;}
In de toekomst kun je volstaan met:
{linear-gradient: ...;}
Internet Explorer 9 kent linear-gradient
helemaal niet, die negeert deze regel gewoon.
(De syntax van linear-gradient
is nogal fors gewijzigd tijdens de proefperiode. Voor oudere op webkit gebaseerde browsers was er een syntax die begon met -webkit-gradient(linear
. Die gebruik ik niet meer, want er zijn steeds minder browsers die die syntax gebruiken. Die krijgen gewoon geen gradiënt.)
transform:
Op dit moment moet je nog het volgende schrijven:
{-ms-transform: ...; -webkit-transform: ...; transform: ...;}
In de toekomst kun je volstaan met:
{transform: ...;}
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 ze in het Engels heten, geen groot succes zijn. Eén van de grootste problemen: veel sitemakers gebruiken alleen de -webkit-
variant. Daar kwamen ze in het verleden nog mee weg, omdat Apple op mobiel zo'n beetje 'n monopolie had. Inmiddels is dat niet meer zo, maar deze gewoonte bestaat nog steeds. Waardoor 'n site alleen in op webkit georiënteerde browsers goed is te bekijken.
Dit is zo'n groot probleem, dat andere browsers soms de variant met -webkit-
ook maar zijn gaan implementeren, naast de standaard. Want als 'n site het niet goed doet in 'n bepaalde browser, krijgt in de regel niet de site maar de browser de schuld.
Voorlopig zijn we echter nog niet van deze voorvoegsels af. Als je ze gebruikt, gebruik dan álle varianten, en eindig met de variant zonder voorvoegsel, zoals die uiteindelijk ooit gebruikt gaat worden. Als je alleen de -webkit-
variant gebruikt, ben je in feite 'n onbetaalde reclamemaker voor Apple.
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!). Enz.
Door het op de goede manier gebruiken van semantische elementen, kunnen zoekmachines, schermlezers, enz. 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 <nav> gebruikt.
Deze tag gedraagt zich als een gewone <div>, maar dan een <div> met een semantische betekenis: navigatie. Hierdoor kunnen schermlezers, zoekmachines, en dergelijke gelijk zien dat hierin links zijn ondergebracht, waarmee je naar andere pagina's en dergelijke kunt gaan.
Omdat <nav> alleen aangeeft dat hierin een of andere vorm van navigatie is ondergebracht, maar niet wat voor navigatie, staat gelijk onder de openingstag <nav> een <h1> De <h1> geeft aan, wat voor soort navigatie hier staat: 'Menu met spelletjes'. Deze <h1> wordt links buiten het scherm geparkeerd, zodat je hem niet ziet. Maar schermlezers en dergelijke lezen de kop gewoon voor, ook al zie je hem niet, zodat duidelijk is wat voor soort navigatie hier staat.
In het voorbeeld staat maar één soort navigatie, maar bijvoorbeeld op de site staat niet alleen het puzzelmenu, maar ook de navigatie voor de site zelf. Door op de site beide <nav>'s van een verborgen kop te voorzien, kunnen schermlezers en dergelijke achterhalen, om welke navigatie het gaat.
(Normaal genomen zul je hier geen <h1> voor gebruiken, maar een <h2> of nog lager. Maar op deze pagina is de <h1> de enige kop.)
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 de <nav>. Dat is een al veel langer bestaande code, die schermlezers en dergelijke wel herkennen. Voor een <nav> ziet dat er zo uit:
<nav role="navigation">
Inmiddels is dit behoorlijk veranderd. Het advies is nu, om deze speciale toevoeging niet meer te gebruiken, omdat de meeste schermlezers en dergelijke een <nav> 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-label
.
aria-hidden
Met behulp van aria-hidden="true"
kan een deel van de code worden verborgen voor schermlezers en dergelijke, zodat dit niet wordt voorgelezen. Op de normale weergave op het scherm heeft dit verder geen enkele invloed.
In dit geval kunnen de pop-ups nogal verwarrend zijn, als ze worden voorgelezen. Bij het negende stukje over de mail bijvoorbeeld kun je gelijk zien, dat het om een steeds herhaalde tekst gaat, die steeds kleiner wordt. En zie je ook gelijk dat je een e-mail kunt versturen.
Een schermlezer echter leest die tekst volledig voor, en van een eindeloos herhaalde tekst worden mensen waarschijnlijk niet gelukkiger. Om die reden wordt de tekst van de eerste en negende pop-up (de krokodil en de mail) verborgen. Van de tweede pop-up worden de dansende letters verborgen. Bij alle drie gebeurt dit met de volgende code :
<span aria-hidden="true">
Hiermee wordt de inhoud van de <span>, de pop-up, verborgen.
Bij de zesde pop-up, de uitgang, is er geen <span>. De afbeelding wordt daar verborgen met:
<img src="014-pics/menu-014-uitgang.jpg" width="260" height="125" alt="Afbeelding 2: " aria-hidden="true">
In principe is alt=""
al voldoende, omdat daarmee wordt aangegeven dat het om een onbelangrijke afbeelding gaat, maar sommige schermlezers en dergelijke geven dan toch nog aan dat hier een afbeelding staat. (In ieder geval in het verleden was dat zo.) Dus voor de zekerheid wordt hier ook aria-hidden="true"
toegevoegd aan de <img>.
aria-label
De links worden niet verborgen voor schermlezers, dus deze worden gewoon voorgelezen. Alleen is de tekst van de links niet overal even duidelijk, omdat deze wat speels is (of in ieder geval is dat speelse geprobeerd...).
De tekst in de eerste link is voor iedereen wat vreemd: 'Ja! Krokodillen aaien! Leuk!' Of je nou kunt zien of niet. Dus dat wordt niet aangepast.
Hetzelfde geldt voor de tekst van de tweede link: Letterdans.
De tekst in de derde link (bij het zesde stukje) is 'Wegwezen!' In combinatie met de afbeelding met 'Uitgang' is dat wel duidelijk, maar zonder die afbeelding niet. Daarom wordt in deze link een aria-label
toegevoegd:
<a href="014-files-dl/menu-014-uitgang-dl.html" aria-label="Verlaat dit menu">Wegwezen!</a>
Afhankelijk van schermlezer en instellingen wordt nu 'Verlaat dit menu' gebruikt, wat duidelijker is dan 'Wegwezen!'
In de vierde link, bij het negende stukje) is de tekst van de link 'E-mail'. Ook dat is mogelijk niet duidelijk, daarom wordt ook hier een aria-label
toegevoegd:
<a href="014-files-dl/menu-014-mail-dl.html" aria-label="Stuur ons een mail">E‑mail</a>
Nu is duidelijk dat het om het versturen van een mail gaat, en niet om lezen of zoiets.
Tabindex
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.
Als je met behulp van de Tab-toets een element hebt bereikt, heeft dit 'focus': als het een link is en je drukt op Enter, wordt de link gevolgd. Bij een tekstveld kun je tekst gaan invoeren. Enz. Normaal genomen wordt focus aangegeven door een lijntje rondom het element dat focus heeft. Bij de links onder de puzzelstukjes worden knop en pop-up zichtbaar, als de link focus heeft. Daarmee is dat lijntje overbodig geworden.
De Tab-toets volgt de volgorde van de elementen in de html. Het maakt niet uit, hoe 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 werking van de Tab-toets kan worden veranderd met behulp van het attribuut tabindex
: <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.
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. Als alle positieve getallen zijn bezocht, worden daarna tabindexen met '0' bezocht. De '0' zorgt er dus voor dat deze als laatste worden bezocht.
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"
gebruikt bij de vier <li>'s die in gebruik zijn. Voor de eerste <li> ziet dat er als volgt uit:
<li id="een">
Eigenlijk zou dit niet nodig moeten zijn, maar sommige touchscreens reageren vertraagd op een aanraking. Dat is om te kijken of er nog een tweede aanraking volgt (vergelijkbaar met een dubbelklik bij de muis). In dit voorbeeld is dat niet nodig, want er zit maar één 'klik' op de <li>, dus wachten op een mogelijke tweede aanraking is niet nodig.
Maar Internet Explorer 11 op een touchscreen in Windows 8 wacht toch op die tweede aanraking. Daardoor blijft de pop-up pas geopend, als je het scherm iets langer aanraakt. Internet Explorer 11 en UC browser op Windows phone openen de pop-up zelfs helemaal niet. Deze tabindex zorgt dat de pop-up gewoon met één korte aanraking openblijft. Omdat het een negatieve tabindex is, heeft deze verder geen invloed op de volgorde van de Tab-toets.
(In Internet Explorer doet zich het eigenaardige verschijnsel voor dat de tabindex niet nodig is als je geen <ul> met <li>'s gebruikt, maar de pop-up in een <div> onderbrengt. Maar een <ul> voor een menu is makkelijker en toegankelijker, dus dat is geen goede oplossing.)
tabindex="0"
Wordt gebruikt bij de <li>'s die nog geen pop-up en dergelijke hebben:
<li tabindex="0"></li>
Het heeft hier twee functies:
* Sommige mensen kunnen of willen de muis niet gebruiken om links en dergelijke af te lopen, maar gebruiken hiervoor de Tab-toets. Een <li> wordt normaal genomen genegeerd bij gebruik van de Tab-toets. Door tabindex="0"
toe te voegen, wordt de link toch bezocht en opent de in de <li> zittende tekst ook bij gebruik van de Tab-toets. Een tabindex met de waarde 0 wordt bezocht na alle andere tabindexen met een positieve waarde. Omdat die hier niet aanwezig zijn. worden alle <li>'s gewoon in volgorde bezocht.
* Het lost een probleem in Internet Explorer op touchscreens in Windows 8, en in Internet Explorer 11 en UC browser op Windows Phone op, zoals gelijk hierboven beschreven bij tabindex="-1"
.
tabindex="..."
Op de plaats van de puntjes moet een positief getal worden ingevuld: het volgnummer. Er is ruimte voor, afhankelijk van de browser, minimaal 32767 tabindexen, dus daar kun je aardig wat links en dergelijke mee bedienen.
Met behulp van een nummer kan de volgorde van de Tab-toets daadwerkelijk worden gewijzigd. Alle elementen met een tabindex worden in de volgorde van het nummer afgelopen. Elementen zonder tabindex of met tabindex="0"
worden bezocht, nadat alle elementen met een positief volgnummer zijn afgewerkt.
Als je dat zou willen, zou je de Tab-toets als eerste naar 'n footer onderaan de pagina kunnen laten gaan, daarna helemaal naar boven en vervolgens naar het midden. En als je toevallig neoliberaal bent en alles in financiële waarde vertaalt, moet je dat vooral doen, want dit levert de fabrikanten van kalmerende middelen, psychiaters, enz. bergen extra werk op en stimuleert dus Sint Economie.
Voor alle niet-neoliberalen: niet doen. De tabindex is bedoeld voor kleine correcties, niet om van je bezoeker een door een jager achtervolgd konijn in een doolhof te maken. Een schermlezer volgt trouwens altijd de volgorde van de html, dus ook voor een schermlezer kunnen grote ingrepen uiterst verwarrend zijn.
Als je de tabindex gebruikt om de volgorde te veranderen, let er dan op dat je dat goed doet. Alle velden in een bestelformulier van een tabindex voorzien, maar dat bij de verzendknop vergeten, helpt niet bij je volgende gesprek over loonsverhoging.
De volgnummers van de tabindex hoeven niet op elkaar aan te sluiten. Het is zelfs beter als dat niet zo is. Lang geleden heb ik 'ns handmatig honderden tabindexen in zitten typen. Netjes op elkaar aansluitend, want tellen kan ik prima. Iets later moest er helemaal aan het begin eentje worden tussengevoegd. Aangezien de nummers zo fantastisch foutloos op elkaar aansloten, moest elk hoger nummer dus handmatig worden veranderd. Volgens mijn therapeut is dit de oorzaak van mijn nog steeds terugkerende angstdromen over genummerde schapen, waar zich plotseling een ongenummerde ram tussen probeert de dringen. Oftewel: zoiets doe je maar één keer.
Het beste is, als de volgorde van de html gewoon ook de meest logische volgorde voor de tabindex is. Dat is hier het geval: een positieve tabindex wordt niet gebruikt.
Muis, toetsenbord, touchpad en touchscreen
Vroeger, toen het leven nog mooi was en alles beter, waren er alleen monitors. Omdat kinderen daar niet af konden blijven met hun tengels, besloten fabrikanten dan maar touchscreens te gaan maken, omdat je die mag aanraken. Het bleek makkelijker te zijn om volwassenen ook te leren hoe je 'n scherm vies maakt, dan om kinderen te leren met hun vingers van de monitor af te blijven.
Zo ontstonden touchscreens en kreeg het begrip ellende een geheel nieuwe lading. In de perfecte wereld van vroeger, waarin alleen desktops bestonden, werkten dingen als hoveren, klikken en slepen gewoon. Zonder dat je eerst 'n cursus hogere magie op Zweinstein hoefde te volgen. Zelfs in JavaScript was het nog wel te behappen, ook voor mensen zoals ik die toevallig niet Einstein heten.
Op dit moment kun je computerschermen ruwweg in twee soorten indelen: schermen die worden aangeraakt, en schermen die worden bediend met hulpmiddelen als een toetsenbord, muis of touchpad. Omdat ook computerschermen zich kennelijk vermengen, bestaan er inmiddels ook schermen die zowel van aanraken als van muizen houden.
Hieronder staat een lijstje met dingen die zijn aangepast voor de verschillende soorten schermen, zodat dit voorbeeld overal werkt.
:hover
Omdat :hover
mogelijk niet werkt, als css uitstaat, ontbreekt of onvolledig is geïmplementeerd, moet je nooit belangrijke informatie alleen met behulp van :hover
tonen.
Je hovert over een element, als je met behulp van muis of touchpad de cursor boven dat element brengt. Hoveren kan over álle elementen. Het wordt veel gebruikt om iets van uiterlijk te laten veranderen, een pop-up te laten verschijnen, en dergelijke.
In dit voorbeeld levert hover niet al te veel problemen op, omdat hover niet wordt gecombineerd met klikken. 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.
In de vorige versie van dit voorbeeld waren hover en klikken beide gekoppeld aan de link. Dat leverde op touchscreens enorme problemen op. Was de aanraking bedoeld als 'hover' of als 'klik'? Elk systeem lost dit dilemma op z'n eigen manier op.
In deze versie zijn de hover en de klik van elkaar gescheiden. De hover zit op de <li>, dat opent de <a>, en de klik zit dan op die <a>. Alle touchscreens kunnen de hover nu goed afhandelen: de pop-up en de link openen. Op een touchscreen blijven ze geopend, zodat daarna de link kan worden aangeraakt.
Internet Explorer 11 op een touchscreen en UC browser op Windows Phone leveren problemen op. Bij aanraking van een <li> openen de daarin zittende pop-up en link wel, maar ze sluiten gelijk weer, omdat wordt gewacht op een mogelijke tweede aanraking (wat bij een muis een 'dubbelklik' is). Daardoor moet je in deze browsers het scherm langer aanraken voordat pop-up en link geopend blijven. Door aan de <li> ook een :focus
te koppelen, blijven pop-up en link ook in deze browsers gelijk geopend.
Hiervoor moet ook een tabindex="-1"
worden gegeven aan de <li>. Meer daarover is te vinden bij Tabindex.
Om hoveren op iOS goed te laten werken, is een minimale hoeveelheid JavaScript nodig. Daarover is meer te vinden bij JavaScript.
:focus
Omdat :focus
mogelijk niet werkt, als css uitstaat, ontbreekt of onvolledig is geïmplementeerd, moet je nooit belangrijke informatie alleen met behulp van :focus
tonen.
De meeste mensen gaan met een muis naar een link, invoerveld, en dergelijke. Waarna ze vervolgens klikken om de link te volgen, tekst in te voeren, of wat ze ook maar willen doen.
Er is echter 'n tweede manier om naar links, invoervelden, en dergelijke te gaan: met behulp van de Tab-toets (sommige browsers gebruiken andere toetsen, maar het principe is hetzelfde). Met behulp van de Tab-toets kun je naar links, invoervelden, en dergelijke 'springen'. (Over het gebruik van de Tab-toets staat meer bij Tabindex.)
Waar je staat, wordt door alle browsers aangegeven met een of ander kadertje. De link en dergelijke met het kadertje eromheen 'heeft focus'. Dat wil zeggen dat je die link volgt, als je op de Enter-toets drukt, of dat je in dat veld tekst kunt gaan invoeren, enz.
Het kadertje dat de focus aangeeft, moet nooit zonder meer worden weggehaald. Gebruikers van de Tab-toets hebben dan geen idee meer, waar ze zijn. Maar in dit voorbeeld kan het kadertje veilig worden weggehaald, omdat bij focus een knop en een pop-up verschijnen.
Eigenlijk is de focus alleen nuttig bij gebruik van een toetsenbord, maar om een of andere mij niet geheel duidelijke reden reageert iOS er ook op. Als je op 'n element 'n :focus
én 'n :hover
zet, blijft die :focus
op iOS van kracht, tot je 'n andere link, knop, of zoiets aanraakt. Dat is hier het geval bij de <li>'s.
Als je 'n <li> aanraakt, houdt deze dus focus. Tot je 'n andere <li> aanraakt, want dan krijgt die focus. Bij aanraken op een andere plaats sluit de pop-up niet, wat nogal irritant is. Dit is opgelost door onclick=""
, een klein stukje JavaScript, aan te brengen bij div#wrapper
:
<div id="wrapper" onclick="">
.
Je kunt daar meer over vinden bij JavaScript.
De code aanpassen aan je eigen ontwerp
- Als je dit voorbeeld gaat aanpassen voor je eigen site, houdt 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. Als je beslist iets van Microsoft wilt gebruiken, schaf dan (voor 'n fikse prijs) een nieuwer programma aan, dat zich wel aan de standaarden houdt.
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, enz. 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 '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 doctype voor html5 is uiterst simpel:
<!DOCTYPE html>
.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.
- 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 ikzelf op test. 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 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 enz., 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 einde (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.
-
Marges, padding en border worden bij de hoogte en breedte van de inhoud 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
margin
,padding
enborder
bínnen de breedte en hoogte van de inhoud te zetten met behulp vanbox-sizing
, als je dat handiger vindt. -
In plaats van
px
kun je ook andere maten gebruiken, met nameem
. Voordeel vanem
is dat een lettergrootte, regelhoogte, en dergelijke in em ook in Internet Explorer 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.
Je kunt je css en html zowel valideren, als 't online staat, als wanneer 't nog in je computer staat.
html kun je valideren op: validator.w3.org/nu.
css kun je valideren op: jigsaw.w3.org/css-validator.
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.
Toegankelijkheid en zoekmachines
Het eerste deel van deze tekst is voor alle voorbeelden hetzelfde. Eventueel specifiek voor dit voorbeeld geldende dingen staan verderop onder het kopje Specifiek voor dit voorbeeld.
Toegankelijkheid (accessibility in het Engels) is belangrijk voor bijvoorbeeld blinden die een 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. - 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: 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
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. -
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 andere mogelijkheid is een zogenaamde skip-link: 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 zichtbaar in speciale programma's zoals tekstbrowsers en schermlezers, want die kijken gewoon naar wat er in de broncode staat.
Zo'n 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 ook 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.
-
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. Zoekmachines zijn ook niet dol op een oerwoud van inline-stijlen (dat zijn stijlen in de tag zelf:
<div style="...">
.) -
Breng een logische structuur aan in je document. Gebruik een <h1> voor de belangrijkste kop, een <h2> voor een subkop, enz. 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 'n lagere plaats in een zoekmachine.
-
Frames zijn 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 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 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.
- Geef de taal van het document aan, en bij woorden en dergelijke die afwijken van die taal de afwijkende taal met behulp van
lang=".."
. Ik doe dat op mijn eigen site maar af en toe, omdat de tekst (en vooral de code) een mengsel is van Engels, Nederlands en eigengemaakte namen. Dit 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. Ik noem er hier enkele.
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
* De links naar de uitgang en voor het sturen naar een mail zijn niet echt duidelijk, als je de bijbehorende pop-ups niet ziet. Daarom hebben deze links met behulp van aria-label
aanvullende, duidelijker tekst gekregen. Meer hierover bij WAI-ARIA-codes.
* De pop-ups zijn voor schermlezers verborgen met behulp van aria-hidden
, omdat ze zonder afbeeldingen en dergelijke verwarrend zijn. Meer hierover bij WAI-ARIA-codes.
* Gelijk onder <nav> is een buiten het scherm verborgen <h1> aangebracht met daarin een omschrijving van het menu.
* De links zijn ook bereikbaar met de Tab-toets: ze worden één voor één afgelopen. Zodra een link focus heeft, openen bijbehorende pop-up en knop met link.
* Zonder afbeeldingen werkt alles wel, maar het wordt wel lastig, omdat je bijvoorbeeld ook de puzzelstukjes niet ziet.
* Zonder css zijn de links wel zichtbaar, maar de pop-ups ook. Dit is uiterst verwarrend. Maar het lijkt me niet dat mensen die een tekstbrowser zoals Lynx gebruiken, op dit soort menu's zitten te wachten.
* Alleen op iOS wordt wat JavaScript gebruikt. Maar daar is dat JavaScript ook absoluut onmisbaar, omdat de links niet verschijnen zonder JavaScript. Vrijwel niemand zal dat echter uitzetten op iOS, omdat je dan weinig meer hebt aan je (peperdure) smartphone of tablet. Meer over JavaScript bij JavaScript.
Getest in
Laatst gecontroleerd op 23 juli 2015.
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 te lezen, want uit een test kan ook prima blijken dat iets totaal niet werkt!
Eventuele opmerkingen over de toegankelijkheid specifiek voor dit voorbeeld staan onderaan Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.
Dit voorbeeld is getest op de volgende systemen:
- Windows 7:
Firefox, UC Browser, Google Chrome, Internet Explorer 9 en 10 in de resoluties 800x600, 1024x768 en 1280x1024. - Windows 8.1:
Bureaublad-versie: Firefox, UC Browser, Google Chrome en Internet Explorer 11 in de resoluties 800x600, 1024x768 en 1366x768.
Startscherm-versie: Internet Explorer 11. - OS X:
Firefox, Safari en Google Chrome in een resolutie van 1680x1050 en kleiner.
Kleiner is wat vaag: het browservenster is traploos verkleind van 1680x1050 tot ongeveer 1000x600. Waarbij alle tussenliggende groottes dus ook zijn getest.
In Safari is ook de Reader-weergave getest. - Linux:
Firefox en Google Chrome in de resoluties 800x600, 1024x768 en 1280x1024. - Windows Phone 8.1 in een resolutie van 800x480 (Nokia Lumia 520):
Internet Explorer (portret en landschap).
UC Browser (portret en landschap).
Opera Mini (portret en landschap). Meer over deze browser hieronder bij Android 4.4.2. - iPad met iOS 8.4 in een resolutie van 1024x768 (MC979NF):
Safari (reader-weergave aan/uit, portret en landschap).
Opera Mini (portret en landschap). Meer over deze browser hieronder bij Android 4.4.2.
Chrome for IOS (portret en landschap).
UC Browser (portret en landschap). - Android 4.1.2 in een resolutie van 800x480 (Samsung Galaxy Core i8620):
Chrome, Android browser, UC Browser en Firefox (alle portret en landschap).
Opera Mini (éénkolomsstand aan/uit, portret en landschap). Meer over deze browser hieronder bij Android 4.4.2. - Android 4.4.2 in een resolutie van 1280x800 (Samsung Tab 3):
Android browser, UC Browser, Firefox en Chrome (alle portret en landschap).
Opera Mini (éénkolomsstand aan/uit, portret en landschap). Deze browser is een apart geval. De opgevraagde site wordt gedownload via de servers van Opera, waarbij het in zo'n klein venster normaal is dat (een groot deel van) de lay-out wordt verwijderd. Daarom wordt bij deze browser voornamelijk gekeken, of er geen content (tekst en dergelijke) verloren gaat.
Er is steeds getest met de laatste versie van de browsers op de aan het begin van dit hoofdstukje genoemde controledatum, omdat ik geen zin heb om rekening te houden met mensen die met zwaar verouderde browsers surfen. Dat is trouwens vragen om ellende, want updates van browsers hebben heel vaak met beveiligingsproblemen te maken.
Ook op Windows XP kunnen mensen surfen met Firefox, Opera of Google Chrome, dus ook daar zijn mensen niet afhankelijk van Internet Explorer 8. Ik maak één uitzondering: Android browser. Omdat Android vaak niet geüpdatet kan worden, test ik ook nog in oudere versies van Android browser.
In resoluties groter dan 800x600 is ook in- en uitzoomen en – voor zover de browser dat kan – een kleinere en grotere letter getest. Er is ingezoomd en vergroot tot zover de browser kan, maar niet verder dan 200%.
Er is getest met behulp van muis en toetsenbord, behalve op de iPad, Android en Windows Phone, waar een touchscreen is gebruikt. Op Windows 8.1 is getest met een touchscreen, met een combinatie van toetsenbord en touchpad, en met een combinatie van toetsenbord en muis.
Op de desktop is ook getest, als JavaScript uitstaat. Eventuele problemen staan hierboven bij Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld. (Op iOS, Android en Windows Phone is niet getest zonder JavaScript, omdat je JavaScript in een toenemend aantal mobiele browsers niet uit kunt zetten. Bovendien is een mobiel apparaat zonder JavaScript niet veel meer dan een duur en groot uitgevallen horloge.)
Naast deze 'gewone' browsers is ook getest in Lynx, WebbIE, NVDA, TalkBack en VoiceOver.
Lynx is een browser die alleen tekst laat zien en geen css gebruikt. Er is getest op Linux.
WebbIE is een browser die gericht is op mensen met een handicap. Er is getest op Windows 7.
NVDA is een schermlezer, zoals die door blinden wordt gebruikt. Er is getest in combinatie met Firefox op Windows 7.
TalkBack is een in Android ingebouwde schermlezer. Er is getest in combinatie met Chrome.
VoiceOver is een in iOS en OS X ingebouwde schermlezer. Er is getest in combinatie met Safari op iOS en OSX.
Als het voorbeeld in deze programma's toegankelijk is, zou het in principe toegankelijk moeten zijn in alle aangepaste browsers en dergelijke. En dus ook voor zoekmachines, want een zoekmachine is redelijk vergelijkbaar met een blinde. Eventuele opmerkingen over de toegankelijkheid specifiek voor dit voorbeeld staan hierboven bij Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.
Alleen op de hierboven genoemde systemen en browsers is getest. Er is dus niet getest op bijvoorbeeld 'n Blackberry. De kans is (heel erg) groot dat dit voorbeeld niet (volledig) werkt op niet-geteste systemen en apparaten. Om het wel (volledig) werkend te krijgen, zul je vaak (kleine) wijzigingen en/of (kleine) aanvullingen moeten aanbrengen, bijvoorbeeld met JavaScript.
Er is ook geen enkele garantie dat iets werkt in een andere tablet of smartphone dan hierboven genoemd, omdat fabrikanten in principe de software kunnen veranderen. Dit is anders dan op de desktop, waar browsers altijd (vrijwel) hetzelfde werken, zelfs op verschillende besturingssystemen. Iets wat in Android browser werkt, zal in de regel overal werken in die browser, maar een garantie is er niet. De enige garantie is het daadwerkelijk testen op een fysiek apparaat. En aangezien er duizenden mobiele apparaten zijn, is daar eigenlijk geen beginnen aan.
De html is gevalideerd met de validator van w3c, de css ook. Als om een of andere reden niet volledig gevalideerd kon worden, wordt dat bij Bekende problemen (en oplossingen) vermeld.
Nieuwe browsers test ik pas, als ze uit het bèta-stadium zijn, omdat er anders 'n redelijke kans is dat ik 'n bug zit te omzeilen, die voor de uiteindelijke versie nog gerepareerd wordt. Dit voorbeeld is alleen getest in de hierboven met name genoemde browsers. Vragen over niet-geteste browsers kan ik niet beantwoorden, en het melden van fouten in niet-geteste browsers heeft ook geen enkel nut. (Melden van fouten, problemen, enz. in wel geteste browsers: graag!)
Bekende problemen (en oplossingen)
Waarop en hoe is getest, kun je gelijk hierboven vinden bij Getest in.
Als je hieronder geen oplossing vindt voor een probleem dat met dit voorbeeld te maken heeft, kun je op het forum proberen een oplossing te vinden voor je probleem. Om forumspam te voorkomen, moet je je helaas wel registreren, voordat je op het forum een probleem kunt aankaarten.
Alle browsers
Bij gebruik van de Terug-toets van de browser of Alt+←, blijft de pop-up geopend.
Teruggaan vanuit een hulppagina naar het puzzelmenu kan door op de link te klikken. Maar je kunt ook 'n pagina teruggaan door de Terug-toets van de browser of alt+← te gebruiken. Als je op deze manier teruggaat, houdt de link waarmee je de hulppagina hebt bezocht meestal focus.
Normaal genomen wordt focus aangegeven met een kadertje rondom de link die focus heeft. In dit voorbeeld wordt het aangegeven doordat de pop-up en bijbehorende knop zichtbaar zijn. Die zijn dus ook nog steeds geopend, als je teruggaat met gebruik van de Terug-toets of alt+←. Dit is geen fout of zo, het is de normale werking van focus.
Alleen in alle versies van Google Chrome en UC browser op Windows 7 en en iOS verliest de link ook focus, als je met de Terug-toets of alt+← teruggaat.
Opera Mini
Het werkt niet
Tja, dat is vrij simpel: het werkt gewoon niet. Punt.
Het menu, de puzzel, staat maar voor 'n klein deel binnen het venster van de browser, de rest is onzichtbaar. Dit komt door het gebruik van transform
bij het plaatsen van het menu. Opera Mini kent dit niet. Omdat het menu eerst halverwege het venster wordt neergezet met behulp van position
, wat Opera Mini wel kent, blijft het hele menu gewoon daar staan: in beide richtingen halverwege het browservenster.
Je zou dat mogelijk nog wel kunnen oplossen, maar ook aanraken werkt niet. Ook dat kun je mogelijk wel oplossen, maar er zijn grenzen. Bovendien is Opera Mini bedoeld om zo snel mogelijk te surfen, waarbij je zo weinig mogelijk data gebruikt. Mensen die dat doen, zijn niet de mensen die een of ander spelletjesmenu bezoeken. En als ze dat toch doen, moeten ze even 'n browser gebruiken die voor dat soort dingen is bedoeld.
In Opera Mini op Android kun je de Weergave in één kolom inschakelen en dan zie je de pop-ups en links. Maar de links zijn niet als link herkenbaar. Persoonlijk denk ik dat deze manier alleen voor De Gevorderde Masochist Met Zelfhaat geschikt is.
Valideren
In de css wordt pointer-events
gebruikt. (Niet te verwarren met de JavaScript-specificatie Pointer Events.) Deze eigenschap is in css aan komen waaien vanuit de SVG-specificatie en wordt (nog) niet herkend door de validator, wat een foutmelding oplevert.
Omdat de reden van deze fout bekend is, is dat geen probleem.
Internet Explorer 9
Internet Explorer 9 kent linear-gradient
niet en negeert dit. De achtergrond van de knoppen met links is in deze browser geen gradiënt (verlopende kleur), maar effen wit.
Je kunt een gradiënt in Internet Explorer enigszins simuleren met behulp van een gradiënt filter. Dat is een eigen techniek van Microsoft die kan worden gebruikt in oudere versies van Internet Explorer, maar dat vond ik de moeite niet waard.
UC browser en Android browser op Android
Dit speelt alleen in browservensters lager dan 480 px of smaller dan 384 px, de maat van de puzzelafbeelding. In deze kleine vensters wordt div#wrapper
met behulp van transform: scaleX()
verkleind. De in div#wrapper
zittende puzzelafbeelding mag niet buiten div#wrapper
(en dus niet buiten het venster van de browser) komen, maar dat gebeurt door een bug ten onrechte wel. Hierdoor valt aan de onderkant een deel van de afbeelding weg.
Alles werkt wel, want de rest van div#wrapper
is wel goed geschaald en dergelijke, maar de <li>'s corresponderen niet meer met de eronder zittende puzzelvakjes. Ook andere methodes als een extra (maximum)hoogte, het gebruik van de eenheden vw
of vh
, het weghalen van breedte en grootte in de html bij de afbeelding, en dergelijke hebben geen effect: de afbeelding blijft groter dan div#wrapper
.
Een vaste maat in px
opgeven werkt wel, maar dat is geen oplossing, omdat de bedoeling nou juist is dat de afbeelding zich aanpast aan de grootte van het venster van de browser.
Als de smartphone in de portretstand wordt gedraaid, speelt dit probleem niet meer, want dan past de afbeelding binnen het venster en corresponderen <li>'s en puzzelvakjes weer met elkaar. Omdat er in de landschapsstand links en rechts veel lege ruimte is, is het hoe dan ook logischer om het toestel in de portretstand vast te houden, dus 'n echt probleem is dit feitelijk niet.
Wijzigingen
Alleen grotere wijzigingen worden hier vermeld, geen dingen als een link die is geüpdatet.
:
Nieuw opgenomen.
11 augustus 2008:
De nieuwe zoomfunctie van Firefox 3 sloopte dit menu nogal. Door de veranderingen die hiervoor nodig waren bleek het vergroten/verkleinen van letters ook ineens 'n stuk beter te werken. Tja.
Het volgende is veranderd:
-
Hoogte bij
#tekst-krokodil
veranderd vanpx
inem
. -
span#wrapper-krokodil
:background-image
veranderd inbackground
, waardoorno-repeat
erbij kon. Omdat de tekst bij het eerste puzzelstukje (waar de krokodil verschijnt) nu breder en hoger kan worden, zou het achtergrondplaatje worden herhaald, wat hier foeilelijk is. -
Bij het vergroten en verkleinen van de tekst bij de krokodil kwam deze gedeeltelijk over de zwarte achtergrond te staan. En zwarte letters op een zwarte achtergrond, daar word ik 'n zwartgallige zwartkijker van.
De tekst zelf staat in de spans
krok-1
tot en metkrok-9
. Deze spans heb ik voorzien van 'n achtergrond in dezelfde kleur als het wolkje in het plaatje. Als je niet vergroot zie je het dus niet. Als je vergroot, wordt ook deze achtergrond vergroot, en blijven de letters dus leesbaar. -
Bij deze spans stond 'n
padding-left
om de tekst precies goed te zetten. Deze moest worden veranderd in 'nmargin-left
, omdat 'npadding
de kleur van de achtergrond krijgt, en dat is hier niet de bedoeling. -
Ten slotte moest elke span nog 'n breedte in
em
krijgen. Inem
, zodat de breedte mee verandert met de lettergrootte. -
Bij
span.wrapper-nog-niet-af...
hoogte en breedte veranderd vanpx
inem
. -
Bij
span#wrapper-mail a span #tekst-mail
breedte veranderd vanpx
inem
.
31 maart 2009:
Tekst aangepast aan de nieuw verschenen Internet Explorer 8. De code is niet veranderd.
26 juli 2011:
background: black;
toegevoegd bijdiv#alternatief a
vanwege toegankelijkheid.- Hoogte en breedte toegevoegd bij olifant.png.
25 december 2013:
- Alle verwijzingen naar Internet Explorer 6 en 7 zijn verwijderd. De code van dit voorbeeld wordt niet meer aangepast. Daarom is uitleg en dergelijke voor deze twee browsers, die alleen rechtstreeks betrekking heeft op de code, wel blijven staan.
- Op allerlei plaatsen tekst aangepast aan nieuwere inzichten.
- Bij Bekende problemen (en oplossingen) overzicht opgenomen van problemen op touchscreens.
1 augustus 2015:
- Alle aanpassingen voor Internet Explorer 6, 7 en 8 verwijderd. Hier wordt niet meer op getest.
- Testen in Opera vervangen door testen in UC Browser. Opera gebruikt inmiddels dezelfde weergave-machine als Google Chrome en wordt heel weinig gebruikt. Testen in UC Browser leek daarom zinvoller.
- Geschikt gemaakt voor touchscreens.
- De code is volledig gewijzigd, daarom worden daar geen wijzigingen van gegeven: daar is geen beginnen aan. Een van de belangrijkste wijzigingen vermeld ik toch: de pop-ups staan niet meer binnen de bijbehorende link, maar gelijk daarna. Vooral dit maakt het mogelijk deze constructie ook op touchscreens te gebruiken.
- Er is geen apart menu meer voor schermlezers en dergelijke. Door het gebruik van WAI-ARIA-codes is het gewone menu ook bruikbaar voor schermlezers en dergelijke.
- Menu is nu ook toegankelijk voor gebruikers van de Tab-toets.
- Alles omgezet naar html5.
- De tekst is volledig herschreven en er zijn nogal wat hoofdstukken aan toegevoegd.
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.
menu-014-dl.html: de pagina met het menu.
menu-014.pdf: deze uitleg (aangepast aan de inhoud van de download).
menu-014-inhoud-download-en-licenties.txt: een kopie van de tekst onder dit kopje (Inhoud van de download en licenties).
014-css-dl:
menu-014-dl.css: stylesheet voor menu en hulppagina's.
014-files-dl:
menu-missende-letters-dl.zip: niet-gebruikte dansletters (zodat het alfabet compleet is). Deze letters zijn afkomstig van het niet meer bestaande calendarofupdates.com.
menu-014-dansletters-dl.html: hulppagina achter de link bij de dansletters.
menu-014-krokodil-dl.html: hulppagina achter de link bij de krokodil.
menu-014-mail-dl.html: hulppagina achter de link bij de mail.
menu-014-uitgang-dl.html: hulppagina achter de link bij de uitgang.
014-pics:
menu-014-a.gif tot en met, menu-014-c.gif, ..., tot en met menu-014-z.gif: de dansende letters. Deze zijn afkomstig van het niet meer bestaande calendarofupdates.com.
menu-014-ijspret.jpg: afbeelding waaronder het menu zit. De afbeelding komt van karenswhimsy.com/public_domain_images. Het puzzelpatroon is aangebracht met Gimp. De gebruiksvoorwaarden van de afbeelding zijn te vinden op karenswhimsy.com/image-ordering.shtm#terms.
menu-014-krokodil.gif en menu-014-olifant.png: de afbeeldingen met de bewegende krokodil en de (niet-bewegende) olifant. Deze komen van de helaas niet meer bestaande site www.davidpye.com. Het wolkje bij de krokodil is aangebracht met Gimp.
menu-014-mail.gif: de afbeelding van de mailbox komt van de niet meer bestaande site www.hellasmultimedia.com.
menu-014-uitgang.jpg: het plaatje met de uitgang. Ik heb er eerlijk waar geen flauw idee meer van, waar ik dit ooit vandaan heb gehaald. In ieder geval niet van een of ander eng bedrijf met pitbulls en deurwaarders. Maar als je dit dus verder wilt gebruiken, is dat op eigen risico.
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>
<html lang="nl">
Een document moet met een doctype beginnen om weergaveverschillen tussen browsers te voorkomen. Zonder doctype is de kans op verschillende (en soms volkomen verkeerde) weergave tussen verschillende browsers heel erg groot.
Geldige doctypes vind je op www.w3.org/QA/2002/04/valid-dtd-list.
Gebruik het volledige doctype, inclusief de eventuele url, anders werkt het niet goed.
Het hier gebruikte doctype is dat van html5. Dit kan zonder enig probleem worden gebruikt: het werkt zelfs in Internet Explorer 6.
<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, enz., maar dan moet je waarschijnlijk heel erg lang wachten.
Mobiele browsers gokken erop dat een pagina een bepaalde breedte heeft. Safari voor mobiel bijvoorbeeld gaat ervan uit dat een pagina 980 px breed is. De pagina wordt vervolgens zoveel versmald dat hij binnen het venster van het apparaat past. Op een iPhone wordt de pagina dus veel smaller dan op een iPad. Vervolgens kan de gebruiker inzoomen op het deel van de pagina dat hij of zij wil zien.
Dit betekent ook dat bij het openen van de pagina de tekst meestal heel erg klein wordt weergegeven. (Meestal, want niet alle browsers en apparaten doen het op dezelfde manier.) Niet erg fraai, maar bedenk maar 'ns 'n betere oplossing voor bestaande sites.
Nieuwe sites of pagina's kunnen echter wel rekening houden met de veel kleinere vensters van mobiele apparaten. Deze pagina bijvoorbeeld past zich aan de breedte van het venster aan, ook bij heel smalle vensters. Maar die stomme mobiele browser weet dat niet, dus die gaat ervan uit dat ook de al aangepaste pagina 980 px breed is, en verkleint die dan. Dat is ongeveer even behulpzaam als de gedienstige kelner die behulpzaam de stoel naar achteren trekt, net als jij wilt gaan zitten.
Om de door de browser aangeboden hulp vriendelijk maar beslist te weigeren, wordt deze tag gebruikt. Hiermee geef je aan dat de pagina is geoptimaliseerd voor mobiele apparaten.
Een iPad in portretstand bijvoorbeeld is 768 px breed. De kreet width=device-width
zegt tegen de mobiele browser dat de breedte van de weer te geven pagina gelijk is aan de breedte van het apparaat. Voor een iPad in portretstand dus 768 px.
En dat klopt, want de breedte van de weer te geven tekst en dergelijke passen zich automatisch aan de breedte van het apparaat aan. Er is op deze pagina niets, wat problemen kan opleveren in een smaller browservenster.
Simpeler gezegd: je zegt tegen het mobiele apparaat dat de pagina geen vaste breedte heeft, en dat het dus niet nodig is om de weergave aan te passen.
Er staat nog een tweede deel in de tag: initial-scale=1
. Sommige mobiele apparaten zoomen een pagina gelijk in of uit. Ook weer in een poging behulpzaam te zijn. Ook dat is hier niet nodig, want de pagina past zich aan het apparaat aan. Er is ook een instructie om zoomen helemaal onmogelijk te maken, maar die gebruik ik niet. De bezoeker kan zelf nog gewoon zoomen, wat belangrijk is voor mensen die wat slechter zien.
<link rel="stylesheet" href="014-css-dl/menu-014-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.
<div id="wrapper" onclick="">
Het bijzondere van de html is hier onclick=""
. Dat stukje is feitelijk JavaScript en staat alleen voor de volledigheid ook hier vermeld. De reden van deze JavaScript-insluiper is te vinden bij JavaScript.
<h1>Menu met spelletjes</h1>
De reden dat de <h1> hier tot de essentiële code wordt gerekend, heeft te maken met toegankelijkheid voor schermlezers en dergelijke. Het menu staat in een <nav> en is daardoor herkenbaar als menu voor schermlezers en dergelijke. Maar daarmee is nog niet duidelijk, om wat voor menu het gaat. Dat staat in deze <h1> omschreven, die gelijk onder de <nav> staat: 'Menu met spelletjes'.
Met behulp van css wordt de <h1> buiten het venster van de browser geplaatst, zodat hij onzichtbaar is. Maar voor een schermlezer maakt dat niet uit: hij wordt gewoon voorgelezen.
Normaal genomen zal dit waarschijnlijk geen <h1> zijn, maar een <h2> of nog lager, omdat normaal genomen zo'n menu niet het eerste onderdeel van een pagina is. Op de site bijvoorbeeld staat in de <h1> de titel van de pagina en wordt voor het aanduiden van dit menu en het menu van de site zelf een <h2> gebruikt.
<li id="...">
tabindex="-1"
komt bij meerdere tags voor: de <li>'s waarbij al een pop-up en dergelijke is gemaakt. Deze tags verschillen iets van elkaar, maar de uitleg is overal hetzelfde.
Deze negatieve tabindex
is nodig, omdat anders in sommige browsers op een touchscreen de pop-up niet gelijk opent. Meer uitleg over de tabindex is te vinden bij Tabindex.
<li tabindex="0"></li>
tabindex="0"
staat bij elke <li> die nog geen pop-up en dergelijke heeft. Het verhelpt een probleem bij Internet Explorer op touchscreens en UC browser op Windows Phone. Het zorgt er ook voor dat de link wordt bezocht bij gebruik van de Tab-toets. Meer uitleg is te vinden bij bij Tabindex.
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, enz., met commentaar, inspringingen, en dergelijke. Dat is de mensvriendelijke versie. Daarnaast is er dan een stylesheet die je op de echte site gebruikt: een gecomprimeerde versie.
Dat comprimeren kun je met de hand doen, maar er bestaan ook hulpmiddelen voor. Op de pagina met links 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
/* menu-014-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.
/****************** Hulppagina's *****************/
Bij grotere bestanden is het vaak handig een soort 'hoofdstukjes' aan te brengen. Als je zoekt naar meerdere sterretjes, kun je zo van deel naar deel springen, wat vaak nogal wat zoekwerk kan besparen. En kan voorkomen dat je in het verkeerde deel van een bestand gaat zitten werken.
body#hulp
Het element body met id="hulp". Op de vier hulppagina's, die achter de links in het menu zitten, is een kleine hoeveelheid css gebruikt. Die wordt in dit stukje van de stylesheet opgegeven. Als je alleen body
gebruikt, zou deze css ook gelden voor de pagina met het menu. Daarom hebben de hulppagina's bij body
een id="hulp" gekregen. Nu geldt deze css alleen voor de hulppagina's.
background: #ff9;
Achtergrondkleur.
font-size: 150%;
Grotere letter. Als eenheid gebruik ik procenten, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
text-align: center;
Tekst horizontaal centreren.
body#hulp p:not(:first-child)
De <p>'s die niet het eerste kind zijn op de pagina's met body id="hulp".
body#hulp
Het element body met id="hulp". Op de vier hulppagina's, die achter de links in het menu zitten, is een kleine hoeveelheid css gebruikt. Die wordt in dit stukje van de stylesheet opgegeven. Als je alleen body
gebruikt, zou deze css ook gelden voor de pagina met het menu. Daarom hebben de hulppagina's bij body
een id="hulp" gekregen. Nu geldt deze css alleen voor de hulppagina's.
:first-child
: alleen de elementen die een eerste kind zijn. p:first-child
geldt alleen voor bijvoorbeeld:
<div>
<p></p>
</div>
maar niet voor:
<div>
<a></a>
<p></p>
</div>
In het eerste geval is de <p> het eerste kind van de <div>, in het tweede geval is de <a> het eerste kind en de <p> pas het tweede kind.
:not()
: dit keert het deel dat tussen de haakjes staat om.
:not(:first-child)
: alleen de elementen die géén eerste kind zijn.
p:not(:first-child)
: alles bij elkaar betekent dit dus alleen de <p>'s die geen eerste kind zijn.
Dit is een hele grove selector, maar omdat de hulppagina's heel simpel zijn, kan die hier worden toegepast.
font-size: 80%;
Lettergrootte iets kleiner maken. Iets hierboven is de lettergrootte bij body#hulp
op 150% gezet. Hiermee beperk ik dat tot de eerste <p>. Als eenheid gebruik ik procenten, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
De lettergrootte wordt geërfd door de nakomelingen. De <p>'s erven dus in eerste instantie de lettergrootte van 150% van de body. De 80% wordt van die 150% genomen, dus de uiteindelijke lettergrootte wordt 80% van 150%. Dat is 120% van de normale lettergrootte, nog steeds iets groter dan normaal.
body#hulp a
De <a>'s op de pagina's met een body met id="hulp". Dit zijn de links van de hulppagina's terug naar het voorbeeld.
position: static;
Iets verderop bij a worden de links in het voorbeeld opgeleukt tot een heuse knop. Dat is eigenlijk bedoeld voor de puzzel, maar kan op de hulppagina's verder ook geen kwaad. Wat wel kwaad kan: de links worden verderop links buiten het scherm geparkeerd met left: -20000px;
. Waarmee ze dus onzichtbaar zijn. Dat is prima in die puzzel, maar hier niet.
left: -20000px;
werkt alleen maar, als het element absoluut, relatief of fixed is gepositioneerd. Verderop worden de <a>'s inderdaad absoluut gepositioneerd. Door de <a>'s op de hulppagina's statisch te positioneren, de standaardinstelling, werkt left: -20000px;
niet meer op deze links en komen ze gewoon op het scherm te staan.
De css voor alle <a>'s staat verderop. Latere css overrulet normaal genomen eerdere css. Maar hier niet, omdat door het gebruik van body#hulp
de selector hier meer gewicht, meer specificiteit, heeft dan de lager staande selector, die alleen uit a
bestaat. Zou je ook hier alleen a
gebruiken, dan zou dit niet werken, omdat dan de lager staande css deze zou overrulen en ook deze <a>'s absoluut gepositioneerd zouden worden. En dus ook links buiten het scherm geparkeerd zouden worden.
/***************** Puzzel ************************/
Bij grotere bestanden is het vaak handig een soort 'hoofdstukjes' aan te brengen. Als je zoekt naar meerdere sterretjes, kun je zo van deel naar deel springen, wat vaak nogal wat zoekwerk kan besparen. En kan voorkomen dat je in het verkeerde deel van een bestand gaat zitten werken.
html
Het element <html>. Dat is het allerbuitenste element.
height: 100%;
Het menu moet horizontaal en verticaal worden gecentreerd binnen het browservenster. Horizontaal is dat vrij simpel, verticaal is het iets lastiger.
Om het menu verticaal te kunnen centreren, moet de hoogte van het venster bekend zijn. Als je immers niet weet, hoe hoog iets is, kun je iets anders niet in het midden van die onbekende hoogte zetten.
Browservensters kunnen allerlei hoogtes hebben, van smartphones tot enorme monitors. Gelukkig hoef je niet de exacte hoogte te weten om te kunnen centreren. Centreren kan ook prima met percentages. Als je een site maakt, weet je de hoogte van het venster niet. Maar de browser weet dit, bij het daadwerkelijk weergeven van de site, wel. De browser kan daardoor de opgegeven percentages bij het vertonen omrekenen naar 'echte', absolute afstanden.
Als je niets speciaals zou doen, zou het menu gewoon linksboven in de hoek van het browservenster worden neergezet, de standaardpositie. Dat is niet de bedoeling: het moet in het midden van het venster komen te staan.
<html> heeft van zichzelf geen hoogte. Het krijgt automatisch de hoogte die nodig is om de inhoud erin weer te kunnen geven. In dit geval is dat het menu. Door <html> een hoogte van 100% te geven, krijgt <html> altijd de hoogte van het browservenster, hoe hoog dit ook is. Dat geeft de mogelijkheid om later het menu halverwege die hoogte van 100%, dus halverwege het venster, te zetten. En als je het menu dan weer de helft van de hoogte van het menu terug omhoog verplaatst, staat het in het midden van het venster, hoe hoog dit ook is.
Voor de breedte is dit allemaal niet nodig, omdat een blok-element zoals <html> standaard de volle breedte van de ouder, hier het browservenster, vult.
Als het je nu duizelt, wordt het mogelijk duidelijker bij het daadwerkelijk centreren van het menu bij nav.
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: black;
Zwarte achtergrondkleur.
height: 100%;
Als een hoogte in procenten wordt opgegeven, is dat altijd ten opzichte van de hoogte van de ouder van het element. Die ouder is hier <html>. Gelijk hierboven is voor <html> een hoogte van 100% opgegeven, even hoog als het venster van de browser, hoe hoog dat venster ook is. <body> is dus ook altijd even hoog als het venster van de browser.
font-family: Arial, Helvetica, sans-serif;
Lettersoort. Als er geen Arial is, wordt gezocht naar Helvetica. Als dat er ook niet is in ieder geval 'n lettersoort zonder schreef (dwarsstreepjes).
margin: 0; padding: 0;
Verschillende browsers hebben verschillende standaard-instellingen hiervoor. Door ze gewoon op 0 te zetten, zijn ze overal hetzelfde.
#wrapper
Het element met id="wrapper". Dit is de div, waar de hele handel in staat.
Mogelijk is dit element niet absoluut noodzakelijk en zou je met allerlei aanpassingen deze <div> kunnen 'overslaan'. Maar dat maakt de code een stuk ingewikkelder. En vanwege mijn aangeboren ongeneeslijke luiheid gebruik ik dus gewoon deze <div>, waar een aantal <div>-puristen ongetwijfeld van zal gruwen.
height: 100%;
Als een hoogte in procenten wordt opgegeven, is dat altijd ten opzichte van de hoogte van de ouder van het element. Die ouder is hier <body>. Gelijk hierboven is voor <body> een hoogte van 100% opgegeven. Ook bij <body> geldt die 100% weer ten opzichte van de ouder, en die ouder is bij <body> het element <html>. Ook <html> heeft een hoogte van 100% gekregen, waardoor <html> altijd even hoog is als het venster van de browser, ongeacht hoe hoog dit is. En uiteindelijk is dus ook kleinkind div#wrapper
altijd even hoog als het venster van de browser.
max-height: 100%;
De combinatie height: 100%;
(gelijk hierboven) en overflow: hidden;
(gelijk hieronder) zou er eigenlijk voor moeten zorgen, dat geen verticale scrollbalk verschijnt. Maar in Internet Explorer 9 en 10 en in de bureaublad-versie van Internet Explorer 11 gebeurt dat toch.
Door toe te voegen dat de hoogte nooit meer dan die 100% mag zijn, verschijnt ook in die browsers geen verticale scrollbalk.
overflow: hidden;
Standaard staat overflow
op visible
: ook als tekst en dergelijke niet binnen het element past, wordt dit toch weergegeven. Normaal genomen is dat ook wat je wilt. De lay-out wordt misschien wat verstoord, maar alle tekst en dergelijke is in ieder geval zichtbaar.
In dit geval wil ik echter dat alles dat niet in #wrapper
past niet wordt weergegeven, want wat niet past, wordt later op andere manieren afgehandeld.
position: relative;
Om nakomelingen te kunnen positioneren ten opzichte van een element, moet dit element zelf een positie hebben. Daarom wordt hier een relatieve positie opgegeven. Omdat verder geen waarden worden opgeven voor top
en dergelijke, heeft dit verder geen enkele invloed op div#wrapper
zelf.
h1
Alle <h1>'s. Dat is er hier maar één, de <h1> met de titel van het menu.
Normaal genomen zou hier waarschijnlijk gen <h1>, maar een <h2> of <h3> of zo staan. Maar in dit geval is dit de enige <h> op de pagina, dus wordt het een <h1>.
position: absolute;
Om de <h1> op de juiste plaats neer te kunnen zetten.
Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Dat is hier <nav>.
left: -20000px;
De <h1> wordt links buiten het scherm geparkeerd. Nu is hij onzichtbaar, maar schermlezers en dergelijke zien hem wel gewoon staan. Hierdoor kan een schermlezer voorlezen, waarvoor dit menu is bedoeld, zonder dat de lay-out wordt verstoord.
/********** Algemene css pop-ups en dergelijke ****************/
Bij grotere bestanden is het vaak handig een soort 'hoofdstukjes' aan te brengen. Als je zoekt naar meerdere sterretjes, kun je zo van deel naar deel springen, wat vaak nogal wat zoekwerk kan besparen. En kan voorkomen dat je in het verkeerde deel van een bestand gaat zitten werken.
ul
Alle <ul>'s. Dat is er hier maar eentje: de ongeordende lijst waar het hele menu in staat.
In het algemeen is het handig een menu in een <ul> te zetten. Dat is meestal het makkelijkst te lay-outen. En schermlezers geven aan het begin het aantal <li>'s aan, waardoor ook het aantal links gelijk bekend is.
list-style-type: none;
De bolletjes en dergelijke die je automatisch ziet bij een <ul>, zijn hier niet welkom.
margin: 0; padding: 0;
De standaardwaarden hiervan verschillen bij verschillende browsers. Door ze op 0 te zetten, zijn ze overal hetzelfde.
li
Alle <li>'s. Hier zijn dat alleen de <li>'s die bij het menu onder de puzzel horen.
background: rgba(0, 0, 0, 0);
Meestal 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, enz. Daarbij is A gelijk aan het tientallige 10, B aan 11, enz. 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 0 is opgegeven, levert dit een zwarte 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 volkomen doorzichtig: 0.
Sommige mensen zullen zeggen: ik heb het altijd al geweten, maar het is hem nu eindelijk voor iedereen zichtbaar in de bol geslagen. Eerst alle <li>'s een zwarte achtergrondkleur geven en deze dan volledig doorzichtig maken. Dat lijkt even nuttig als een re-integratieproject voor een werkloze: je maakt iemand z'n leven zwart en het resultaat is onzichtbaar.
Ik wil geen spelbederver zijn, maar helaas, het is niet mij, maar Microsoft in de bol geslagen. In Internet Explorer 9 en 10 werkt hoveren niet, als er geen achtergrondkleur (of een doorzichtige afbeelding, dat werkt ook) aanwezig is. Bij Internet Explorer 11 is het Microsoft kennelijk weer uit de bol geslagen, want daar werkt hoveren prima, ook zonder achtergrond. Blijft toch een fascinerend fenomeen, bolbliksems.
Vandaar deze onzichtbare achtergrondkleur. Hoewel je de kleur niet ziet, werkt het toch.
width: 33.3%; height: 25%;
Een breedte in procenten geldt altijd ten opzichte van de ouder van het element. Dat is hier de <ul>, waarbinnen de <li>'s zitten.
Een <ul> is een blok-element, waardoor het normaal genomen automatisch even breed wordt als de ouder. De ouder van <ul> is <nav>. Deze 33,3% geldt dus ten opzichte van <nav>, en dus ook ten opzichte van de daarin zittende puzzel-afbeelding.
En dat komt goed uit. Er zitten drie puzzelstukjes naast elkaar. 33,3% is een derde, dus er passen ook drie <li>'s naast elkaar. Oftewel: precies één <li> voor elk puzzelstukje.
Voor de hoogte geldt exact hetzelfde verhaal, maar dan met vier onder elkaar.
position: absolute;
Om de <li>'s op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die een positie heeft. Dat is hier <nav>. Dat komt goed uit, want binnen <nav> zit ook de afbeelding van de puzzel. Dus als je positioneert ten opzichte van <nav>, positioneer je in feite ook ten opzichte van de puzzel.
Een <li> is van zichzelf een inline-element. Door het absoluut te positioneren verandert het in 'n soort blok-element. Hierdoor zijn ook eigenschappen als breedte en hoogte te gebruiken.
top: 0;
Helemaal bovenin <nav> zetten.
Normaal genomen worden elementen in de volgorde van de html op het scherm gezet. In dit geval zou dat betekenen dat de <ul> met de daarin zittende <li>'s ónder de puzzelafbeelding zou komen te staan. Maar de <li>'s moeten niet onder, maar boven de puzzel komen te staan. Daarom worden ze, net als de afbeelding, helemaal bovenin de <nav> gezet.
Nu staan álle <li>'s, alle twaalf, bovenaan. De tweede, derde en vierde rij met <li>'s moeten lager komen te staan, boven de bijbehorende puzzelstukjes. Dat wordt iets verderop geregeld. Door hier top: 0;
te geven spaar ik een aparte regel voor de bovenste drie <li>'s uit.
li:nth-of-type(3n + 2)
Voor deze elementen geldt ook de eerder bij li opgegeven css, voor zover die hier niet wordt gewijzigd.
Dit is minder ingewikkeld, dan het mogelijk lijkt. Hoewel, dat zeggen ze altijd. En het is ook wel waar, maar altijd pas achteraf, als je het al begrijpt. Over naar het begrijpen dan maar.
li
: da's simpel: gewoon alle <li>'s.
nth-of-type
: een zogenaamde pseudo-class. nth
wil zeggen 'de zoveelste', of-type
betekent 'van de soort'. Aangezien dit achter een <li> staat, gaat het hier dus om één (of meer) <li>'s.
(3n + 2)
: tussen de haakjes staat aangegeven, om welke <li> of <li>'s het gaat.
De getallen '3' en '2' zijn gewoon getallen, daar is verder weinig geheimzinnigs aan.
De 'n' is een soort teller, die steeds met 1 wordt verhoogd. Bij de eerste keer is de 'n' 0, bij de tweede keer 0 + 1 = 1, bij de derde keer 1 + 1 = 2, enz.
3n
betekent, net als in de wiskunde, 3 x de waarde van 'n'. De eerste keer is dat dus 3 x 0 = 0, de tweede keer 3 x 1 = 3, de derde keer 3 x 2 = 6, enz. Deze berekening levert een reeks getallen op, beginnend met 0, die steeds 3 hoger worden: 0, 3, 6, 9, 12, ...
Omdat er twaalf <li>'s zijn, wordt de berekening 12 keer gemaakt. De twaalfde en laatste berekening is 3 x 11 = 33. Maar alleen de uitkomsten tot en met 12 hebben nut, omdat er maar 12 <li>'s zijn.
(De laatste waarde van 'n' is geen 12 maar 11, omdat met 0 wordt begonnen. Voor mensen lastig, maar computers beginnen heel vaak te tellen met 0.)
De eerste keer is het resultaat 3 x 0 = 0. Daarachter staat nog + 2. De eerste keer is de volledige berekening dus 3 x 0 + 2 = 2. Oftewel: de tweede <li>.
De tweede keer is het resultaat 3 x 1 = 3. Daarachter staat nog + 2. De tweede keer is de volledige berekening dus 3 x 1 + 2 = 5. Oftewel: de vijfde <li>.
De derde keer is het resultaat 3 x 2 = 6. Daarachter staat nog + 2. De derde keer is de volledige berekening dus 3 x 2 + 2 = 8. Oftewel: de achtste <li>.
Enz.
In dit geval gaat het dus om de tweede, vijfde, achtste en elfde <li>. En als dat nou niet toevallig is: dat zijn precies de <li>'s die in de tweede kolom met puzzelstukjes moeten komen te staan! Komt dat even goed uit, nu kan ik die in één keer aanspreken.
(Als je 8000 <li>'s zou hebben, zou je met deze ene regel alle 8000 <li>'s op precies dezelfde manier kunnen afhandelen en alleen de tweede, vijfde, achtste, elfde, veertiende, enz. <li> kunnen aanspreken. Er zijn met behulp van deze en soortgelijke pseudo-classes nog veel ingewikkelder en handiger selectors mogelijk, waarvan een klein aantal hieronder wordt gebruikt.)
left: 33.3%;
Bij li iets hierboven zijn de <li>'s absoluut gepositioneerd. Dat heeft een nadeel: ze worden niet netjes achter of onder elkaar gezet, maar allemaal over elkaar heen. Allemaal in de linkerbovenhoek van de <nav> en daarmee ook in de linkerbovenhoek van de in de <nav> zittende puzzel-afbeelding.
Zoals gelijk hierboven uitgelegd, bestrijkt deze selector de tweede, vijfde, achtste en elfde <li>. De <li>'s die in de tweede kolom moeten komen. Elke <li> is 33,3 % breed. Als ik de <li>'s uit deze kolom dus op 33,3% vanaf links neerzet, komen ze precies achter de <li>'s uit de tweede kolom te staan.
li:nth-of-type(3n + 3)
Voor deze elementen geldt ook de eerder bij li opgegeven css, voor zover die hier niet wordt gewijzigd.
Deze selector is exact hetzelfde als die gelijk hierboven, alleen wordt er nu 3 en geen 2 bij de 3n opgeteld. Waardoor hiermee de derde, zesde, negende en twaalfde <li> worden aangesproken. Precies de <li>'s die in de derde kolom moeten komen te staan.
left: 66.6%;
Ook hier is het verhaal precies hetzelfde als gelijk hierboven, alleen moeten deze <li>'s op 66,6% vanaf links worden neergezet, omdat het om de derde kolom gaat.
li:nth-of-type(n + 4):nth-of-type(-n + 6)
Voor deze elementen geldt ook de eerder bij li opgegeven css, voor zover die hier niet wordt gewijzigd.
De ellendepukkel die mij vroeger wiskunde gaf, was een gepatenteerde kloothommel die kinderen háátte. Los daarvan had hij de irritante eigenschap om, als je eindelijk iets begreep of deed alsof je het begreep, onmiddellijk met iets nieuws te komen dat weer net iets lastiger was.
Uit pure frustratie vanwege deze uiterst traumatische onverwerkte ervaring ga ik hier hetzelfde doen. Ik maak het iets moeilijker.
Achter de <li> van deze selector staan twee pseudo-classes: nth-of-type(n + 4)
en nth-of-type(-n + 6)
. Dat betekent alleen maar dat de <li> aan beide pseudo-classes moet voldoen. Je kunt ze dus apart bekijken, waarmee het opeens een stuk beter te behappen is.
li
: alle <li>'s.
nth-of-type(n + 4)
: vrijwel hetzelfde als iets hierboven bij li:nth-of-type(3n + 2).
De 'n' is weer een teller die met 0 begint en steeds 1 hoger wordt. De eerste keer staat er dus 0 + 4 = 4, de tweede keer 1 + 4 = 5, de derde keer 2 + 4 = 6, enz. Dit levert de getallen 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 en 15 op. Alleen de uitkomsten 12 en lager hebben nut, want er zijn maar twaalf <li>'s.
De eerste pseudo-class stelt dus als voorwaarde dat het de vierde, vijfde, enz. tot en met de twaalfde <li> is.
nth-of-type(-n + 6)
: ook deze selector is weinig anders dan de eerdere, maar met een minteken voor de 'n'. De 'n' is weer een teller die met 0 begint en steeds 1 hoger wordt. Alleen is het hier iets lastiger vanwege het minteken.
Bij de eerdere pseudo-class bij li:nth-of-type(3n + 2) stond 3n: voor de 'n' staat het getal 3. Wat je uit moet leggen als 3 x n.
Bij deze selector staat geen getal voor de 'n', alleen een minteken. Als er geen getal voor de 'n' staat, staat er eigenlijk toch 'n getal: de 1. Maar dat wordt weggelaten, omdat '1n' moet worden gelezen als '1 x n', en dan is de 1 een beetje overbodig.
Hier staat echter een minteken voor de 'n', en dan kan het helpen om de 1 er wel even bij te denken: -1n: Wat je dus moet lezen als -1 x n.
Bij de eerste ronde is 'n' 0. De berekening wordt dan -1 x 0 = 0.
Bij de tweede ronde is 'n' 1. De berekening wordt dan -1 x 1 = -1.
Bij de derde ronde is 'n' 2. De berekening wordt dan -1 x 2 = -2.
Enz., de uitkomst is steeds 1 lager. Hoewel 'n' steeds 1 meer wordt, wordt de uitkomst door het minteken steeds 1 lager.
Bij de twaalfde en laatste ronde is 'n'11 en is de berekening -1 x 11 = -11.
(Omdat de 'n' met 0 begint te tellen, is de 'n' bij de twaalfde berekening 11 en geen 12.)
Bij deze uitkomst moet 6 worden opgeteld, want er staat -n + 6
tussen de haakjes.
Bij de eerste ronde staat er -1 x 0 + 6 = 6.
Bij de tweede ronde staat er -1 x 1 + 6 = -1 + 6 = 5.
Bij de derde ronde staat er -1 x 2 + 6 = -2 + 6 = 4.
Bij de twaalfde ronde staat er -1 x 11 + 6 = -11 + 6 = -5.
De uitkomst is de serie getallen 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5.
Oftewel: het gaat om de zesde, vijfde, vierde, derde, tweede en eerste <li>. De nulde en lagere <li>'s vervallen, want er bestaan geen nulde of lagere <li>'s.
:nth-of-type(n + 4):nth-of-type(-n + 6)
: beide pseudo-classes achter elkaar.
De <li>'s moeten binnen beide pseudo-classes vallen.
De eerste pseudo-class levert de vierde tot en met de twaalfde <li> op.
De tweede pseudo-class levert de eerste tot en met de zesde <li> op.
Alleen de vierde, vijfde en zesde <li> zitten binnen beide pseudo-classes, dus de css van deze selector geldt alleen voor de vierde, vijfde en zesde <li>. En dat zijn, niet geheel toevallig, de <li>'s die boven de tweede rij puzzelstukjes moeten komen te staan.
top: 25%;
Op 25% vanaf de bovenkant van de <nav> neerzetten. Omdat de <li>'s 25% hoog zijn, komt deze rij <li>'s precies onder de bovenste rij <li>'s te staan.
li:nth-of-type(n + 7):nth-of-type(-n + 9)
Voor deze elementen geldt ook de eerder bij li opgegeven css, voor zover die hier niet wordt gewijzigd.
Los van de getallen is deze selector precies hetzelfde als die hierboven bij li:nth-of-type(n + 4):nth-of-type(-n + 6).
nth-of-type(n + 7)
: de eerste pseudo-class levert hier de getallen 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 op. Er zijn maar 12 <li>'s, dus alleen de getallen 7 tot en met 12 zijn interessant.
nth-of-type(-n + 9)
: de tweede pseudo-class levert hier de getallen 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2 op. Alleen de getallen 1 tot en met 9 zijn interessant, want een nulde of lagere <li> is onzin.
Ook hier komen alleen de <li>'s in aanmerking, die binnen beide pseudo-classes vallen. Dat zijn alleen de zevende, achtste en negende <li>. En komt dat even goed uit: dat zijn precies de drie <li>'s die in de derde rij zitten!
top: 50%;
Op 50% vanaf de bovenkant van de <nav> neerzetten. Omdat de <li>'s 25% hoog zijn, komt deze rij <li>'s precies onder de bovenste twee rijen <li>'s te staan en vormt hiermee de derde rij.
li:nth-of-type(n + 10):nth-of-type(-n + 12)
Voor deze elementen geldt ook de eerder bij li opgegeven css, voor zover die hier niet wordt gewijzigd.
Los van de getallen is deze selector precies hetzelfde als die iets hierboven bij li:nth-of-type(n + 4):nth-of-type(-n + 6).
nth-of-type(n + 10)
: de eerste pseudo-class levert hier de getallen 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 op. Er zijn maar 12 <li>'s, dus alleen de getallen 10 tot en met 12 zijn interessant.
nth-of-type(-n + 12)
: de tweede pseudo-class levert hier de getallen 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 op.
Ook hier komen alleen de <li>'s in aanmerking, die binnen beide pseudo-classes vallen. Dat zijn alleen de tiende, elfde en twaalfde <li>. Wat precies de drie <li>'s zijn die in de vierde en onderste rij zitten.
top: 75%;
Op 75% vanaf de bovenkant van de <nav> neerzetten. Omdat de <li>'s 25% hoog zijn, komt deze rij <li>'s precies onder de bovenste drie rijen <li>'s te staan en vormt hiermee de vierde en onderste rij.
li > span
Alle <span>'s die een direct kind van een <li> zijn. Binnen deze <span>'s zitten de pop-ups.
Het teken >
geeft aan dat het om directe kinderen moet gaan:
<li>
<span></span>
</li>
In onderstaande code is de buitenste <span> een direct kind, waarvoor deze selector dus geldt. De binnenste <span> is geen direct kind van de <li>, maar van de buitenste <span>, dus daarvoor geldt deze selector niet:
<li>
<span>
<span></span>
</span>
</li>
Het gebruik van de >
geeft de mogelijkheid css op te geven die alleen de <span>'s bestrijkt, waarbinnen de volledige pop-up staat. Op die manier kun je bijvoorbeeld het tonen en verbergen van de pop-up regelen door slechts één <span> aan te passen, zonder dat dit dieper geneste <span>'s beïnvloedt.
display: none;
Verbergen. Hiermee wordt ook alles binnen de <span> en daarmee de hele pop-up verborgen. Alleen de knop met de link zit niet binnen de <span>, het verbergen daarvan wordt gelijk hieronder bij a
geregeld.
position: absolute;
Om de <span> op de juiste plaats te kunnen zetten.
Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft, Dat is hier de <li>, waar de <span> een direct kind van is.
a
Alle <a>'s. Omdat in dit geval alle <a>'s binnen het puzzelmenu zitten, kan deze simpele selector worden gebruikt.
Met behulp van css wordt het uiterlijk van de link veranderd in 'n soort knop.
background: white;
Witte achtergrond.
Hier gelijk onder wordt nog een background
opgegeven, maar dan met een gradiënt, een verlopende kleur. Omdat de gradiënt onder de hier opgegeven witte achtergrond staat, 'wint' de gradiënt van deze witte achtergrond. Dus feitelijk zou je deze witte achtergrond kunnen weglaten, omdat die toch wordt overrulet.
Deze regel staat er alleen maar voor Internet Explorer 9. Die browser kent het hieronder gebruikte linear-gradient
niet, en negeert daarom de regel hieronder. Waardoor de <a> helemaal geen achtergrond zou krijgen in Internet Explorer 9. Door hier een gewone witte achtergrond op te geven, heeft ook in Internet Explorer 9 de <a> in ieder geval een achtergrondkleur.
background: -webkit-linear-gradient(top, #fff 0%, #bbb 100%); background: linear-gradient(to bottom, #fff 0%, #bbb 100%);
Hier staat in feite twee keer hetzelfde: linear-gradient(to bottom, #fff 0%, #bbb 100%);
Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-. Hieronder wordt alleen de tweede vorm uitgelegd, want dat is de vorm volgens de uiteindelijke standaard.
Internet Explorer 9 kent linear-gradient
niet en negeert deze regel daarom, zoals gelijk hierboven bij de eerste background
beschreven.
Je kunt een gradiënt zelf uitvogelen, maar vaak is het makkelijker om gebruik te maken van een gradiënt-editor, zoals die op colorzilla.com. Deze levert ook gelijk de oudere vormen van de code, zodat je je daar zelf niet in hoeft te verdiepen. Je kunt zelfs code voor oudere versies van Internet Explorer laten maken. (Nachtmerrie-code die gebruik maakt van een eigen techniek van Microsoft: filters.)
(Overigens is het wel raadzaam die code op te schonen, omdat er wel heel erg veel code voor heel erg oude versies van verschillende browsers in staat.)
In dit geval heb ik geen gradiënt-editor gebruikt, omdat het hier allemaal mooie ronde getallen en codes zijn.
linear-gradient
valt in een aantal delen uiteen:
to bottom
: de kant waar de gradiënt naartoe gaat. Omdat alleen de onderkant is opgegeven, loopt de gradiënt loodrecht van boven naar onder.
Na de richting staan twee keer twee waarden, gescheiden door een komma. De eerste waarde is steeds de kleur, de tweede de plaats waar die kleur staat.
#fff
0%: de kleur #fff
(wit) op 0% vanaf de bovenkant neerzetten (dat is helemaal bovenaan).
#bbb 100%
: de kleur #bbb
(lichtgrijs) op 100% vanaf de bovenkant neerzetten (dat is helemaal onderaan).
Er zijn slechts twee plaatsen opgegeven die een bepaalde kleur moeten krijgen: boven- en onderaan. De overgang tussen die kleuren verloopt geleidelijk, dat regelt de browser verder. Dit is een vrij simpele gradiënt, maar je kunt ook tig kleuren op tig plaatsen aangeven. En ook nog in allerlei richtingen.
color: black;
Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.
Normaal genomen is de kleur van de tekst in een link blauw, of rood of zo als de link is bezocht. Dat vind ik hier niet mooi: de tekst moet gewoon zwart zijn.
box-shadow: 4px 6px 4px 1px;
Schaduw aan de knop geven.
Met behulp van box-shadow
kan schaduw worden gegeven aan een element. Er is geen kleur opgegeven, wat betekent dat de voorgrondkleur wordt gebruikt, hier zwart.
De schaduw is, als je verder niets opgeeft, precies even groot als het element waar de schaduw bij hoort. Dat schiet niet echt op, want dat betekent dat de schaduw precies onder het element staat en dus onzichtbaar is. Daarom wordt de schaduw met behulp van de vier getallen aangepast. De getallen die hier worden gebruikt, leveren de schaduw op, zoals die hierboven bij de afbeelding is te zien. Hieronder heb ik de waarden iets veranderd, zodat het effect van de verschillende waarden duidelijker is te zien.
4px: het eerste getal, hier 4px, geeft de verplaatsing in horizontale richting aan: 4 px naar rechts. Als dit getal 0 zou zijn, zou de linkerkant van de schaduw gelijkvallen met de linkerkant van de <a>, nu is de schaduw 4 px naar rechts verschoven. Als je hier een negatief getal invult, verschuift de linkerkant van de schaduw naar links. Om bijstaande afbeelding te krijgen, zijn de waarden 30px 0 0 0 gebruikt: alleen een horizontale verschuiving van 30 px.
6px: voor het tweede getal geldt precies hetzelfde, maar dan in verticale richting. De bovenkant van de schaduw wordt 6 px naar beneden verplaatst. Om bijstaande afbeelding te krijgen, zijn de waarden 0 30px 0 0 gebruikt: alleen een verticale verschuiving van 30 px.
4px: het derde getal geeft de breedte van de vervaging aan. De schaduw vervaagt hier over een afstand van 4 px. Om bijstaande afbeelding te krijgen, zijn de waarden 0 0 30px 0 gebruikt: de schaduw vervaagt over een afstand van 30 px. Negatieve getallen zijn hier niet toegestaan. De vervaging is wat moeilijk te zien, maar dat is nou juist ook het kenmerk van een vervaging.
1 px: het laatste getal ten slotte geeft de breedte van de schaduw aan: die is hier maar 1 px. Op bijstaande afbeelding zijn de waarden 0 0 0 30px gebruikt: de schaduw is 30 px groter dan het element waar hij bijhoort. Omdat verder geen waarden zijn opgegeven, staat de schaduw aan alle kanten 30 px buiten het element. Bij negatieve waarden wordt de schaduw kleiner dan het element. Dat is alleen maar zinvol als je de schaduw ook verplaatst, want anders verstop je de schaduw alleen maar.
Meestal moet je even wat experimenteren, voordat je de juiste waarden hebt. Vooral de laatste waarden, die voor het vervagen en voor de breedte van de schaduw, beïnvloeden elkaar nogal.
text-decoration: none;
Normaal genomen wordt de tekst in een link onderstreept. Dat wil ik hier niet.
border: black solid 1px;
Zwart randje.
border-radius: 10em / 6em;
De naam van deze eigenschap is wat slecht gekozen, want er worden niet alleen borders afgerond, maar ook dingen als achtergronden.
Je kunt voor alle vier de hoeken andere waarden opgeven. En voor elke hoek kun je dan ook nog een andere waarde voor de horizontale en de verticale richting opgeven.
De horizontale en verticale waarde wordt gescheiden door een schuine streep. Voor de streep staat de horizontale waarde, achter de streep de verticale. Als er maar één waarde is opgegeven, geldt die voor horizontaal en verticaal. (Als een element bijvoorbeeld 50 px hoog en breed is en je geeft alleen 25 px op, kun je op deze manier dus een volmaakte cirkel maken.)
Hier is de waarde in horizontale richting 10 em, in verticale richting 6 em. Omdat er maar één waarde per richting staat, geldt die voor alle vier de hoeken. In horizontale richting is de ronding haast twee keer zo lang als in verticale richting, wat een ovaal oplevert.
padding: 8px 18px;
Afstand tussen tekst en rand van de <a>. Omdat voor onder en links geen waarden zijn opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 8px 18px 8px 18px
in de volgorde boven – rechts – onder – links. Boven en onder 8 px padding, links en rechts 18px.
Dit is tamelijk veel padding. Dat heeft te maken met de hierboven opgegeven border-radius. Omdat de buitenkant van de <a> naar binnen afbuigt, is er meer padding nodig dan normaal. Bij een meer gebruikelijke padding van 3 px aan alle kanten, komt de tekst veel te dicht of zelfs buiten de knop te staan, zoals is te zien op de afbeelding.
position: absolute;
Om de knop op de juiste plaats neer te kunnen zetten.
Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Dat is hier de <li>, waarbinnen de <a> zit.
left: -20000px;
De hele handel links buiten het scherm parkeren, zodat de knop onzichtbaar is. Als de knop zichtbaar moet worden, hoeft deze alleen maar binnen het scherm te worden gezet.
Er wordt geen gebruik gemaakt van display: none;
, omdat schermlezers en dergelijke dan de <a> volledig negeren en de link dus niet wordt voorgelezen. Nu is de link gewoon aanwezig, alleen staat deze links buiten het scherm. Maar dat maakt voor schermlezers en dergelijke niets uit.
z-index: 10;
In de html staat de <a> voor de <span>, waarin de pop-up zit. Normaal genomen komt de <span> daardoor boven de link te staan, waardoor je deze niet meer ziet. Door de <a> een hogere z-index te geven, komt deze toch boven de <span> met de pop-up te staan, ook al staat deze lager in de html.
Een z-index werkt alleen als het element is gepositioneerd. Dat is hierboven geregeld met position: absolute;
.
Dit is de laagste z-index die wordt gebruikt, dus je zou ook 1 kunnen gebruiken. Door een hoger getal te nemen, is het mogelijk om later eventueel een lagere z-index tussen te voegen, zonder dat je deze waarde hoeft te veranderen. Hier is het niet zo belangrijk, maar het is een goede gewoonte om je aan te leren. Ooit heb ik 'n paar honderd z-indexen aangebracht, netjes op volgorde, en toen moest er helemaal aan het begin eentje worden tussengevoegd...
li:empty:not(:focus):hover::after, li:empty:focus::after
Deze regel is voor de <li>'s, die nog niet in gebruik zijn. Als alle <li>'s zouden worden gebruikt, is de regel overbodig.
Dit zijn twee selectors, eentje voor en eentje na de komma. Een deel van beide selectors is hetzelfde.
Beide selectors:
li:empty
: alle lege <li>'s. Beide selectors beginnen hiermee. Een element is leeg, als het geen ander element of tekst bevat. Er mag zelfs geen spatie in zitten. Dit geldt voor de <li>'s die nog niet in gebruik zijn:
<li tabindex="0"></li>
Er staat helemaal niets tussen de openings- en de sluittag. tabindex="0"
telt niet mee, want dat staat bínnen de openingstag.
::after
: hier eindigen beide selectors mee. Met behulp van ::after
wordt bij de <li> een pseudo-element gemaakt. Hierin kan met behulp van het hieronder gebruikte content
tekst worden gezet.
De eerste selector:
:not(:focus)
: :focus
is simpel: als het element focus heeft. (Meer over wat focus is bij :focus.) Maar hiervoor staat :not()
. Daarmee wordt het juist omgekeerd: als het element géén focus heeft. Deze selector geldt dus alleen, als het element, hier de <li>, geen focus heeft.
:hover
: bij hoveren over het element.
:not(:focus):hover
: samen betekent dit: bij hoveren over het element, over de <li>, maar alleen als de <li> geen focus heeft.
li:empty:not(:focus):hover::after
: alles samen. Maak een pseudo‑element (::after
) bij hoveren (:hover
) over een <li>, maar alleen als die <li> leeg (:empty
) is en als die <li> geen focus (:not(:focus)
) heeft.
Dat hier een hele serie pseudo-elementen en pseudo-classes achter elkaar staat, is geen enkel probleem.
De :not(:focus)
is nodig voor Internet Explorer 9 en 11, vreemd genoeg niet voor versie 10. Hieronder bij font-size
wordt de lettergrootte verkleind. Als in Internet Explorer 9 of 11 een <li> focus heeft en er wordt gelijktijdig over gehoverd, wordt de lettergrootte twee keer toegepast: kennelijk één keer voor de :focus
en één keer voor de :hover
. Door de :hover
alleen te laten werken als de <li> geen focus heeft, wordt dit voorkomen.
De tweede selector:
:focus
: als de <li> focus heeft.
li:empty:focus::afterM
: alles samen. Maak een pseudo-element (::after
) als de <li> focus (:focus
) heeft, maar alleen als die <li> leeg (:empty
) is.
content: "Dit puzzel\00ADstukje is nog niet af. Hier kun je zelf nog iets maken.";
De tekst die in het met ::after
gemaakte pseudo-element moet worden weergegeven. Dit is gewoon normale tekst, met uitzondering van \00AD
. Dit is een code voor een zogenaamd 'zacht koppelteken'. Dat is een koppelteken dat je normaal genomen niet ziet, maar wel als het woord bij het koppelteken wordt afgebroken. Het betreffende woord is hier 'puzzelstukje', een tamelijk lang woord om weer te geven in een heel kleine pop-up.
Om aan te geven dat 00AD
geen gewone tekst is, staat gelijk ervoor een \
. Daardoor weet de browser dat de vier tekens hierna het volgnummer van een utf-8-code zijn, en wordt voorkomen dat ze gewoon worden weergegeven. 00AD
is het volgnummer dat hoort bij een zacht koppelteken.
Hieronder wordt voor dit pseudo-element automatisch afbreken aangezet met hypens: auto;
, maar niet elke browsers herkent dat al. Voor de wat oudere browsers is deze utf-8-code bedoeld.
background: rgba(255, 255, 255, 0.8);
Meestal 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, enz. Daarbij is A gelijk aan het tientallige 10, B aan 11, enz. 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 een heel klein beetje doorzichtig: 0.8. Hierdoor zie je nog vaag de puzzel door de achtergrond heen.
color: black;
Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.
Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hierboven heb ik een achtergrondkleur opgegeven. Sommige mensen hebben zelf de kleur en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als ik nu de achtergrondkleur verander, maar niet de voorgrondkleur, loop ik het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.
Door beide op te geven, weet ik redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important
heeft gebruikt, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.
display: block;
Weergeven als blok-element, zodat eigenschappen als hoogte gebruikt kunnen worden.
box-sizing: border-box;
Standaard worden border
en padding
opgeteld bij de breedte van het element. In dit geval is het handiger, als ook border
en padding
binnen die breedte vallen.
min-height: 100%;
Een hoogte in procenten wordt altijd genomen ten opzichte van de ouder van het element. Dat is hier de <li> waar het pseudo-element bij hoort.
Een blok-element wordt normaal genomen precies hoog genoeg, om de inhoud ervan weer te kunnen geven. Ik vind het mooier als de hele <li>, de ouder, wordt gevuld. De <li> is precies even groot als het puzzelstukje eronder, dus op deze manier dekt het pseudo-element het hele stukje eronder af.
In plaats van height
wordt min-height
gebruikt. Als de lettergrootte wordt vergroot, kan de tekst hoger worden dan 100% van de <li>. Bij gebruik van height
zou de achtergrond niet meegroeien boven 100%, waardoor de tekst slecht leesbaar wordt, als deze wordt vergroot en buiten de <li> komt te staan. Nu groeit de achtergrond, als dat nodig is, mee met de tekst.
font-size: 0.85em;
Iets kleinere letter dan normaal. Als eenheid gebruik ik em
, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
-moz-hyphens: auto; -ms-hyphens: auto; -webkit-hyphens: auto; hyphens: auto;
Hier staat in feite vier keer hetzelfde: hyphens: auto;
Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
Het in content
gebruikte woord 'puzzelstukje' is heel erg lang voor zo'n klein pseudo-element. Daarom wordt automatisch afbreken aangezet.
border: black solid 2px;
Zwart randje.
padding: 5px;
Afstand tussen tekst en rand van het pseudo-element.
li:focus, nav a:focus
Als een <li> focus heeft, of als een <a> binnen een <nav> focus heeft.
outline: none;
Als een element focus heeft, wordt dit normaal genomen aangegeven door een kadertje rondom het element met focus. Dat vind ik hier niet mooi, dus haal ik het weg. Meer over focus en waarom je die niet zonder meer onherkenbaar moet maken, is te vinden bij :focus.
a:hover
Als over een <a> wordt gehoverd.
text-decoration: underline;
Onderstreep de tekst in de <a>.
li:focus > span, li:hover > span, a:focus + span
li:focus > span
: doe iets met de <span>'s die een direct kind zijn van een <li>, maar alleen als die <li> focus heeft.
Het teken >
geeft aan dat het om directe kinderen moet gaan:
<li>
<span></span>
</li>
In onderstaande code is de buitenste <span> een direct kind, waarvoor deze selector dus geldt. De binnenste <span> is geen direct kind van de <li>, maar van de buitenste <span>, dus daarvoor geldt deze selector niet:
<li>
<span>
<span></span>
</span>
</li>
Het gebruik van de >
geeft de mogelijkheid css op te geven die alleen de <span>'s bestrijkt, waarbinnen de volledige pop-up staat. Op die manier kun je bijvoorbeeld het tonen en verbergen van de pop-up regelen door slechts één <span> aan te passen, zonder dat dit dieper geneste <span>'s beïnvloedt.
Deze selector is alleen nodig voor Internet Explorer 11 op een touchscreen en UC browser op Windows Phone. Zonder deze selector moeten eerste en tweede puzzelstukje langer worden aangeraakt, voordat de pop-up opent. Waarom dit niet het geval is bij het zesde en negende stukje, weet ik niet. Wat ik inmiddels wel weet: zodra er een afbeelding in een pop-up zit, gedragen deze browsers zich wat vreemd bij een touchscreen.
li:hover > span
Precies hetzelfde verhaal als hierboven. Alleen werkt dit, als over de <li> wordt gehoverd. En dit is voor álle browsers bedoeld.
a:focus + span
Als de <a> focus heeft, doe dan iets met de in de html direct daarop volgende <span>. De +
geeft aan dat <a> en <span> gelijk op elkaar moeten volgen. Bovendien moeten ze dezelfde ouder hebben. Dat is hier de <li>, waar ze in zitten.
De opbouw van de html is bij elk puzzelstukje als volgt:
<li>
<a></a>
<span>
(...) <span>'s en <img>'s, de eigenlijke pop-up (...)
</span>
</li>
De direct op de <a> volgende <span> is dus, net zoals hierboven bij li:hover
en li:focus
, de <span> waar de hele pop-up in zit.
Aangezien de knop met de <a> normaal genomen is verborgen, kan deze normaal genomen geen focus krijgen. Deze selector is bedoeld voor mensen die van link naar link springen met behulp van de Tab-toets, zodat ook bij gebruik van het toetsenbord om de links af te lopen de pop-up wordt getoond. Meer over de Tab-toets is te vinden bij Tabindex.
display: block;
Bij li > span zijn de <span>'s met de pop-up verborgen met display: none;
. Hier worden ze zichtbaar gemaakt.
li:hover
Als over een <li> wordt gehoverd.
z-index: 20;
Verhoog de z-index van de <li>. Hierdoor wordt ook alles dat in de <li> zit met een hogere z-index weergegeven.
Als een <li> focus heeft, worden de daarin zittende knop met de link en de pop-up getoond. Als je, terwijl die eerste <li> nog focus heeft, over een ander puzzelstukje (en dus over de daarbij horende <li>) hovert, openen de in die tweede <li> zittende knop en pop-up.
Door de z-index van de tweede <li> te verhogen tijdens het erover hoveren, zijn knop en pop-up van de tweede <li> volledig zichtbaar. Normaal genomen zal altijd het later in de html staande element over een eerder element heen worden gezet. Door de z-index bij hoveren te verhogen, worden nu ook knop en pop-up van een eerdere <li> volledig weergegeven. Als dat niet gebeurt, is het nogal verwarrend.
Een z-index werkt alleen bij een gepositioneerd element. Bij li zijn alle <li>'s absoluut gepositioneerd, dus dat is hier het geval.
/*********** Eerste puzzelstukje (krokodil) *********/
Bij grotere bestanden is het vaak handig een soort 'hoofdstukjes' aan te brengen. Als je zoekt naar meerdere sterretjes, kun je zo van deel naar deel springen, wat vaak nogal wat zoekwerk kan besparen. En kan voorkomen dat je in het verkeerde deel van een bestand gaat zitten werken.
#een span
Alle <span>'s binnen het element met id="een".
Dat is de, <span> waarbinnen de eerste pop-up zit, die met de krokodil. En alle <span>'s die daar weer binnen zitten, want het gaat om álle <span>'s binnen #een
.
pointer-events: none;
Dit is nodig voor Internet Explorer 11, omdat anders de pop-up bij aanraken van een touchscreen niet geopend blijft. Deze oplossing werkt bij álle pop-ups, maar is helaas alleen bij de eerste pop-up echt praktisch bruikbaar. Als hij overal bruikbaar zou zijn, zou je gewoon iets als li span {pointer-events: none;}
kunnen gebruiken. Nu moet helaas voor elke pop-up een andere oplossing worden gezocht.
pointer-events: none;
zorgt ervoor dat het element totaal niet reageert op de muis. Niet op hoveren en niet op klikken. Hoveren en klikken gaat als het ware dwars door het element heen naar het eronder liggende element.
Je kunt dit zichtbaar maken door met de muis over de eerste pop-up te hoveren. Zodra je beneden het eerste puzzelstukje, beneden de eerste <li>, komt, sluit de pop-up. Ook als je nog boven de tekst in de pop-up hovert. De <span>'s, en dus de daarin zittende pop-up, reageren niet op het hoveren. Bij de andere pop-ups blijft de pop-up geopend, zolang je over de pop-up hovert, ook als je buiten het puzzelstukje komt, waar de pop-up bij hoort. Bij de eerste pop-up is dit geen probleem, bij de andere wel.
Hier iets boven bij li:hover staat een afbeelding. Als pointer-events: none;
overal zou worden gebruikt, zou dat er precies zo uitzien. Als het tweede stukje met de dansletters focus heeft en is geopend, zou de pop-up van het negende stukje daar gewoon doorheen verschijnen, als je over dat negende stukje hovert. Omdat de pop-up het hoveren gewoon 'doorgeeft' aan de <li> bij het negende stukje.
Bij de eerste pop-up is dat geen probleem, bij de andere wel.
top: 0; left: -150px;
Helemaal bovenaan en 150 px naar links neerzetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Dat is de <li>, waar deze <span> in zit: li#een
.
Omdat de bovenkant van die <li> precies gelijk staat met de bovenkant van de puzzelafbeelding, komt de bovenkant van deze <span>, en dus de daarin zittende pop-up, ook precies gelijk met de bovenkant van de puzzel. Hierdoor verdwijnt ook in lagere browservensters niets aan de bovenkant van het venster, omdat de pop-up te hoog staat.
Omdat de pop-up wel 150 px links buiten de puzzel komt te staan, zou in smallere vensters wel links een deel van de pop-up wegvallen. Daarom wordt later bij @media screen and (max-width: 360px) en @media screen and (min-width: 361px) and (max-width: 670px) left
aangepast voor smallere vensters.
Dit heeft alleen effect op <span>'s die zijn gepositioneerd. Bij li > span zijn de <span>'s die directe kinderen van de <li> zijn absoluut gepositioneerd. Dit heeft alleen effect op die <span>, de <span> waarbinnen de hele pop-up zit. Omdat dieper geneste <span>'s niet zijn gepositioneerd, negeren die dit gewoon.
#een-tekst
Voor dit element geldt ook de eerder bij #een span opgegeven css, voor zover die hier niet wordt gewijzigd.
Het element met id="een-tekst". Dit is de <span>, waarbinnen de tekst van de eerste pop-up zit. Binnen deze <span> zitten weer andere <span>'s, met elk een regel tekst. Hier door kan elke regel tekst precies op de juiste plaats boven de wolk worden neergezet.
display: block;
Een <span> is een inline-element. De hieronder gebruikte margin-top
werkt alleen op blok-elementen. Door de <span> om te toveren in een blok-element, kan een marge aan de bovenkant worden gebruikt.
margin-top: -220px;
Een negatieve marge aan de bovenkant plaatst het element hoger. In dit geval 220px.
In de <span> met de pop-up zit een <img>: de krokodil met bijbehorende wolk. Op de afbeelding is de doorzichtige achtergrond van die afbeelding even gemaakt, zodat de afbeelding volledig zichtbaar is. De span met de tekst komt daar gewoon onder te staan, zoals het volgens de browser hoort.
Door de <span> 220 px omhoog te plaatsen, komt de <span>, en dus de hier weer in zittende <span>'s met de losse regels tekst, op de juiste hoogte te staan.
Met behulp van regelhoogte en dergelijke wordt dan hieronder voor elke regel tekst de exacte plaats bepaald.
#een-tekst span
De <span>'s binnen het element met id="een-tekst".
span#een-tekst
is de <span> waarbinnen de volledige tekst bij de krokodil zit. Binnen die <span> zit elke aparte regel tekst weer in een eigen <span>. Om die laatste <span>'s gaat het hier.
De exacte plaats van elke <span> wordt hieronder voor elke <span> apart opgegeven. Een aantal eigenschappen is echter hetzelfde voor al deze <span>'s, dus die kunnen hier in één keer worden opgegeven.
background: #e7e7e7;
Achtergrondkleur. Deze kleur is hetzelfde als die van de wolk bij de krokodil. Dus eigenlijk zou je dit weg kunnen laten, want je ziet het toch niet. Maar als mensen de lettergrootte vergroten, kan de tekst buiten de wolk komen te staan. En dan is die achtergrond wel belangrijk, omdat de tekst anders nauwelijks is te lezen.
color: black;
Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.
Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hierboven heb ik een achtergrondkleur opgegeven. Sommige mensen hebben zelf de kleur en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als ik nu de achtergrondkleur verander, maar niet de voorgrondkleur, loop ik het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.
Door beide op te geven, weet ik redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important
heeft gebruikt, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.
display: block;
Een <span> is van zichzelf een inline-element. Hier worden ze veranderd in blok-elementen. Eigenlijk is dat hier niet nodig, maar het kan in de toekomst maandenlange wanhopige speurtochten naar de oorzaak van geheimzinnige, enge, onverklaarbare verschijnselen voorkomen.
Als ergens in een voorouder van een element een line-height
is opgegeven, kan die regelhoogte later in een inline-element niet meer worden veranderd. Als in <body> een regelhoogte is opgegeven, kan die in een 97 niveaus diep geneste <span> niet worden gewijzigd. Punt. Discussie gesloten.
Daar zijn goede redenen voor, want het zou echt een zootje worden als je verschillende regelhoogtes in één regel gaat krijgen. (De lettergrootte kan wel worden veranderd. Als dat gebeurt, wordt de regelhoogte daar wel aan aangepast.)
In een blok-element kan de regelhoogte wel worden gewijzigd. Die gewijzigde regelhoogte geldt dan weer voor alle nakomelingen van het blok-element, en kan ook op z'n beurt ook weer alleen worden gewijzigd in een blok-element, niet in een inline-element.
Hier iets onder wordt de regelhoogte voor deze <span>'s aangepast. Dat kan in principe gewoon, omdat nergens eerder een regelhoogte is opgegeven. In dat geval kan ook in een inline-element de regelhoogte worden aangepast.
Maar als ooit – in het jaar 2098, wanneer dit puzzelmenu inmiddels uit 888 stukjes bestaat – door een achterachterachterkleinkind van mij argeloos ergens een regelhoogte wordt toegevoegd, leidt dit tot voornoemde wanhopige speurtocht, omdat de regelhoogte hier dan opeens niet meer werkt.
Daarom verander ik in principe een element, waarin de regelhoogte wordt aangepast, gelijk in een blok-element. Uit verantwoordelijkheidsgevoel voor de geestelijke gezondheid van mijn achterachterachterkleinkind. Als dan later ooit ergens bij een van de voorouders een regelhoogte wordt toegevoegd, blijft de in deze <span> opgegeven regelhoogte gewoon werken.
Dit brengt één klein nadeel met zich mee: een blok-element is normaal genomen even breed als z'n ouder. Dus ook de achtergrond van dat blok-element. Daardoor komt de achtergrondkleur rechts buiten de wolk te staan. Om dat te voorkomen, moet hieronder bij elke <span> met tekst de juiste breedte worden opgegeven.
Op de afbeelding is geen breedte opgegeven aan de <span>'s met tekst, waardoor ze de volle breedte van hun ouder span#een-tekst
vullen.
font-size: 0.95em;
Iets kleinere letter, zodat alles binnen de wolk naast de krokodil past. Als eenheid gebruik ik em
, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
line-height: 1.25em;
Standaard is een regelhoogte ongeveer 1,2 em. Hier komt een iets grotere regelhoogte beter uit. Als eenheid gebruik ik em
, zodat ook gebruikers van Internet Explorer de regelhoogte kunnen veranderen.
#een-tekst-1
Voor dit element geldt ook de eerder bij #een-tekst span opgegeven css, voor zover die hier niet wordt gewijzigd.
Het element met id="een-tekst-1". Dit is de <span> waarbinnen de eerste regel van de tekst uit de pop-up staat: 'Wil jij de tanden'.
width: 7.8em;
Breedte. Bij #een-tekst span is de <span> in een blok-element veranderd en heeft een achtergrondkleur gekregen. Als geen breedte wordt opgegeven, vult de <span> de volle breedte van z'n ouder, zoals op de afbeelding iets hierboven is te zien, waardoor de achtergrondkleur buiten de wolk komt te staan.
Als eenheid wordt em
gebruikt, zodat de breedte meegroeit met een eventueel grotere lettergrootte. Hierdoor blijft de tekst goed te lezen, ook als deze zo groot wordt dat de tekst buiten de wolk komt te staan.
Op de afbeelding is de tekst tot 200% vergroot en staat dus ruim buiten de wolk. Door de breedte in em
en de gekleurde achtergrond is de tekst toch nog goed te lezen, hoewel bij zo'n sterke vergroting een heel klein stukje tekst wegvalt achter de knop met de link.
margin-left: 120px;
Met behulp van een marge links op de juiste plaats binnen de wolk neerzetten. Zonder marge aan de linkerkant wordt de tekst gewoon links in de ouder van de <span> (hier is dat span#een-tekst
) neergezet, waardoor de tekst onder de krokodil zou verdwijnen, zoals op de afbeelding is te zien.
#een-tekst-2
{width: 6em; margin-left: 134px;}
#een-tekst-3
{width: 4em; margin-left: 147px;}
#een-tekst-4
{width: 3.8em; margin-left: 153px;}
#een-tekst-5
{width: 3.8em; margin-left: 154px;}
#een-tekst-6
{width: 6em; margin-left: 142px;}
#een-tekst-7
{width: 12em; margin-left: 52px;}
#een-tekst-8
{width: 10em; margin-left: 60px;}
Voor deze elementen geldt ook de eerder bij #een-tekst span opgegeven css, voor zover die hier niet wordt gewijzigd.
De elementen met id="een-tekst-2" tot en met id="een-tekst-8": de <span>'s met de tweede tot en met achtste regel tekst. De uitleg is precies hetzelfde als die bij #een-tekst-1
gelijk hierboven, alleen zijn de waarden bij de eigenschappen anders.
span#een-tekst-9
Voor dit element geldt ook de eerder bij #een-tekst span opgegeven css, voor zover die hier niet wordt gewijzigd.
De <span> met id="een-tekst-9". De <span> met de negende en laatste regel: '(Alleen voor kinderen met drie armen!)'. Deze selector is iets langer dan die van de eerste acht regels met tekst: hij begint met span
.
Bij #een-tekst span wordt een lettergrootte van 0,95 em opgegeven aan alle <span>'s binnen #een-tekst
. Daar valt ook deze <span> onder.
Hieronder wordt de lettergrootte van deze <span> verkleind. Normaal genomen zou de regel hieronder winnen van de regel bij #een-tekst-span
, omdat hij lager in de css staat. In dit geval gebeurt dat echter alleen, als deze selector met span
begint.
#een-tekst span
heeft een id (#een-tekst
) én een element (span
) in de selector.
#een-tekst-9
(zonder span
aan het begin) telt alleen een id (#een-tekst-9
). Daardoor heeft de eerste regel meer specificiteit, meer 'gewicht', en wint deze toch van de tweede regel, ook al staat deze lager.
span#een-tekst-9
heeft ook een id (#een-tekst-9
) én een element (span
), net zoals #een-tekst span
. De regel heeft nu evenveel specificiteit als #een-tekst span
. En nu wint deze regel wel, omdat hij lager in de css staat.
width: 18.5em;
Breedte. Meer uitleg is te vinden bij #een-tekst-1.
font-size: 0.72em;
Iets kleinere lettergrootte dan de rest van de pop-up. Als eenheid gebruik ik em
, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
margin: 5px 0 0 38px;
Aan de bovenkant 5 px marge, rechts en onder geen marge en links 38 px. Waarmee deze regel op de juiste plaats komt te staan.
#een:focus a, #een:hover a, #een a:focus
Drie selectors.
#een
: het element met id="een". Dit is de <li> waar de <a> die bij het eerste puzzelstukje hoort in zit. Met deze <a> moet iets worden gedaan.
#een:focus a
: doe iets met de <a> als li#een
focus heeft. (Meer over focus bij :focus.)
#een:hover a
: doe iets met de <a> als over li#een
wordt gehoverd.
#een a:focusM
: doe iets met de <a> binnen li#een
, maar alleen als de <a> focus heeft.
Deze laatste selector is voor gebruikers van het toetsenbord, meer daarover bij :focus.
top: 66px; left: 64px;
Bij a zijn alle <a>'s absoluut gepositioneerd en met left: -20000px;
links buiten het scherm geparkeerd. Hier wordt de <a> weer op het scherm gezet. Met deze top
en left
staat de knop goed ten opzichte van de pop-up met tekst en krokodil.
-webkit-transition-delay: 0.5s; transition-delay: 0.5s;
Hier staat in feite twee keer hetzelfde: transition-delay: 0.5s;
Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
Deze eigenschap zorgt voor een vertraging van 'n halve seconde bij het zichtbaar maken van de knop met de link.
Bij a is de knop met de <a> links buiten het scherm geparkeerd met left: -20000px;
. Hierboven is de knop weer binnen het scherm gezet met left: 64px;
.
Als je bij transition-delay
geen eigenschappen opgeeft, zoals hier het getal is, geldt de eigenschap voor álle veranderingen. Hier is de enige verandering left
. Hierboven staat weliswaar ook top
, maar dat staat niet bij a, dus dat verandert niet. Alleen left
staat bij a én hier, dus in dit geval mogen alle veranderingen onder transition-delay
vallen. (Nou ja, 'alle'..., dat is er hier dus maar eentje.)
De normale toestand is left: -20000px;
, zoals opgegeven bij a. Bij hoveren of focus wordt dat veranderd naar left: 64px;
. Door het gebruik van transition-delay
wordt dit 'n halve seconde vertraagd. 'n Halve seconde, omdat als waarde 0.5s
is opgegeven.
Als je op een touchscreen het scherm toevallig precies op de plaats aanraakt, waar een knop met link verschijnt, dan wordt in sommige browsers gelijk die link gevolgd. In sommige browsers kun je dat voorkomen als je het wereldrecord vinger terugtrekken evenaart, maar dat lukt zelfs mij niet altijd, terwijl ik toch heel soepele, lenige, bevallige vingertjes heb. Kortom: dat schiet niet op.
Als je die knop nou met 'n heel kleine vertraging laat verschijnen, dan is je vinger alweer van het scherm af, voordat de link zichtbaar wordt. En kan de link dus nog niet worden aangeraakt en gevolgd, omdat de link er stomweg nog niet staat.
Een vertraging van 'n halve seconde valt nauwelijks op, omdat gelijktijdig een pop-up wordt geopend. 0,5 seconde is minimaal noodzakelijk, omdat Chrome for iOS dat nodig heeft. Andere browsers hebben aan 0,3 seconde genoeg.
Internet Explorer 9 kent transition-delay
niet. Maar deze browser wordt op mobiel zo weinig (meer) gebruikt dat hij in de statistieken zelfs volledig onvindbaar is.
/********** Tweede puzzelstukje (dansletters) **********/
Bij grotere bestanden is het vaak handig een soort 'hoofdstukjes' aan te brengen. Als je zoekt naar meerdere sterretjes, kun je zo van deel naar deel springen, wat vaak nogal wat zoekwerk kan besparen. En kan voorkomen dat je in het verkeerde deel van een bestand gaat zitten werken.
#twee span
Alle <span>'s binnen het element met id="twee".
Dat is de <span>, waarbinnen de tweede pop-up zit, die met de dansletters. En alle <span>'s die daar weer binnen zitten, want het gaat om álle <span>'s binnen #twee
.
top: 0; left: -141px;
Helemaal bovenaan en 150 px naar links neerzetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Dat is de <li> waar deze <span> in zit: li#twee
.
Omdat de bovenkant van die <li> precies gelijk staat met de bovenkant van de puzzelafbeelding, komt de bovenkant van deze <span>, en dus de daarin zittende pop-up, ook precies gelijk met de bovenkant van de puzzel. Hierdoor verdwijnt ook in lagere browservensters niets aan de bovenkant van het venster, omdat de pop-up te hoog staat.
Omdat de pop-up wel 150 px links en rechts iets buiten de puzzel uitsteekt, zou in smallere vensters wel links en rechts een deel van de pop-up wegvallen. Daarom wordt later bij @media screen and (max-width: 470px), (max-height: 570px) left
aangepast voor smallere vensters.
Dit heeft alleen effect op <span>'s die zijn gepositioneerd. Bij li > span zijn de <span>'s die directe kinderen van de <li> zijn absoluut gepositioneerd. Dit heeft alleen effect op die <span>, de <span> waarbinnen de hele pop-up zit. Omdat dieper geneste <span>'s niet zijn gepositioneerd, negeren die dit gewoon.
#twee-tekst
Voor dit element geldt ook de eerder bij #twee span opgegeven css, voor zover die hier niet wordt gewijzigd.
Het element met id="twee-tekst". Dit is de <span>, waarbinnen de dansende letters zitten. Binnen deze <span> zit elk woord weer in een eigen <span>. Hierdoor kun je op een simpele manier de afstand tussen de woorden en dergelijke regelen.
background: #0f9;
Achtergrondkleurtje.
display: block;
Een <span> is een inline-element. Door het te veranderen in een blok-element, kunnen eigenschappen als breedte en hoogte worden gebruikt.
width: 370px;
370 px breed.
height: 380px;
380 px hoog.
border: 10px outset #0ff;
Meerkleurige rand.
padding: 10px;
Afstand tussen letters en rand van de pop-up.
#twee-tekst span
Voor deze elementen geldt ook de eerder bij #twee span opgegeven css, voor zover die hier niet wordt gewijzigd.
De <span>'s binnen het element met id="twee-tekst". Dit zijn de <span>'s waarbinnen de dansende letters zitten: voor elk woord een aparte <span>.
Omdat er ook een afbeelding en een knop met een link in de pop-up staan, worden hieronder wat correcties voor positie en dergelijke van de afzonderlijke <span>'s aangebracht. Een aantal eigenschappen is echter hetzelfde voor al deze <span>'s, dus die kunnen hier in één keer worden opgegeven.
display: inline-block;
Een <span> is een inline-element. Daardoor kun je geen eigenschappen als hoogte gebruiken. Je zou van de <span>'s blok-elementen kunnen maken, maar dan komt elke <span> op een nieuwe regel te staan. Dat is niet de bedoeling, want in elke <span> zit een woord. En elk woord, ook korte woorden, zou dan op een nieuwe regel komen te staan.
inline-block
verenigt in dit geval het beste van twee werelden: de <span>'s komen naast elkaar te staan (tot de regel vol is), maar eigenschappen als hoogte en dergelijke kunnen toch worden gebruikt.
height: 50px;
Hoogte. In de <span>'s zitten afbeeldingen met letters. De hoogte van die afbeeldingen varieert nogal. De makkelijkste manier om die verschillen te corrigeren is het geven van een hoogte aan de <span>, want daar staan ze nou eenmaal allemaal in.
#twee-tekst span img
Alle afbeeldingen die in een <span> zitten die weer binnen het element met id="twee-tekst" zit. Dit zijn de dansende letters.
De afbeelding van de olifant zit niet in een <span>, dus die valt niet onder deze selector. Die olifant wordt hier gelijk onder bij #twee-tekst > img
apart afgehandeld.
background: #0f9;
Zelfde achtergrondkleur als de pop-up.
De afbeeldingen hebben een doorzichtige achtergrond. Bij inzoomen (vergroten) kan het zijn dat de onderste woorden net niet meer binnen de pop-up vallen, waardoor ze geen achtergrond hebben en heel moeilijk leesbaar zijn. (Eigenlijk zou dit niet moeten gebeuren, maar door afrondingsverschillen passen in sommige browsers net niet meer alle woorden naast elkaar, waardoor de laatste regel te laag komt te staan.)
Bij een grotere lettergrootte wordt de tekst in de knop met de link vergroot, waardoor niet meer alle woorden naast elkaar passen. Ook nu komt de onderste regel buiten de pop-up te staan.
Door een achtergrondkleur aan de afbeeldingen te geven, blijven ze goed leesbaar, ook als ze buiten de pop-up staan.
margin-left: -3px;
Door alle afbeeldingen met letters iets naar links te verplaatsen, passen er meer naast elkaar. Dat kan bij deze letters makkelijk, want de letters hebben vrij veel lege ruimte aan de zijkant.
#twee-tekst > img
Alle <img>'s binnen het element met id="twee-tekst" die een direct kind van #twee-tekst
zijn. Dat ze een direct kind moeten zijn, wordt aangegeven met het teken >
.
Onderstaande <img> is een direct kind van #twee-tekst
:
<li id="twee-tekst">
<img>
</li>
De <img> hieronder is geen direct kind van #twee-tekst
, omdat er een <span> tussen #twee-tekst
en <img> zit:
<li id="twee-tekst">
<span>
<img>
</span>
</li>
In dit geval is er maar één <img> die een direct kind van #twee-tekst
is: de afbeelding met de olifant.
float: left;
In tegenstelling tot wat veel mensen denken, is een <img> een gewoon inline-element, net zoals gewone tekst. Weliswaar een inline-element met wat bijzondere eigenschappen, maar het blijft een inline-element. Een <span> is ook een inline-element. Normaal genomen wordt de <img> dus gewoon links gezet en komen rechts daarvan één of meer <span>'s, tot de regel vol is.
Op de afbeelding rechts is de olifant eigenlijk gewoon 'n soort letter: hij staat gezellig samen met de <span> met het woord 'vinden' op één regel, netjes op dezelfde hoogte. Dat die regel wat hoog is, komt omdat de afbeelding met de olifant wat hoog is. De regelhoogte past zich aan die hoogte aan.
Op de afbeelding links is float
gebruikt. De olifant wordt nu los van de rest neergezet, niet als inline-element. In de ruimte rechts van de olifant worden nu net zoveel <span>'s neergezet als er in passen. In dit geval zijn dat de twee <span>'s met de woorden 'vinden' en 'zoiets'.
margin: 5px 20px 0 0;
Marge van 5 px aan de bovenkant, 20 px rechts en onder en links geen marge.
#twee-tekst span:first-of-type, #twee-tekst span:nth-of-type(6), #twee-tekst span:nth-of-type(10)
Voor deze elementen geldt ook de eerder bij #twee span opgegeven css, voor zover die hier niet wordt gewijzigd.
Elk woord zit in een aparte <span>. In totaal zijn er elf woorden, dus er zijn elf <span>'s. Op een aantal regels staan twee woorden naast elkaar. Het eerste woord daarvan krijgt rechts een extra marge, zodat er wat afstand is tussen de twee woorden.
Er zijn elf <span>'s, die netjes op volgorde binnen #twee-tekst
zitten. In totaal moeten drie woorden een marge rechts krijgen. Het simpelste zijn die woorden te bereiken via het volgnummer van de <span> waar ze in zitten.
(Er zijn vier regels met twee woorden, maar de afstand tussen 'geschikt' en 'voor' op de tweede regel is uit zichzelf groter dan bij de andere drie, dus die wordt hieronder apart afgehandeld.)
#twee-tekst
: alleen bepaalde <span>'s van de tweede pop-up moeten deze marge krijgen. Zou je dit niet beperken tot #twee-tekst
, dan zou élke <span> op de pagina die toevallig hetzelfde volgnummer heeft deze marge krijgen.
span:first-of-type
: het eerste element van deze soort. Omdat er span
aan het begin staat, gaat het hier om de eerste <span>. Dit is de <span>, waarin 'niet' zit, het linkerwoord op de eerste regel. (In plaats van :first-of-type
kun je ook :nth-of-type(1)
gebruiken, dat betekent precies hetzelfde.)
span:nth-of-type(6)
: vrijwel hetzelfde als die gelijk hierboven, maar hier gaat het om de zesde <span>. Dit is de <span>, waarin 'maar' zit, het linkerwoord op de vierde regel.
span:nth-of-type(10)
: ook weer vrijwel hetzelfde, maar nu voor de tiende <span>. Dit is de <span> waarin 'juist' zit, het linkerwoord op de onderste regel.
margin-right: 25px;
Marge van 25 px aan de rechterkant, zodat er wat afstand tot het volgende woord ontstaat.
#twee-tekst span:nth-of-type(3)
{margin-right: 13px;}
Voor dit element geldt ook de eerder bij #twee span opgegeven css, voor zover die hier niet wordt gewijzigd.
Exact hetzelfde verhaal als gelijk hierboven, maar dan voor de derde <span> met rechts een marge van slechts 13 px.
#twee:focus a, #twee:hover a, #twee a:focus
{top: 26px; left: 130px; -webkit-transition-delay: 0.5s; transition-delay: 0.5s;}
Als de tweede <li> focus heeft, of als over de tweede <li> (het tweede puzzelstukje) wordt gehoverd, of als de tweede <a> focus heeft, toon dan de knop met de link.
Dit werkt precies hetzelfde als bij de eerste <li>, waarvan de uitleg te vinden is bij #een:focus a, #een:hover a, #een a:focus. Alleen de waarden bij top
en left
zijn anders, omdat de knop op een andere plaats komt te staan.
/************ Zesde puzzelstukje (uitgang) *************/
Bij grotere bestanden is het vaak handig een soort 'hoofdstukjes' aan te brengen. Als je zoekt naar meerdere sterretjes, kun je zo van deel naar deel springen, wat vaak nogal wat zoekwerk kan besparen. En kan voorkomen dat je in het verkeerde deel van een bestand gaat zitten werken.
#zes img
De <img>'s binnen het element met id="zes". Er is hier maar één afbeelding: de afbeelding van de uitgang bij het zesde puzzelstukje.
display: none;
Afbeelding verbergen.
position: absolute;
Om de afbeelding op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Dat is hier li#zes
.
left: -130px;
Afbeelding 130 px naar links verplaatsen, zodat hij binnen de puzzel komt te staan.
#zes:focus a, #zes:hover a, #zes a:focus
{top: -20px; left: -64px; -webkit-transition-delay: 0.5s; transition-delay: 0.5s;}
Als de zesde <li> focus heeft, of als over de zesde <li> (het zesde puzzelstukje) wordt gehoverd, of als de zesde <a> focus heeft, toon dan de knop met de link.
Dit werkt precies hetzelfde als bij de eerste <li>, waarvan de uitleg te vinden is bij #een:focus a, #een:hover a, #een a:focus. Alleen de waarden bij top
en left
zijn anders, omdat de knop op een andere plaats komt te staan.
#zes:focus img, #zes:hover img, #zes a:focus + img
#zes:focus img
: doe iets met de de <img>'s binnen het element met id="zes" maar alleen als #zes
focus heeft. #zes
is de zesde <li>. Daarbinnen zit maar één <img>: het plaatje met de uitgang.
#zes:hover img
: precies hetzelfde als gelijk hierboven, maar dan bij hoveren over de zesde <li>.
#zes a:focus + img
: doe iets met de <img>'s die gelijk op een <a> volgen binnen het element met id="zes", maar alleen als de <a> focus heeft.
De +
geeft aan dat de <img> gelijk op de <a> moet volgen in de html, en beide moeten dezelfde ouder hebben. Die gemeenschappelijke ouder is hier li#zes
.
Deze derde selector is bedoeld voor mensen die de Tab-toets gebruiken om links af te lopen. Meer daarover is te vinden bij Tabindex.
display: block;
En wat moet er dan voor wonderschoons gebeuren met deze <img>? Hij moet worden getoond, wat het hoogste is wat een afbeelding in het leven kan bereiken.
Bij #zes img is de afbeelding verborgen met display: none;
, hier wordt hij weer zichtbaar gemaakt.
/*********** Negende puzzelstukje (mail) ****************/
Bij grotere bestanden is het vaak handig een soort 'hoofdstukjes' aan te brengen. Als je zoekt naar meerdere sterretjes, kun je zo van deel naar deel springen, wat vaak nogal wat zoekwerk kan besparen. En kan voorkomen dat je in het verkeerde deel van een bestand gaat zitten werken.
#negen > span
Voor dit element geldt ook de eerder bij li > span opgegeven css, voor zover die hier niet wordt gewijzigd.
Alle <span>'s die een direct kind van het element met id="negen" zijn. Dit is de <span> waarbinnen de afbeelding en de <span>'s met de eigenlijke tekst zitten.
Het teken >
geeft aan dat het om directe kinderen moet gaan:
<li>
<span></span>
</li>
In onderstaande code is de buitenste <span> een direct kind van li#negen
, waarvoor deze selector dus geldt. De binnenste <span> is geen direct kind van de <li>, maar van de buitenste <span>, dus daarvoor geldt deze selector niet:
<li id="negen">
<span>
<span></span>
</span>
</li>
In dit geval is er maar één span een direct kind van li#negen
. Het gebruik van de >
geeft de mogelijkheid css op te geven die alleen die ene <span> bestrijkt, zonder dat dit dieper geneste <span>'s beïnvloedt.
background: #fc9;
chtergrondkleurtje.
color: black;
Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.
Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hierboven heb ik een achtergrondkleur opgegeven. Sommige mensen hebben zelf de kleur en/of achtergrondkleur veranderd, bijvoorbeeld omdat ze slecht kleuren kunnen onderscheiden. Als ik nu de achtergrondkleur verander, maar niet de voorgrondkleur, loop ik het risico dat tekstkleur en achtergrondkleur te veel op elkaar gaan lijken.
Door beide op te geven, weet ik redelijk zeker dat achtergrond- en tekstkleur genoeg van elkaar blijven verschillen. Als de gebruiker !important
heeft gebruikt, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.
display: block;
Van zichzelf is een <span> een inline-element. Door het te veranderen in een blok-element kun je eigenschappen als breedte gebruiken. Maar eigenlijk zou dat hier niet nodig moeten zijn. Bij li > span is deze <span> absoluut gepositioneerd, waardoor de <span> al in een soort blok-element is veranderd.
Daar wordt deze <span> ook verborgen met display: none;
, wat hier dus weer ongedaan wordt gemaakt met display: block;
.
Waarom al dat gedoe hier nodig is en display: block;
wordt gebruikt, staat iets hieronder bij transition-delay: 0.1s;
.
width: 200%;
Een breedte in procenten wordt altijd genomen ten opzichte van de ouder van het element. Dat is hier li#negen
. De pop-up wordt dus twee keer zo breed als de bijbehorende <li>. En omdat de <li> weer even breed is als een puzzelstukje, wordt afbeelding twee keer zo breed als een puzzelstukje.
-moz-hyphens: auto; -ms-hyphens: auto; -webkit-hyphens: auto; hyphens: auto;
Hier staat in feite vier keer hetzelfde: hyphens: auto;
. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
Omdat de ruimte voor de tekst hier en daar wat krap is, wordt automatisch afbreken aangezet. Dit werkt niet in alle browsers, maar dat maakt niet zoveel uit. Waar het wel werkt, is het meegenomen.
border: red solid 1px;
Rood randje.
padding: 5px;
Afstand tussen tekst en rand van de pop-up.
left: -20000px;
Links buiten het scherm parkeren, zodat de pop-up onzichtbaar is. Waarom hiervoor is gekozen en niet voor display: none;
staat gelijk hieronder bij transition-delay: 0.1s
.
transition-delay: 0.1s;
Zodra een pop-up een afbeelding bevat, heeft Internet Explorer 11 op een touchscreen daar om een of andere reden problemen mee: de pop-up blijft niet open. Ik heb geen oplossing kunnen vinden die bij elke pop-up werkt, elke oplossing is weer anders. pointer-events: none;
werkt wel overal, maar is helaas alleen bij de eerste pop-up bruikbaar, zoals beschreven bij #een span. Bij de zesde pop-up werkt display: none;
bij de afbeelding, hier niet, om wat voor reden dan ook.
transition-delay
is een deel van de oplossing bij deze pop-up. Daarom is hier -webkit-transition-delay niet gebruikt, want het is alleen nodig voor Internet Explorer, en die heeft niets aan het voorvoegsel -webkit-
.
Na enig gepuzzel blijkt deze pop-up in Internet Explorer 11 ook op een touchscreen geopend te blijven door de volgende combinatie van display
, left
en transition-delay
:
display: block;
(iets hierboven opgegeven). Bij li > span is ook deze <span> verborgen met display: none;
, maar dan blijft de pop-up niet geopend. De pop-up moet al bestaan voor het touchscreen wordt aangeraakt. Dus display: none;
is voor deze <span> niet bruikbaar.
left: -20000px;
: omdat de pop-up al aanwezig is, wordt deze – anders dan bij de andere pop-ups – verborgen door hem links buiten het scherm te parkeren. Als hij getoond moet worden, wordt hij dan weer op het scherm gezet.
transition-delay: 0.1s;
: ten slotte is dan nog een minieme vertraging van een tiende seconde nodig. Vraag me niet waarom.
Deze eigenschap zorgt voor een vertraging, als iets wordt veranderd bij :focus
, :hover
, en dergelijke. Als je geen eigenschappen vermeldt, heeft de vertraging betrekking op álle veranderingen.
Bij #negen:focus > span, #negen:hover > span, # negen a:focus + span wordt left: -120%;
opgegeven. Dat is de enige eigenschap die daar wordt gebruikt, dus in dit geval mag transition-delay
gewoon voor álle eigenschappen gelden.
#negen span:nth-of-type(3)
{font-size: 0.95em;}
#negen span:nth-of-type(5)
{font-size: 0.9em;}
#negen span:nth-of-type(6)
{font-size: 0.85em;}
#negen span:nth-of-type(7)
{font-size: 0.8em;}
Eerst de selector.
#negen
: de werking moet beperkt worden tot de elementen die bij de negende pop-up horen, de pop-up binnen li#negen
.
Binnen li#negen
zitten vijf <span>'s met doorlopende tekst en twee <span>'s met aparte blokjes tekst. De zeven <span>'s samen vormen een aaneengesloten rijtje. De doorlopende tekst zit in de eerste, derde, vijfde, zesde en zevende <span>. Die doorlopende tekst wil ik steeds iets kleiner maken.
span:nth-of-type(...)
: het nummer tussen de haakjes geeft aan het hoeveelste element van die soort het moet zijn. Omdat het achter span
staat, gaat het hier om de zoveelste <span>. In de vier bovenstaande selectors zijn de cijfers 3, 5, 6 en 7 ingevuld, dus het gaat in dit geval om de derde, vijfde, zesde en zevende <span>.
De eerste <span> doet niet mee, ook al staat daar doorlopende tekst in, want daarvan wordt de lettergrootte nog niet verkleind.
Bij elk van de vier <span>'s wordt de tekst steeds iets kleiner gemaakt met behulp van font-size
. Als eenheid gebruik ik em
, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
De tekst is te lang voor de meeste browservensters, maar dat maakt niet uit. Wat niet past, verdwijnt gewoon aan de onderkant van het venster. In dit geval is dat verdwijnen opzettelijk, dus het is geen probleem.
Op de hiernaast staande afbeelding zijn de <span>'s met doorlopende tekst even met kleurtjes herkenbaar gemaakt:
eerste <span>: tekst met de gewone roze achtergrond.
tweede <span>: het blokje tekst rechts met de gele achtergrond.
derde <span>: de tekst met de blauwe achtergrond.
vierde <span>: het blokje tekst links met de grijze achtergrond.
vijfde <span>: de tekst met de rode achtergrond.
zesde <span>: de tekst met de groene achtergrond.
zevende <span>: de tekst onderaan met de gele achtergrond.
Alleen van de derde, vijfde, zesde en zevende <span> wordt hier de lettergrootte verkleind: steeds iets kleiner.
#negen img
Alle <img>'s binnen het element met id="negen". Er is zit maar één afbeelding binnen li#negen
: de postbus.
float: right;
In tegenstelling tot wat veel mensen denken, is een <img> een gewoon inline-element, net zoals tekst. Weliswaar een inline-element met wat bijzondere eigenschappen, maar het blijft een inline-element.
Als de <img zonder meer wordt weergegeven, komt deze dan ook gewoon naast de tekst op dezelfde regel te staan, zoals op de afbeelding hiernaast is te zien. Waarbij de regelhoogte zich aan de hoogte van de afbeelding aanpast.
Door de afbeelding naar rechts te floaten, wordt deze zo hoog mogelijk en vervolgens zo ver mogelijk naar rechts neergezet. De afbeelding komt nu los van de tekst te staan. Links van de afbeelding wordt de lege ruimte nu volledig opgevuld met tekst, zoals op de afbeelding hiernaast is te zien.
#idee
Het element met id="idee". Dit is de <span>, waarbinnen het gele vakje met tekst rechts binnen de pop-up staat.
background: yellow;
Gele achtergrond.
color: #411;
Donkerbruine (of zoiets, ik ben kleurenzwak) voorgrondkleur. Dit is onder andere de kleur van de tekst.
width: 40%;
Een breedte in procenten wordt altijd genomen ten opzichte van de ouder van het element. Dat is hier de <span> waar de hele pop-up in zit. Die is bij #negen > span met width: 200%;
zelf weer twee keer zo breed gemaakt als de ouder daarvan: li#negen
. Deze <li> is even breed als 'n stukje van de puzzel. De <span> met de pop-up is dus twee puzzelstukjes breed.
Dit gele blokje wordt krijgt 40% van die breedte van twee puzzelstukjes naast elkaar.
float: right;
De tekst staat in een gewone <span>. Daardoor zou de tekst gewoon net als alle andere tekst worden weergeven: op een regel. Dat dat niet helemaal goed gaat, is hiernaast te zien.
Door de <span> naar rechts te floaten, wordt deze zo hoog mogelijk en vervolgens zo ver mogelijk naar rechts neergezet. De andere tekst komt dan gewoon links daarvan te staan.
Een <span> is van zichzelf een inline-element. Het floaten verandert de <span> in een soort blok-element, waardoor ook eigenschappen als breedte bruikbaar worden.
font-size: 1.1em;
Iets grotere letter. Als eenheid gebruik ik em
, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
margin: 3px 0 0 3px;
Kleine marge boven en links van de <span>, zodat er wat ruimte komst tussen de rest van de tekst en het gele blokje.
border: black solid 1px;
Zwart randje.
border-radius: 8px;
Ronde hoeken.
padding: 3px;
Kleine ruimte tussen tekst in en rand van het blokje.
#vraag-eerst
Het element met id="vraag-eerst". Dit is de <span>, waarbinnen de tekst over de toestemming staat.
background: #ddd;
Achtergrondkleurtje.
float: left;
Tekst niet tussen de andere tekst neerzetten. De uitleg is iets hierboven te vinden bij #idee onder float: right;
. Alleen wordt hier niet naar rechts, maar naar links gefloat.
margin: 3px 3px 0 0;
Boven en rechts marge van 3 px, zodat de rest van de tekst niet gelijk tegen het blokje aan komt te staan.
border: solid blue 2px;
Blauw randje.
padding: 2px;
Kleine afstand tussen tekst in en rand van het blokje.
#negen:focus a, #negen:hover a, #negen a:focus
{top: -25px; left: -8px; -webkit-transition-delay: 0.5s; transition-delay: 0.5s;}
Als de negende <li> focus heeft, of als over de negende <li> (het negende puzzelstukje) wordt gehoverd, of als de negende <a> focus heeft, toon dan de knop met de link.
Dit werkt precies hetzelfde als bij de eerste <li>, waarvan de uitleg te vinden is bij #een:focus a, #een:hover a, #een a:focus. Alleen de waarden bij top
en left
zijn anders, omdat de knop op een andere plaats komt te staan.
#negen:focus > span, #negen:hover > span, #negen a:focus + span
#negen:focus > span
: doe iets met de de <span>'s die een direct kind van het element met id="negen"zijn, maar alleen als #negen
focus. heeft. #negen
is de negende <li>, waarin pop-up en knop zitten die bij het negende puzzelstukje horen.
Het teken >
geeft aan, dat het alleen <span>'s zijn die een direct kind van #negen
zijn. Onderstaande <span> is een direct kind van #negen
:
<li id="negen">
<span>
</li>
De binnenste <span> hieronder is geen direct van #negen
, omdat er een <span> tussen de binnenste <span> en de <li> zit. De buitenste <span> is wel een direct kind van li#negen
.
<li id="negen">
<span>
<span>
</span>
</li>
#negen:hover > span
: precies hetzelfde verhaal als gelijk hierboven, maar nu bij hoveren over li#negen
.
#negen a:focus + span
doe iets met de <span>'s die gelijk op een <a> volgen binnen het element met id="negen", maar alleen als de <a> focus heeft.
De +
geeft aan dat de <span> gelijk op de <a> moet volgen in de html, en beide moeten dezelfde ouder hebben. Die gemeenschappelijke ouder is hier li#negen
.
Deze derde selector is bedoeld voor mensen die de Tab-toets gebruiken om links af te lopen. Meer daarover is te vinden bij Tabindex.
left: -120%;
Bij #negen > span is de <span> met de pop-up links buiten het scherm geparkeerd. Hier wordt hij terug op het scherm gezet, waardoor hij zichtbaar wordt.
Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een positie heeft. Dat is hier li#negen
. Dit geldt ook als je als eenheid geen px, maar procenten gebruikt.
Ik gebruik procenten, zodat de plaatsing mee verandert bij smallere browservensters. Als je px of een andere absolute eenheid gebruikt, gebeurt dat niet. Een deel van de pop-up zou daardoor rechts buiten het venster verdwijnen.
In heel kleine vensters is dat nog steeds zo, daarom wordt de plaatsing daarvoor bij @media screen and (max-width: 380px), (max-height: 540px) aangepast.
Bij 0% zou de linkerkant van de pop-up precies gelijk komen te staan met de linkerkant van li#negen
. Bij #negen > span is aan de pop-up een breedte van 200% gegeven, twee keer zo breed als li#negen
. Bij -100% zou de pop-up daardoor voor de helft links van li#negen
komen te staan.
Hier is -120% opgegeven, daardoor blijft er aan de rechterkant van de pop-up een stukje van de eronder liggende li#negen
– en dus het daarmee corresponderende puzzelstukje – zichtbaar.
/********** Aanpassingen voor kleinere vensters **********/
Bij grotere bestanden is het vaak handig een soort 'hoofdstukjes' aan te brengen. Als je zoekt naar meerdere sterretjes, kun je zo van deel naar deel springen, wat vaak nogal wat zoekwerk kan besparen. En kan voorkomen dat je in het verkeerde deel van een bestand gaat zitten werken.
Normaal genomen worden media queries door de meeste mensen van klein naar groot neergezet, ook door mij. De pagina wordt als het ware afgestemd op de kleinste weergave. Voor grotere browservensters worden dan later met behulp van media queries aanpassingen aangebracht.
Die volgorde heb ik hier niet aangehouden. Hier staan de aanpassingen voor kleinere vensters juist onderaan. Het gaat hier, voor een deel, om heel specifieke aanpassingen voor één pop-up en dergelijke, en het zou – volgens mij – in dit geval verwarrend zijn om daarmee te beginnen.
Het is een tamelijk grote serie media queries, maar ze bestrijken zo'n beetje alle verschillende mogelijkheden. Zou je nog meer puzzelstukjes afmaken, dan zouden veel daarvan waarschijnlijk gebruik kunnen maken van al bestaande media queries voor de vier stukjes die al klaar zijn.
css voor vensters in landschapsstand en lager dan 350 px
@media screen and (orientation: landscape) and (max-height: 350px)
De css die hier tot nu toe staat, geldt voor alle browservensters. De css die hieronder staat, geldt alleen voor liggende browservensters lager dan 350 px. Voor een deel is dit nieuwe css, voor een deel wordt hierboven staande css aangepast.
@media
: geeft aan dat het om css gaat, die alleen van toepassing is, als aan bepaalde voorwaarden wordt voldaan. Al langer bestond de mogelijkheid om met behulp van zo'n @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. Een menu printen is wat zinloos.
and
: er komt nog een voorwaarde, waaraan moet worden voldaan.
(orientation: landscape)
: het scherm moet in landschapsstand zijn.
Een scherm kent twee standen: landscape (landschap, liggend) en portrait (portret, staand). (Allerlei andere standen zoals bijvoorbeeld lezend in bed tellen hier niet mee. Liggend of staand, dat is het, al hang je met je tablet ondersteboven heen en weer te zwaaien aan de trapeze.)
Dit is bedoeld voor tablets, smartphones, en dergelijke. Voor desktop monitors zal de stand meestal niet echt van belang zijn. In combinatie met de lage maximumhoogte van 350 px wordt helemaal duidelijk, dat dit niet voor de desktop is bedoeld. Maar in veel browsers werkt dit ook op de desktop. Als je de grootte van het venster verandert, zodat het lager dan 350 px en breder dan 350 px (landschapsstand) wordt, werkt dit vaak ook op de desktop.
and
: er komt nog een voorwaarde, waaraan moet worden voldaan.
(max-height: 350px)
: het browservenster mag niet hoger zijn dan 350px. Is het venster hoger, 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 (orientation: landscape) and (max-height: 350px) {
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 }
.
#wrapper
Het element met id="wrapper". Dit is de div waar de hele handel in staat.
-ms-transform: scaleX(0.6); -webkit-transform: scaleX(0.6); transform: scaleX(0.6);
Hier staat in feite drie keer hetzelfde: transform: scaleX(0.6);
Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
Bij #wrapper heeft div#wrapper
, waar de hele handel in staat, een maximale hoogte van 100% gekregen. Dat is bedoeld voor lagere browservensters, om te voorkomen dat een deel van de <li>'s buiten het venster komt te staan en daarmee onbereikbaar is.
Dit geldt ook voor de inhoud van div#wrapper
. Waaronder de puzzelafbeelding, want die mag niet hoger of breder dan div#wrapper
zijn, zoals met behulp van max-height
en max-width
opgegeven bij nav > img. Als in een laag venster de hoogte van de afbeelding wordt aangepast, maar niet de breedte, krijg je 'n lachspiegeleffect. Om dat zo goed mogelijk te corrigeren, wordt de breedte aangepast.
transform
is een eigenschap om van alles aan te passen. Hier wordt de transform-functie scaleX()
gebruikt: schalen in horizontale richting. In dit geval wordt tot zes tiende verkleind. Omdat ook de afbeelding hieraan meedoet, wordt het lachspiegeleffect enigszins verminderd.
In Android browser en UC browser op Android is de puzzelafbeelding in zulke lage browservensters toch hoger dan het venster. Dat is een bug in die browsers, meer daarover bij Bekende problemen (en oplossingen).
li:empty:hover::after, li:empty:focus::after
{font-size: 0.7em;}
Bij li:empty:not(:focus):hover::after, li:empty:focus::after wordt bij hoveren een tekst tevoorschijn getoverd voor de nog niet in gebruik zijnde puzzelstukjes. Dat blijft hier allemaal hetzelfde werken, alleen wordt de lettergrootte wat verkleind voor deze kleine browservensters, anders past het niet.
Als eenheid gebruik ik em
, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
css voor vensters in landschapsstand en hoger dan 351 px en lager dan 479 px
@media screen and (orientation: landscape) and (min-height: 351px) and (max-height: 479px)
De opbouw van deze regel staat beschreven bij @media screen and (orientation: landscape) and (max-height: 350px). Er zijn twee verschillen: het browservenster moet minimaal 351 px hoog zijn: (min-height: 351px)
. En de maximale hoogte mag 479 px zijn: (max-height: 479px)
. Er zijn hier dus drie voorwaarden: liggend en een hoogte tussen 351 en 479 px.
#wrapper {
-ms-transform: scaleX(0.8); -webkit-transform: scaleX(0.8); transform: scaleX(0.8);}
li:empty:hover::after, li:empty:focus::after
{font-size: 0.7em;}
Ook het verhaal voor de css is hetzelfde als hierboven bij @media screen and (orientation: landscape) and (max-height: 350px). Het is bedoeld voor browservensters die niet echt klein zijn, maar ook niet echt groot: pubervensters. De maat van de scaleX() is daarom iets aangepast.
css voor vensters smaller dan 360 px
@media screen and (max-width: 360px)
De opbouw van deze regel staat beschreven bij @media screen and (orientation: landscape) and (max-height: 350px). Er zijn twee verschillen: de stand van het browservenster maakt niet uit, dus orientation
ontbreekt. En het gaat hier niet om een maximale hoogte, maar om een maximale breedte: (max-width: 360px)
.
#een a, #een span
De links binnen het element met id="een" en de <span>'s binnen het element met id="een". Dit zijn de link en de pop-up binnen li#een
, die bij het eerste puzzelstukje horen.
-ms-transform: scale(0.9); -webkit-transform: scale(0.9); transform: scale(0.9);
Hier staat in feite drie keer hetzelfde: transform: scale(0.9);
. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
transform
is een eigenschap om van alles aan te passen. Hier wordt de transform-functie scale()
gebruikt: schalen in beide richtingen, horizontaal en verticaal. In dit geval wordt tot negen tiende verkleind. Omdat maar één getal is opgegeven, wordt in beide richting evenveel geschaald.
In zulke kleine browservensters is er wat te weinig ruimte voor pop-up en knop van het eerste puzzelstukje. Daarom worden ze iets verkleind.
#een a
De links binnen het element met id="een". Dat is er hier maar één: de link binnen li#een
, die bij het eerste puzzelstukje hoort.
margin-left: 110px;
Een extra marge aan de linkerkant, omdat de knop met de link anders over de afbeelding en tekst van de pop-up heen komt te staan, want die wordt gelijk hieronder ook naar rechts verplaatst.
#een span
De <span>'s binnen het element met id="een". Dat is er hier maar één: de <span> met de pop-up binnen li#een
, die bij het eerste puzzelstukje hoort.
left: -20px;
Bij #een span is de <span> met left: -120px;
een eindje links buiten de puzzelafbeelding gezet. In dit soort smalle browservensters zouden krokodil en tekst daardoor grotendeels links buiten het venster verdwijnen. 100 px minder naar links zetten en het past weer.
Dit heeft alleen effect op <span>'s die zijn gepositioneerd. Bij li > span zijn de <span>'s die directe kinderen van de <li> zijn absoluut gepositioneerd. Dit heeft alleen effect op die <span>, de <span> waarbinnen de hele pop-up zit. Omdat dieper geneste <span>'s niet zijn gepositioneerd, negeren die dit gewoon.
css voor vensters breder dan 361 px en smaller dan 670 px
@media screen and (min-width: 361px) and (max-width: 670px)
De opbouw van deze regel staat beschreven bij @media screen and (orientation: landscape) and (max-height: 350px). Er zijn drie verschillen: de stand van het browservenster maakt niet uit, dus orientation
ontbreekt. En het gaat hier niet om de hoogte, maar om de breedte. Het venster moet minstens 361 px (min-width: 361px)
en hoogstens 670 px (max-width: 670px)
breed zijn.
#een a
De links binnen het element met id="een". Dat is er hier maar één: de link binnen li#een
, die bij het eerste puzzelstukje hoort.
margin-left: 150px;
Een extra marge aan de linkerkant, omdat de knop met de link anders over de afbeelding en tekst van de pop-up heen komt te staan, want die wordt gelijk hieronder ook naar rechts verplaatst.
#een span
De <span>'s binnen het element met id="een". Dat is er hier maar één: de <span> met de pop-up binnen li#een
, die bij het eerste puzzelstukje hoort.
left: 0;
Bij #een span is de <span> met left: -120px;
een eindje links buiten de puzzelafbeelding gezet. In dit soort smalle browservensters zouden krokodil en tekst daardoor grotendeels links buiten het venster verdwijnen. Daarom wordt left
hier aangepast.
Dit heeft alleen effect op <span>'s die zijn gepositioneerd. Bij li > span zijn de <span>'s die directe kinderen van de <li> zijn absoluut gepositioneerd. Dit heeft alleen effect op die <span>, de <span> waarbinnen de hele pop-up zit. Omdat dieper geneste <span>'s niet zijn gepositioneerd, negeren die dit gewoon.
css voor vensters smaller dan 470 px of lager dan 570 px
@media screen and (max-width: 470px), (max-height: 570px)
De opbouw van deze regel staat gedeeltelijk beschreven bij @media screen and (orientation: landscape) and (max-height: 350px). Omdat er wat nieuwe dingen in staan, die in die regel niet staan, worden delen van de regel hieronder ook summier beschreven.
@media
: precies hetzelfde als bij de eerder genoemde regel.
screen
: idem.
and
: idem.
(max-width: 470px)
: het browservenster mag niet breder dan 470 px zijn.
,
: een komma. Dit is het grootste verschil met de eerdere regel. Een komma betekent in een media querie: 'of'. De css hieronder is geldig als het venster niet breder is dan 470 px, óf als het venster niet hoger is dan 570 px. Als het venster 47.000 px breed is, maar 569 px hoog, valt het venster onder deze regel. Ondanks de openluchtfilmbreedte.
(max-height: 570px)
: het browservenster mag niet hoger zijn dan 570px.
#twee:focus a, #twee:hover a, #twee a:focus
Als de tweede <li> focus heeft, of als over de tweede <li> (het tweede puzzelstukje) wordt gehoverd, of als de tweede <a> focus heeft, toon dan de knop met de link.
top: 10px; left: 100px;
Bij #twee:focus a, #twee:hover a, #twee a:focus wordt de knop met de link neergezet op top: 26px; left: 130px;
. Hieronder wordt de <span> met de pop-up verplaatst en verkleind. Daarom moet de positie van de knop met de link worden aangepast, zodat deze goed staat ten opzichte van de pop-up met de dansende letters.
#twee > span
Alle <span>'s die een direct kind van een het element met id="twee" zijn. Dat is er hier maar een, waarbinnen de pop-up zit.
Het teken >
geeft aan dat het om directe kinderen moet gaan:
<li id="twee">
<span></span>
</li>
In onderstaande code is de buitenste <span> een direct kind, waarvoor deze selector dus geldt. De binnenste <span> is geen direct kind van de <li>, maar van de buitenste <span>, dus daarvoor geldt deze selector niet:
<li id="twee">
<span>
<span></span>
</span>
</li>
top: -80px;
Bij #twee span wordt de <span> met top: 0;
bovenin li#twee
geplaatst. Hier gelijk onder wordt de <span> fors verkleind met scale(0.6)
. Dat verkleinen gebeurt vanuit het middelpunt van het te verkleinen element, waardoor de bovenkant van de <span> lager komt te staan. En de bij de pop-up horende knop nu eenzaam en alleen staat te treuren op, voor een muis, onbereikbare hoogte.
Door de pop-up hoger te plaatsen, wordt dit voorkomen.
(Je kunt ook bij transform
opgeven dat de schaling vanaf bijvoorbeeld de bovenkant moet plaatsvinden, maar dit vind ik simpeler.)
-ms-transform: scale(0.6); -webkit-transform: scale(0.6); transform: scale(0.6);
Hier staat in feite drie keer hetzelfde: transform: scale(0.6);
. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms- en -webkit-.
transform
is een eigenschap om van alles aan te passen. Hier wordt de transform-functie scale()
gebruikt: schalen in beide richtingen: horizontaal en verticaal. In dit geval wordt tot zes tiende verkleind. Omdat maar één getal is opgegeven, wordt in beide richting evenveel geschaald.
In zulke kleine browservensters is er te weinig ruimte voor de pop-up van het tweede puzzelstukje. Daarom wordt de pop-up stevig verkleind. Omdat de dansende letters nogal groot zijn, kan dat zonder de leesbaarheid aan te tasten.
css voor vensters smaller dan 380 px of lager dan 540 px
@media screen and (max-width: 380px), (max-height: 540px)
De opbouw van deze regel staat beschreven bij @media screen and (max-width: 470px), (max-height: 570px). Er zijn twee verschillen: de maximumbreedte is hier 470 px en de maximumhoogte 570 px.
#negen:focus a, #negen:hover a, #negen a:focus
Als de negende <li> focus heeft, of als over de negende <li> (het negende puzzelstukje) wordt gehoverd, of als de negende <a> focus heeft, toon dan de knop met de link.
top: -50px; left: 30px;
Bij #negen:focus a, #negen:hover a, #negen a:focus wordt de knop met de link neergezet op top: -25px; left: -8px;
. Hieronder wordt de <span> met de pop-up verplaatst en verbreed. Daarom moet de positie van de knop met de link worden aangepast, zodat deze goed staat ten opzichte van de pop-up met de tekst.
#negen:focus > span, #negen:hover > span, #negen a:focus + span
Deze selectors openen de pop-up bij het negende puzzelstukje. Hoe ze precies werken, is te vinden bij #negen:focus > span, #negen:hover > span, #negen a:focus + span.
width: 250%;
Bij #negen > span is een breedte van 200% opgegeven. Dat is in deze smalle browservensters te weinig.
top: -120px;
Een groot deel van de tekst zou wegvallen in deze lagere vensters, daarom wordt de pop-up een stuk omhoog gezet.
left: -160%;
Bij #negen:focus > span, #negen:hover > span, #negen a:focus + span is de <span> met de pop-up op left: -120%;
gezet. Hier wordt de pop-up meer naar links gezet, zodat er meer binnen het browservenster past.
JavaScript
De code is geschreven in een afwijkende
lettersoort. De code die te maken heeft met de basis van dit voorbeeld (essentiële code) is in de hele uitleg onderstippeld blauw
. Alle niet-essentiële code is bruin
. (In de inhoudsopgave staat alles in een gewone letter vanwege de leesbaarheid.)
Beide stukjes JavaScript hieronder zijn alleen nodig voor iOS. In principe werkt het menu niet op iOS, als JavaScript uitstaat. Maar dat zal niet snel gebeuren, omdat je dan niet veel meer hebt dan een groot uitgevallen (en peperduur, want Apple) horloge.
<div id="wrapper" onclick="">
Op iOS werkt aanraken van de <li> niet, het heeft geen enkel effect. Er is al jarenlang discussie over de oorzaak hiervan. En er zijn tal van oplossingen, die volgens anderen dan weer niet altijd werken. Omdat Apple ongeveer even open is over de werking van iOS als de staatsloterij vóór de trekking over het nummer van het winnende lot, zal wel altijd onduidelijk blijven, hoe dit komt.
(Vraag aan statistici: waarom is het enthousiasme van Applefans recht evenredig met de geslotenheid van Apple? Bestaat daar een of andere statistische verklaring voor? Of kan ik deze vraag beter aan een in vreemde verschijnselen gespecialiseerde antropoloog stellen?)
In dit geval lost een simpele onclick=""
bij #wrapper
het op:
<div id="wrapper" onclick="">
Nu werkt aanraken van de puzzel wel.
Verder heeft dit geen enkel effect. onclick
is een stukje JavaScript: doe iets als er wordt geklikt op dit element. En 'klikken' moet hier dan worden gelezen als 'aanraken'. En wat moet er dan worden gedaan? Dat staat achter het isgelijkteken: ""
. Noppes. Niets. Nada. Blijf lekker in bed liggen vandaag. Doe vooral niets en bemoei je er verder niet mee. Maar waar het om gaat: er wordt nu geluisterd naar mogelijke aanrakingen, en die werken nu op de hele div#wrapper
, en daarmee op de hele puzzel.
Een enigszins onverwachte bijwerking van dit minieme stukje JavaScript is de uitwerking op focus. Op iOS houdt een element na aanraking focus, tot er een ander element dat focus kan krijgen wordt aangeraakt. Dat andere element krijgt dan focus, en het eerste element (hier de <li>) verliest de focus, waardoor de pop-up sluit. Zolang een <li> focus heeft, blijven bijbehorende knop en pop-up geopend.
Als je het scherm buiten een <li> aanraakt, is er niets dat focus kan krijgen en blijven knop en pop-up gewoon zichtbaar, omdat de <li> focus houdt.. De enige manier om een pop-up te sluiten is het aanraken van een andere <li>. Maar dan opent daar de pop-up van. En is niet meer te sluiten.
Door de onclick
bij div#wrapper
blijkt ook dit opgelost: waar je het scherm nu ook aanraakt, de pop-up en knop sluiten.
<script>
document.getElementsByTagName("body")[0].addEventListener("touchstart", function () {return null;});
</script>
Het tweede stukje JavaScript dat nodig is.
<script>
en </script>
Dit is gewone html: het zijn de openings- en sluittag voor het script. In html5 is de toevoeging type="text/javascript"
niet meer nodig.
Het eigenlijke JavaScript is tamelijk simpel. Ik ga er niet al te diep op in, want deze site gaat uiteindelijk niet over JavaScript, maar over css.
document.getElemtsByTagName("body")[0]
Zoek naar alle elementen die 'body' heten. Aangezien 'n computer niet echt slim is, weet de ziel niet dat je per definitie maar één 'body' hebt. Van deze elementen wordt een soort lijstje gemaakt. In dit geval dus een 'lijstje' met één deelnemer. Elk element van dat lijstje krijgt een volgnummer. En een computer begint graag te tellen met '0': ziedaar de '0' uit [0]
binnen komen wandelen.
In normale mensentaal: maak een lijstje met alle <body>'s, en gebruik daarvan de eerste.
In nog normalere mensentaal: doe iets met <body>.
addEventListener
En wat moet het ding dan doen met de body? Heel preuts aangelegde mensen kunnen nu beter stoppen met lezen, want het gaat hier verder over geheimzinnige aanrakingen van de body en zo, die ook nog 'ns worden afgeluisterd door 'n soort gluurder. U bent gewaarschuwd.
Er wordt een zogenaamde 'eventlistener' toegevoegd aan <body>. Dat is een ding dat luistert of er iets gebeurt. Zo'n gebeurtenis kan een toetsaanslag zijn, een beweging van de muis, een liefdevolle aanraking met de vinger, van alles.
"touchstart"
In dit geval is de gebeurtenis, waarnaar wordt geluisterd, 'touchstart'. Het begin van een aanraking. Over het einde van de aanraking ga ik het niet hebben, dat is te privé. Maar het bestaat wel, ook in JavaScript.
'touchstart' registreert het begin van een aanraking. In dit geval als iemand (of iets) het scherm van de tablet, smartphone, of wat dan ook aanraakt.
function () {return null;}
En hier dan wat er gebeurt na de aanraking. function()
is gewoon een soort aankondiging dat er iets gaat gebeuren. Erachter tussen de accolades staat, wat er gaat gebeuren. Voor degenen die echt op onkuise dingen hadden gehoopt: dat gaat tegenvallen.
return null
wil zeggen dat er helemaal niets gebeurt. Echt niets. Het is ongeveer het JavaScript-equivalent van: "Sorry schat, ik heb hoofdpijn vanavond" als reactie op een aanraking.
Bij de uitleg van deze code zijn allerlei haakjes en dergelijke weggelaten, want dat voert hier te ver. Als je je in dat soort dingen wilt verdiepen, kun je beter naar sites gaan die meer voor JavaScript zijn bedoeld.
Vanwaar deze hele exercitie die eindigt met een volstrekt nietsdoen? Vanwege iOS.
Omdat hoveren op een touchscreen niet mogelijk is, maar er al miljoenen websites bestaan die dat wel gebruiken, moesten de makers van touchscreens daar iets mee. Zonder meer hoveren negeren was onmogelijk, omdat bijvoorbeeld heel veel menu's dan niet meer zouden werken. Als je iets nieuws op de markt brengt, maar vrijwel geen enkele website werkt nog, is dat commercieel gezien misschien niet zo handig.
Ook in dit voorbeeld wordt :hover
gebruikt: op de <li>'s die al in gebruik zijn. Op diverse plaatsen in de css staan varianten op li:hover
.
Het eerste probleem: op iOS blijft een :hover
geopend. Op de desktop sluit een pop-up weer, als de muis het voor hoveren gevoelige deel verlaat, op iOS niet. En ook niet zonder meer als je op 'n andere plek het scherm aanraakt.
Daarnaast wordt op diezelfde <li>'s ook gewerkt met focus: li:focus
. Dat zijn dus twee verschillende dingen op hetzelfde element. Als je met een muis of toetsenbord werkt, is dat geen probleem. Op een touchscreen kan het dat wel zijn.
Dit scriptje zorgt ervoor, dat de pop-ups bij een eerste aanraking buiten de pop-up gelijk weer sluiten, en niet pas bij een tweede aanraking.
Omdat het script aan <body> is gekoppeld, werkt het in het hele browservenster. Dat zal bij een touchscreen normaal genomen hetzelfde zijn als het hele scherm.
Hoe het precies werkt, weet ik niet. Maar het werkt wel. Ik heb wel wat vage ideeën over de werking, maar zeker weten, nee. Als je gaat zoeken op internet kom je bij tien mensen twintig verhalen met dertig verklaringen en veertig tegenwerpingen tegen. En Apple zelf doet volstrekt geheimzinnig over dit soort dingen. (Sorry Applefans, dat is natuurlijk geen probleem. Dat is juist fantastisch van Apple! Dat ik dat nou toch niet wil begrijpen...)