Skip links en inhoudsopgave

Hover over een van de thumbnails naast de tekst en de bijbe­horende grote afbeelding verschijnt - uitleg

Laatst aangepast: .

Afbeelding 1: weergave van thumbnails en grote afbeeldingen in vensters van verschillende grootte

Korte omschrijving

Als je met de cursor boven ’n thumbnail komt, ’n thumbnail aanraakt, op ’n thumbnail klikt of naar ’n thumbnail tabt, opent de bijbehorende grote afbeelding.

BELANGRIJK

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

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

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

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

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

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

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

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

Opmerkingen

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

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

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

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

Achterliggend idee

Omdat oudere versies van Internet Explorer niet meer worden ondersteund, kon de code voor dit voorbeeld een heel stuk worden verbeterd.

Op een pagina staat aan de linkerkant tekst. Rechts staan dertien kleine afbeeldingen, zogenaamde ’thumbnails’. (Een Nederlandse vertaling als ’miniatuur’ is nooit echt in gebruik geraakt, dus ik blijf ook het algemeen gebruikte ’thumbnail’ gebruiken.) Die afbeeldingen horen niet bij een bepaald onderdeel van de tekst, het is gewoon een kolom afbeeldingen rechts van de tekst.

In browservensters smaller dan 340 px staan de thumbnails niet naast, maar onder de tekst. In zulke smalle vensters is er domweg niet genoeg ruimte om naast de tekst nog afbeeldingen neer te zetten.

De tekst links staat in een aantal <p>’s, die samen in een <div> staan. Omdat alle tekst in één gemeenschappelijke <div> staat, kan de breedte van alle tekst simpel worden veranderd door de breedte van die <div> aan te passen.

Afbeelding 2: de achtergrond-afbeelding met alle thumbnails

Als de dertien kleine afbeeldingen rechts van de tekst echt dertien losse afbeeldingen zouden zijn, zouden er dertien aanroepen naar de server moeten worden gedaan. Iets wat relatief veel tijd kost.

In werkelijkheid zijn de dertien thumbnails dan ook geen dertien kleine afbeeldingen, maar is het één grote achtergrond-afbeelding, waarop dertien kleinere afbeeldingen zijn gemonteerd. Dat spaart 12 aanroepen naar de server uit. Zo’n grote afbeelding die bestaat uit een aantal kleinere afbeeldingen, heet een ’sprite’.

Rechts op de pagina, op de plaats waar de thumbnails staan, staat een <div>. Binnen deze <div> staan weer dertien <div>’s, één voor elke thumbnail.

Binnen elk van deze dertien <div>’s zitten twee <span>’s.

De eerste <span> wordt veranderd in een blok-element en krijgt dezelfde hoogte en breedte als de bijbehorende thumbnail. Deze thumbnail wordt als achtergrond-afbeelding in de <span> gezet. Alle thumbnails staan op één grote afbeelding, maar met behulp van background-position kan de juiste thumbnail in de juiste <span> worden gezet.

Door afrondingsverschillen kan bij in- of uitzoomen de thumbnail net 1 px kleiner worden dan de bijbehorende <span>. Daarom is een kleine ruimte tussen de thumbnails opengelaten, zodat wordt voorkomen dat in zo’n geval 1 px van de onder‑ of bovenliggende afbeelding zou verschijnen. De achtergrond van de grote afbeelding is doorzichtig, dus je ziet in zo’n geval gewoon niets in dat kiertje.

(De ruimte tussen de thumbnails is 10 px, omdat dat makkelijker monteerde. De grootte van het bestand neemt hierdoor nauwelijks toe. En omdat dat verder niets uitmaakt, is de ruimte soms – o schandelijke slordigheid – 9 of 11 px. Een van de zeldzame gevallen waarin des duivels oorkussen ledigheid oplevert.)

De tweede <span> binnen elk van de dertien <div>’s bevat een tekst die onder de <span> met de thumbnail komt te staan.

In browservensters breder dan 340 px zijn de dertien <div>’s met behulp van :hover en :focus gevoelig gemaakt voor hoveren met de muis, klikken, aanraken en focus. Bij een van deze gebeurtenissen wordt met behulp van ::after een pseudo-element geopend, waarin een grotere versie van de thumbnail wordt weergegeven. Ook dit is weer een achtergrond-afbeelding. Door het geven van een tabindex aan de dertien <div>’s kunnen ook gebruikers van de Tab-toets de grote afbeeldingen openen.

Op iOS is een miniem stukje JavaScript nodig, omdat aanraken daar anders geen effect heeft. Als JavaScript uit staat, heb je nauwelijks iets aan iOS. Dat daar wat JavaScript nodig is, zal dus geen probleem zijn.

Pas als :hover of :focus bij de <div> boven de thumbnail wordt geactiveerd, krijgt het met ::after gemaakte pseudo-element een achtergrond-afbeelding. Daardoor wordt de grotere afbeelding pas gedownload, als deze daadwerkelijk wordt getoond. Zou je de achtergrond-afbeelding op de normale manier aan de element geven, of als je <img> zou gebruiken in plaats van background-image, dan zouden alle grote afbeeldingen gelijk bij openen van de pagina worden gedownload, ook als je ze verbergt met behulp van display: none; of zoiets. Nu worden alleen de grote afbeeldingen gedownload, die daadwerkelijk moeten worden getoond.

Als een browservenster breder is dan 340 px, maar te laag of te smal om de foto volledig te tonen, wordt de afbeelding verkleind. Hierdoor kan de afbeelding zo groot mogelijk worden weergegeven, maar zonder dat delen van de afbeelding buiten het venster van de browser verdwijnen.

Op een hogeresolutiescherm is een veel betere kwaliteit afbeelding mogelijk. Daarom zijn van elke grote afbeelding twee stuks aanwezig: eentje van 480 x 360 px voor gewone beeldschermen en eentje van 960 x 720 px voor hogeresolutieschermen. Meer hierover is te lezen bij Hogeresolutieschermen.

Hogeresolutieschermen

Vaak wordt dit soort schermen Retina-schermen genoemd, maar Retina is gewoon de merknaam van Apple voor een hogeresolutiescherm.

Er komen steeds meer apparaten met een hogere resolutie, dan op de desktop gebruikelijk is: meer dpi, dots per inch. Van oudsher wordt helaas ’inch’ gebruikt als eenheid. Een nieuwere eenheid is dpcm: dots per centimeter. De beste eenheid voor het meten van de resolutie van een computerscherm is dppx: dots per px unit, maar deze wordt nog lang niet overal ondersteund. 1 dppx is even groot als 96 dpi, de standaardresolutie van een gewone desktop monitor (Apple had een iets andere dpi).

Als je meer pixels in een inch stopt, waardoor de pixels dichter op elkaar staan, krijg je fijnere afbeeldingen. Vooral bij ronde lijnen en dergelijke is dit goed te merken. Een ronde lijn die wordt weergegeven met 72 px per inch is grover, dan diezelfde lijn die met 300 px per inch ordt weergegeven.

Een lijn die op een normale desktopmonitor 4 px breed is, zou op zo’n hogeresolutiescherm van 300 dpi maar 1 px breed zijn. Superduidelijk, dat wel, maar zonder vergrootglas niet te zien. Omdat de pixels vier keer zo dicht op elkaar staan. Bestaande sites die vier (of meer) keer zo klein worden weergegeven, als waar ze voor bedoeld zijn, maken alleen opticiens vrolijk.

Althans: je zou die kleinere weergave op een hogeresolutiescherm verwachten. Maar gelukkig wordt dat voorkomen. Apparaten met een hogeresolutiescherm geven een ’valse’ resolutie op. Een iPad met een hogeresolutiescherm geeft niet het aantal ’schermpixels’ op, maar het aantal ’css-pixels’. En dat is hetzelfde als bij een ’normale’ desktopmonitor. Hierdoor ziet een site er op een iPad hetzelfde uit als op een desktopmonitor.

Niet alleen de iPad heeft dit handigheidje, alle hogeresolutieschermen doen dit. Anders zouden ze volstrekt onbruikbaar zijn voor heel veel sites.

Met behulp van media queries kun je testen op onder andere de resolutie. Dit geeft de mogelijkheid naar hogeresolutieschermen afbeeldingen van een hogere kwaliteit te sturen, terwijl je voor gewone beeldschermen afbeeldingen van mindere kwaliteit kunt gebruiken. Dat is belangrijk, omdat die afbeeldingen van hogere kwaliteit (veel) groter zijn in omvang. Door te testen op resolutie, kun je naar een gewoon beeldscherm de veel kleinere afbeeldingen van mindere kwaliteit sturen.

Helaas zijn er nogal wat sites die dit testen op resolutie doen op een manier, die alleen werkt op een iPad/iPhone en in Safari. Door dat te doen werk je mee aan de kans op net zo’n monopolie, als Internet Explorer ooit had. Dat heeft ons jarenlang grote ellende opgeleverd. Het lijkt me niet handig om dat nog eens te gaan herhalen met Apple, temeer niet omdat Apple zich steeds meer als een gediplomeerd patenttrol begint te gedragen en veelbelovende pogingen doet Microsoft van de troon te stoten als meest onsympathiek bedrijf in de ICT.

In de vorige versie van dit voorbeeld zat bij elke thumbnail maar één grote afbeelding. Hier zijn dat er twee: eentje van 480 x 360 px (of 360 x 480 px voor een staande afbeelding) en eentje van 960 x 720 px (of 720 x 960 px voor een staande afbeelding). Beide afbeeldingen zijn volledig hetzelfde, alleen de afmetingen verschillen. De grotere afbeeldingen eindigen allemaal op ’-2x.jpg’, de kleinere missen het ’-2x’ en eindigen op ’.jpg’.

Het verhaal hieronder is een stuk simpeler, dan het in werkelijkheid is. Dat heeft twee redenen: ik wil het niet te ingewikkeld maken, en ik ben zelf ook geen expert op het gebied van afbeeldingen. Dingen als (lossless) comprimeren, anti-aliasing en subpixels bijvoorbeeld, laat ik buiten beschouwing. Kennis daarvan is ook niet echt nodig voor dit voorbeeld.

Een jpg-afbeelding – het hier gebruikte formaat – is een zogenaamde bitmap-afbeelding. Wat voor het oog mooie, in elkaar overlopende kleuren en soepele rondingen zijn, bestaat in feite helemaal niet. Het zijn kleine blokjes, die alleen maar zo soepel en vervloeiend zijn, omdat ogen makkelijk voor de gek te houden zijn.

Hieronder staat een stukje van een detail van een vleugel op de zevende foto, vijftien keer vergroot. Dat mooie ronde adertje (of hoe dat ook heet bij ’n insect) blijkt opgebouwd te zijn uit ’n verzameling rotsblokken, waar Stonehenge nog iets van kan leren. Maar als je deze rotspartij niet vergroot, blijkt het er op een beeldscherm prima uit te zien. Omdat mensenogen gewoon niet zo goed zijn.

Althans: tot voor niet zo heel lang geleden zag het er overal mooi uit.

Afbeelding 3: bij sterk vergroten van een foto worden de blokjes zichtbaar

Bij een gewoon beeldscherm komt één blokje op de afbeelding hierboven ongeveer overeen met één dot op de monitor. En omdat je oog zo makkelijk kan worden genept, lijkt dit ’n echte weergave van de werkelijkheid en zie je de aparte dots niet.

Een gewoon beeldscherm heeft meestal 96 dots per inch, oftewel 96 dpi. Een Apple-beeldscherm heeft er 72 per inch.

(Op papier is je oog trouwens minder goed voor de gek te houden, daarom zijn voor een afdruk ruwweg vier keer zoveel dots nodig voor een enigszins acceptabele kwaliteit. Daardoor zijn veel afbeeldingen op internet eigenlijk niet af te drukken: ze bevatten gewoon te weinig pixels voor een kwalitatief goede papieren afdruk.)

En toen kwamen er hogeresolutieschermen. Een hogeresolutiescherm heeft meer dpi, meer dots per inch. Meestal is dat nu nog niet meer dan twee keer zoveel als een gewoon beeldscherm, maar er zijn ook nog hogere resoluties.

Als een scherm een resolutie, een dichtheid, van bijvoorbeeld 200 dpi heeft, is dat ongeveer twee keer zoveel als de resolutie van een gewoon beeldscherm. De dots staan twee keer zo dicht op elkaar, waardoor je veel fijnere details kunt weergeven. Maar die arme afbeelding kan dat helemaal niet aan, want die is bedoeld voor een gewoon beeldscherm met 96 dpi. Op zo’n gewoon beeldscherm zit in de afbeelding voor elke dot op het beeldscherm ongeveer ’n eigen pixel in de afbeelding, waardoor beeldscherm en afbeelding goed op elkaar aansluiten en samen een gelukkige relatie hebben. Op een hogeresolutiescherm merkt de tot dan gelukkige afbeelding opeens dat hij te weinig pixels heeft om het hogeresolutiescherm tevreden te stellen, waardoor de relatie tussen afbeelding en beeldscherm opeens een stuk minder goed wordt. En de weergave van de afbeelding slechter.

Je zou dit kunnen oplossen door de afbeelding twee (of bij nog hogere resoluties drie, vier, ...) keer zo klein weer te geven. Dan vallen de pixels binnen de afbeelding weer gelijk met de dots op het beeldscherm. Dat heeft alleen één niet geheel onbelangrijk nadeel: de afbeelding is weliswaar mooi scherp, maar wel twee (drie, vier, ...) keer zo klein, omdat de pixels dichter bij elkaar staan. Want het aantal pixel in de afbeelding neemt niet op wonderbaarlijke wijze toe.

Als alle afbeeldingen opeens twee (drie, vier, ...) keer zo klein zouden worden op een hogeresolutiescherm, zou dat een ramp zijn voor alle bestaande websites. Geen foto zou nog zonder vergrootglas te bekijken zijn. En hogeresolutieschermen zouden niet verkocht worden, want wat heb je aan zo’n fantastisch scherm, als je ’n vergrootglas nodig hebt om iets te kunnen zien.

Daarom is voor een andere oplossing gekozen: de afbeelding wordt even groot weergegeven als op een gewoon beeldscherm. Waardoor bij een resolutie van 200 dpi van het beeldscherm en een resolutie van 96 dpi van de afbeelding gewoon de helft van de pixels ontbreekt. Die bestaat gewoon niet. De browser probeert die missende pixels zelf aan te vullen. Dat gaat nog niet eens zo slecht, maar het eindresultaat is toch merkbaar slechter, dan wanneer de afbeelding zelf een hogere resolutie zou hebben.

De browser zet als het ware tussen elke twee pixel van de afbeelding één nieuwe pixel, waarbij zo goed mogelijk wordt geraden, welke kleur die pixel moet hebben. Maar als een detail heel fijn is, zoals iets hieronder op de afbeelding bij de adertjes in de vleugel, kan de browser die heel fijne details niet spontaan fabriceren. Omdat die hele fijne adertjes stomweg ontbreken in de afbeelding.

Je kunt dit probleem oplossen door alleen nog hogeresolutie-afbeeldingen te gebruiken. Maar daar maak je je niet populair mee, want dan downloadt een piepkleine smartphone een joekel van een afbeelding in superkwaliteit, geschikt voor een breedbeeldbeeldscherm .

De oplossing bestaat uit het gebruiken van meerdere afbeeldingen. Dat is iets meer werk, maar ook weer niet zoveel, omdat het om ’n vrij simpele handeling gaat, die je zelfs kunt automatiseren voor ’n hele serie afbeeldingen.

De afbeeldingen die eindigen op -2x.jpg hebben een afmeting van 960 x 720 px. De andere afbeeldingen hebben een afmeting van 480 x 360 px. Afgezien van de afmetingen zijn ze verder precies hetzelfde. Als je nou een afbeelding van 960 px breed weergeeft op een breedte van 480 px, dan heb je opeens twee keer zoveel px op dezelfde ruimte. Oftewel: ongeveer dezelfde resolutie als een hogeresolutiescherm van 200 dpi.

Afbeelding 4
Afbeelding 4: een detail uit de zevende afbeelding. Links de afbeelding van 480 x 360 px, rechts die van 960 x 720 px. Hoewel de rechterafbeelding zelfs nog iets meer is vergroot dan de linker, zijn de details van de vleugel toch veel beter te zien.

Op de afbeelding hiernaast is het enige verschil tussen de afbeeldingen de afmeting. Als je ze niet zou vergroten of verkleinen, is de rechterafbeelding twee keer zo groot als de linker. De rechterafbeelding is echter wel verkleind, waardoor deze een hogere resolutie, meer dpi, heeft gekregen. Het verschil in kwaliteit is duidelijk zichtbaar: op de linkerafbeelding zijn de fijnere lijntjes binnen de vleugel stomweg afwezig. En wat niet aanwezig is, kan ook niet worden weergegeven door de browser, ook al doet deze nog zo haar best.

Voor een gewoon beeldscherm is de kwaliteit van de linkerafbeelding goed genoeg, want dat beeldscherm is toch niet in staat de fijne lijntjes weer te geven. Een hogeresolutiescherm kan dat wel.

Als je op een hogeresolutiescherm een afbeelding van 960 x 720 px en een afbeelding van 480 x 360 px naast elkaar op een breedte van 480 px bekijkt, zie je duidelijk verschil in kwaliteit. Beide afbeeldingen worden op een grootte van 480x360 px weergegeven, dus de grote afbeelding heeft in hoogte en breedte twee keer zoveel pixel ter beschikking en kan dus beter details weergeven. Die alleen op een hogeresolutiescherm te zien zijn, omdat een gewoon scherm stomweg te grof is om die details weer te geven. Het verschil in kwaliteit komt ruwweg overeen met het verschil in beide afbeeldingen iets hierboven.

Je kunt je afvragen, waarom dan niet altijd de beste kwaliteit afbeelding wordt gebruikt. Dat heeft te maken met de grootte van de bestanden. Elke pixel in een afbeelding is opgebouwd uit drie kleuren: rood, groen en blauw. Elk van die drie kleuren kan 256 mogelijke waarden hebben: van volledig ontbrekend tot volledig aanwezig (knalrood bijvoorbeeld). Samen kunnen deze drie kleuren op 256 x 256 x 256 = 16.777.216 manieren worden gecombineerd. Dat levert 16.777.216 mogelijke kleuren op, ruim voldoende voor het menselijk oog. Van volledig wit (drie keer nul) tot volledig zwart (drie keer 255. 255, want een computer begint bij nul te tellen).

Voor elke pixel in de afbeelding zijn drie bytes nodig: eentje voor elke kleur. Een afbeelding van 100 x 100 px heeft daardoor een bestandsgrootte van 3 x 100 x 100 = 30.000 byte, oftewel 30 kB (kilobyte).

Een afbeelding van 200 x 200 px, twee keer zo groot als een afbeelding van 100 x 100 px, heeft een bestandsgrootte van 3 x 200 x 200 = 120.000 byte, 120 kB. Dat is vier keer zoveel. En dat moet allemaal worden gedownload. Als de monitor toch niet in staat is die kwalitatief betere afbeelding goed weer te geven, is het zinloos die te downloaden en kun je beter de kwaliteit downloaden die bij de monitor past. Dat gaat (veel) sneller en is, als je moet betalen voor de bandbreedte, (veel) goedkoper.

(Als iemand dit nou gaat uitproberen met twee afbeeldingen, dan blijkt bovenstaande niet te kloppen. Door slimme compressiemethoden is een bestand uiteindelijk (veel) kleiner, dan je zou verwachten. Als je bijvoorbeeld een effen blauw vlak van 30 x 30 px hebt, is een regel als ’geef een blauw vlak weer van daar naar daar’ veel efficiënter dan het opslaan van 30 x 30 x 3 = 2700 byte.)

In dit voorbeeld wordt met behulp van media queries opgevraagd, wat voor soort scherm de computer heeft. Als dat een hogeresolutiescherm is, wordt de grote afbeelding gedownload (en heel gedetailleerd twee keer verkleind weergegeven op een grootte van 480 x 360 px). Bij een gewoon beeldscherm wordt de kleinere afbeelding van 480 x 360 px gedownload.

Eigenlijk zou ook de achtergrond-afbeelding met de thumbnails op een hogeresolutiescherm twee keer zo groot moeten zijn als op een gewoon scherm. Ik heb dat niet gedaan, omdat het maar om ’n soort voorvertoning van de grote afbeelding gaat. Omdat die thumbnails zo klein zijn, kun je toch geen details zien, hoge resolutie of niet.

Als het browservenster smaller of lager is dan de grote foto, wordt de foto verkleind tot deze in het venster vast. Dat verkleinen levert geen problemen voor de kwaliteit op, want browsers kunnen dat wel goed.

In de (niet al te verre?) toekomst kan de css trouwens ’n heel stuk worden ingekort, omdat je dan gelijk bij background-image zelf kunt opgeven, welke afbeelding moet worden gedownload. Hiervoor zijn dan geen media queries meer nodig. In één van de ontwerpspecificaties voor css wordt hiervoor image-set gebruikt, maar dit wordt helaas nog nauwelijks ondersteund door browsers.

Als je beslist image-set al wilt gebruiken, kun je op internet zoeken naar een zogenaamde ’polyfill’ voor image-set. Een polyfill is een JavaScript dat zorgt dat een bepaalde eigenschap ook werkt in browsers die de eigenschap nog niet ondersteunen. Zo’n polyfill moet heel grondig getest worden, want er is nogal verschil in kwaliteit. Daarom beperk ik het gebruik van polyfills tot wat echt absoluut noodzakelijk is. En wordt er hier geen gebruik van gemaakt.

Een betrouwbare site om naar polyfills te zoeken is Modernizr/wiki/HTML5-Cross-Browser-Polyfills.

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, Safari en Android browser: -webkit-.

(Google Chrome is van webkit overgestapt op een eigen weergave-machine: blink. Blink gaat geen voorvoegsels gebruiken. Het is echter een aftakking van webkit, dus het zal nog wel even duren voor -webkit- hier helemaal uit is verdwenen. Ook Opera gebruikt 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 wordt -webkit-min-device-pixel-ratio 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.

-webkit-min-device-pixel-ratio:

Hiervoor geldt niet alles, wat hierboven is geschreven. Dit is een door Apple bedachte eigenschap, die in geen enkele specificatie voorkomt en ook niet door andere browsers wordt ondersteund of ondersteund gaat worden. Het wordt gebruikt om in media queries de resolutiedichtheid op te vragen. Andere browsers gebruiken hiervoor het wel in de specificatie voorkomende min-resolution.

Op dit moment moet je daarom nog schrijven:

(-webkit-min-device-pixel-ratio: ...), (resolution: ...)

In de toekomst kun je – als Apple zich ook eindelijk aan de standaard gaat houden – volstaan met:

(resolution: ...)

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

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

Voorlopig zijn we echter nog niet van deze voorvoegsels af. Als je ze gebruikt, gebruik dan álle varianten, en eindig met de variant zonder voorvoegsel, zoals die uiteindelijk ooit gebruikt gaat worden. Als je alleen de -webkit-variant gebruikt, ben je in feite ’n onbetaalde reclamemaker voor Apple.

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. Maar gebruikers van de Tab-toets zullen dit al hebben gedaan.

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

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

De volgorde van de Tab-toets kan worden veranderd met behulp van het 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. Of om een element bereikbaar te maken voor de Tab-toets, zoals de hierboven genoemde <div>.

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

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

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

tabindex="-1"

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

In dit voorbeeld wordt tabindex="-1" niet gebruikt.

tabindex="0"

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

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

Deze waarde wordt in dit voorbeeld gebruikt bij de <div>’s, die boven de kleine afbeeldingen staan. Dit is de html van de <div> boven de eerste kleine afbeelding:

<div id="nr-1" tabindex="0">

Door de toevoeging van tabindex="0" kan de <div> focus krijgen bij gebruik van de Tab-toets, terwijl een <div> dat normaal genomen niet kan krijgen.

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

tabindex="..."

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

Muis, toetsenbord, touchpad en touchscreen

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

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

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

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

:hover

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

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

In dit voorbeeld verschijnt, in browservensters breder dan 340 px, een grote afbeelding bij hoveren over een van de thumbnails.

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

Focus wordt hier gebruikt om de <div> boven de thumbnail bereikbaar te maken voor de Tab-toets. Daarvoor heeft elke <div> als attribuut tabindex="0" gekregen, omdat een <div> anders geen focus kan krijgen.

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 zou het kadertje veilig kunnen worden weggehaald, omdat de grote afbeelding al aangeeft, welke <div> focus heeft.

Om :hover en :focus werkend te krijgen op iOS, is een minieme hoeveelheid JavaScript nodig. Meer daarover bij JavaScript.

De code aanpassen aan je eigen ontwerp

Toegankelijkheid en zoekmachines

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

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

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

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

Enkele tips die helpen bij toegankelijkheid:

Specifiek voor dit voorbeeld

Getest in

Laatst gecontroleerd op 15 november 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 deel te lezen, want uit een test kan ook prima blijken dat iets totaal niet werkt!

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

Dit voorbeeld is getest op de volgende systemen:

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

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.

UC browser op Android en Android browser

UC browser op Android en oudere versies van Android browser kennen de eenheden vw en vh niet. In browservensters breder dan 340 px, maar te smal of te laag om de foto volledig te tonen, worden hierdoor de foto’s niet verkleind. Een deel van de foto verdwijnt hierdoor buiten het venster van de browser. De foto’s kunnen wel gescrold worden, dus op die manier zijn ze toch volledig te zien.

Als je dit een probleem vindt, kun je op internet zoeken naar een zogenaamde ’polyfill’ voor vm en vh. Een polyfill is een JavaScript dat zorgt dat een bepaalde eigenschap ook werkt in browsers die de eigenschap nog niet ondersteunen. Zo’n polyfill moet heel grondig getest worden, want er is nogal verschil in kwaliteit. Daarom beperk ik het gebruik van polyfills tot wat echt absoluut noodzakelijk is. En wordt er hier geen gebruik van gemaakt.

Een betrouwbare site om naar polyfills te zoeken is Modernizr/wiki/HTML5-Cross-Browser-Polyfills.

Validatie

De validator van w3c herkent pointer-events en calc() nog niet. Wat dus twee foutmeldingen oplevert. Ook -webkit-min-device-pixel wordt niet herkend, maar dit zal ook in de toekomst niet worden herkend, omdat dit een eigen brouwsel van Apple is.

Omdat de reden van de foutmeldingen duidelijk is, zijn ze hier verder geen probleem.

Wijzigingen

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

:

Bij in- en uitzoomen verdween er in Internet Explorer 7 tekst uit het meerregelige onderschrift bij de tweede afbeelding. Opgelost door regelhoogte toe te voegen aan .foto-tekst.

25 maart 2009:

Tekst aangepast aan de nieuw verschenen Internet Explorer 8. De code hoefde niet te worden veranderd.

2 augustus 2010:

1 augustus 2011:

Vanwege toegankelijkheid color: black; toegevoegd aan css voor body.

15 november 2015:

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.

afbeelding-017-dl.html: de pagina met het voorbeeld.

afbeelding-017.pdf: deze uitleg (aangepast aan de inhoud van de download).

afbeelding-017-inhoud-download-en-licenties.txt: een kopie van de tekst onder dit kopje (Inhoud van de download en licenties).

017-css-dl:

afbeelding-017-dl.css: stylesheet voor afbeelding-017-dl.html.

017-pics:

afbeeldingen.

De afbeeldingen die eindigen op '-2x.jpg' hebben een dubbele breedte en hoogte. Ze zijn bedoeld voor hogeresolutieschermen en browservensters met een breedte tussen 480 en 760 px.

De afbeeldingen zijn afkomstig van PD Photo.org.

De afbeeldingen zijn binnen het publiek domein geplaatst, zoals omschreven op creativecommons.org/licenses/publicdomain.

Voor buiten de VS is daar nog aan toegevoegd de Creative Commons CC0 designation, zoals omschreven op wiki.creativecommons.org/wiki/CC0_FAQ.

HTML

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

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

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

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

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

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

<!DOCTYPE html>

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

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

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

Het hier gebruikte doctype is dat van html5. Dit kan zonder enig probleem worden gebruikt: het werkt zelfs in Internet Explorer 6.

<html lang="nl">

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

<meta charset="utf-8">

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

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

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

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

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

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

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

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

Nieuwe sites of pagina’s kunnen echter wel rekening houden met de veel kleinere vensters van mobiele apparaten. Op deze pagina bijvoorbeeld worden in een smal venster de thumbnails niet naast, maar onder de tekst gezet. En in middelbrede vensters worden de grote foto’s zoveel verkleind, dat ze in het venster passen.

Maar die stomme mobiele browser weet dat niet, dus die gaat ervan uit dat ook deze pagina 980 px breed is, en verkleint die dan. Dat is ongeveer even behulpzaam als de gedienstige kelner die behulpzaam de stoel naar achteren trekt, net als jij wilt gaan zitten.

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

Een iPad in portretstand bijvoorbeeld is 768 px breed. De kreet width=device-width zegt tegen de mobiele browser dat de breedte van de weer te geven pagina gelijk is aan de breedte van het apparaat. Voor een iPad in portretstand dus 768 px.

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

<div id="nr-1" tabindex="0">

Boven elke afbeelding staat een <div>, waarbinnen <span>’s voor de thumbnail en het onderschrift zitten. Om deze <div>’s toegankelijk te maken voor gebruikers van de Tab-toets, is tabindex="0" toegevoegd. Meer daarover kun je vinden 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 blauw gekleurd. Alle niet-essentiële code is bruin. (In de inhoudsopgave staat alles in een gewone letter vanwege de leesbaarheid.)

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

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

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

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

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

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

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

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

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

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

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

Dat comprimeren kun je met de hand doen, maar er bestaan ook hulpmiddelen voor. Als je op internet zoekt naar 'css' en 'compress' of 'comprimeren', vind je tal van sites, waar je dat automatisch kunt laten doen.

(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

/* afbeelding-017-dl.css */

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

body

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

background-color: #ff9;

Achtergrondkleur.

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 in een eigen stylesheet, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.

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

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

font-size: 110%;

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

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

margin: 0; padding: 0;

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

main

Het element waar de belangrijkste inhoud van de pagina in staat. Dit element komt maar één keer voor op de pagina.

display: block;

Internet Explorer 9, 10 en 11 kennen dit element niet. Een onbekend element is standaard een inline-element, waardoor er bijvoorbeeld geen breedte aan kan worden gegeven, zoals verderop voor browservensters minimaal 340 px breed bij main gebeurt. Daarom wordt hier opgegeven dat <main> een blok-element is.

Eigenlijk hoeft dit pas verderop, waar breedte en dergelijke daadwerkelijk worden opgegeven. Hier maakt het nog niets uit. Maar voor dit soort elementen geef ik dit altijd zo vroeg mogelijk op, omdat het later makkelijk kan worden vergeten en dan in Internet Explorer tot vreemde resultaten kan leiden. Of er wordt later, bij een wijziging van de pagina, hier al een breedte of iets dergelijks opgegeven. Als je dan vergeet dit alsnog op te geven, kun je je ongans zoeken naar waarom Internet Explorer kuren heeft.

#tekst

Het element met id=”tekst”. De <div> waarbinnen alle tekst staat.

padding: 5px;

Wat afstand tussen de buitenkant van de <div> en de erin staande tekst.

#thumbs div

Alle <div>’s binnen het element met id=”thumbs”. De dertien <div>’s die boven de thumbnails staan.

margin-bottom: 10px;

Marge aan de onderkant. Hierdoor ontstaat er wat ruimte tussen het onderschrift bij een thumbnail en de daaronder staande thumbnail.

#thumbs span:first-child

Alle <span>'s binnen het element met id=”thumbs” die eerste kind zijn.

Een klein stukje van de html maakt dit hopelijk begrijpelijker:

<div id="thumbs"> <div id="nr-1"> <span></span> <span>Foto nummer 1</span> </div> (...) tot en met (...) <div id="nr-13"> <span></span> <span>Foto nummer 13</span> </div> </div>

De buitenste <div> is div#thumbs. Binnen div#thumbs staan weer dertien <div>’s: div#nr-1 tot en met div#nr-13, voor elke thumbnail een. Binnen elk van deze dertien <divs>’s staan weer twee <span>’s. De eerste van die twee <span>’s is steeds het eerste kind van een van die dertien <div>’s. Elk van de dertien <div>’s heeft zo’n <span> die eerste kind is, dus deze selector bestrijkt dertien <span>’s: eentje binnen elk van de dertien <div>’s.

Binnen deze <span>’s komen, als achtergrond-afbeelding, de thumbnails te staan.

display: block;

Een <span> is van zichzelf een inline-element en kan daarom geen hoogte, breedte, en dergelijke krijgen. Door het te veranderen in een blok-element, kan dat wel.

width: 200px; height: 150px;

Dit zijn de breedte en hoogte van ’n thumbnail. De thumbnails worden als achtergrond-afbeelding in de <span> gezet. Een achtergrond-afbeelding heeft zelf geen breedte of hoogte, maar vult alleen de achtergrond van het element waar hij in staat. Door aan de <span> deze breedte en hoogte te geven, past er precies ’n thumbnail in.

Voor de staande thumbnails worden de hoogte iets hieronder aangepast.

margin: 0 auto;

Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 auto 0 auto in de volgorde boven – rechts – onder – links. Boven en onder geen marge. Links en rechts auto, wat hier hetzelfde betekent als evenveel. Hierdoor staat de <span>, en dus de daarin zittende achtergrond-afbeelding, altijd horizontaal gecentreerd binnen de ouder van de <span>.

De ouder van deze <span>’s is een van de dertien <div>’s die boven een thumbnail staan. Normaal genomen wordt een blok-element zoals een <div>, als er geen breedte aan is opgegeven, automatisch even breed als zijn ouder. De ouder van die dertien <div>’s is div#thumb, die ook geen breedte heeft gekregen. En dus even breed wordt als z’n ouder. Dat is het blok-element <main>, die ook geen breedte heeft. De mama van <main> is het blok-element <body>: ook geen breedte gekregen. De papa (ja, ik wordt wat melig van al die familie...) is <html>: ook al een blok-element zonder breedte.

<html> is het buitenste element. Daardoor wordt <html>, als geen breedte is opgegeven, even breed als het venster van de browser. Via via worden de dertien <div>’s dus ook even breed als het venster van de browser. En omdat de <span>’s met de thumbnails horizontaal in het midden van deze <div>’s staan, staan ze automatisch ook in het midden van het venster, ongeacht hoe breed dit venster is.

Voor vensters minimaal 340 px breed wordt dit verderop veranderd.

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

#thumbs .staand span:first-child

Voor deze elementen geldt ook de eerder bij #thumbs span:first-child opgegeven css, voor zover die hier niet wordt gewijzigd.

De <span>’s die eerste kind zijn en binnen elementen met class=”staand” zitten, die weer binnen het element id=”thumbs” zitten. Deze selector is precies hetzelfde als die hierboven bij #thumbs span:first-child. Alleen is hier .staand toegevoegd: de <span>’s die eerste kind zijn en binnen een element met class=”staand” zitten, die weer binnen het element met id=”thumbs” zitten. Dit zijn de <span>’s die bij de vierde en achtste thumbnail horen en binnen div#nr-4 en div#nr-8 zitten. Alleen deze twee <div>’s hebben een class=”staand”.

height: 267px;

De staande thumbnails zijn hoger dan de andere, liggende thumbnails.

#thumbs span:last-child

De <span>’s die laatste kind zijn en binnen het element met id=”thumbs” liggen.

Deze selector werkt precies hetzelfde als die bij #thumbs span:first-child iets hierboven, alleen moet de <span> hier niet het eerste, maar het laatste kind zijn. Dat is de tweede <span> binnen de <div>’s die boven de thumbnails staan. Omdat in die <div>’s slechts twee <span>’s zitten, is de tweede <span> altijd het laatste kind. In deze <span> komt het onderschrift onder de thumbnails te staan.

background: white;

Witte achtergrond.

display: block;

Een <span> is van zichzelf een inline-element en kan daarom geen breedte en dergelijke krijgen. Door het te veranderen in een blok-element, kan dat wel.

width: 192px;

Breedte.

De thumbnails zijn 200 px breed. Hieronder wordt links en rechts een padding van 3 px en een border van 1 px opgegeven. De totale breedte van de <span> met het onderschrift wordt dan 1 + 3 + 192 + 3 + 1 = 200 px, even breed als de thumbnail.

text-align: center;

Tekst horizontaal centreren.

border: black solid 1px;

Randje.

border-radius: 0 0 5px 5px;

Rechts- en linksonder ronde hoeken.

padding: 0 3px;

Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 3px 0 3px in de volgorde boven – rechts – onder – links.

Links en rechts wat afstand tussen de buitenkant van de <span> en de tekst erin. Boven en onder is dat niet nodig, omdat er altijd al wat ruimte aan de boven- en onderkant van tekst is.

margin: 0 auto;

Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 auto 0 auto in de volgorde boven – rechts – onder – links. Boven en onder geen marge. Links en rechts auto, wat hier hetzelfde betekent als evenveel. Hierdoor staat de <span> en daarmee de erin zittende tekst altijd horizontaal gecentreerd, net als de erboven staande thumbnail.

Een uitgebreider verhaal hoe dit werkt is te vinden bij margin: 0 auto;.

#nr-1 span:first-child

Voor dit element geldt ook de eerder bij #thumbs span:first-child opgegeven css.

De <span> die het eerste kind is van het element met id=”nr-1”. De eerste <span> binnen de <div> die bij de eerste thumbnail hoort. In deze <span> komt de eerste thumbnail als achtergrond-afbeelding te staan. De grootte van de <span> en dergelijke is al opgegeven bij #thumbs span:first-child.

background: url(../017-pics/thumbnails.png);

’thumbnails.png’ is een grote afbeelding, waarop dertien kleinere thumbnails zijn gemonteerd. (Een afbeelding hiervan is te zien bij Als de dertien kleine afbeeldingen...)

De thumbnail die in de bovenste <span> moet komen, staat helemaal bovenaan de grote afbeelding. Daarom kan deze zonder meer als achtergrond-afbeelding worden neergezet.

(Door de dertien thumbnails op één grote afbeelding te monteren, een zogenaamde ’sprite’, kan de afbeelding in één keer worden gedownload. Dat bespaart twaalf relatief trage aanroepen naar de server.)

#nr-2 span:first-child

Voor dit element geldt ook de eerder bij #thumbs span:first-child opgegeven css.

De <span> die het eerste kind is van het element met id=”nr-2”. De eerste <span> binnen de <div> die bij de tweede thumbnail hoort. In deze <span> komt de tweede thumbnail als achtergrond-afbeelding te staan. De grootte van de <span> en dergelijke is al opgegeven bij #thumbs span:first-child.

background: url(../017-pics/thumbnails.png) 0 -159px; Afbeelding 5: de thumbnails staan verkeerd als de achtergrond-afbeelding niet de juiste afstand naar boven wordt verplaatst

’thumbnails.png’ is een grote afbeelding, waarop dertien kleinere thumbnails zijn gemonteerd. (Een afbeelding hiervan is te zien bij Als de dertien kleine afbeeldingen...)

0 is de verplaatsing van de achtergrond-afbeelding in horizontale richting, -159px is de verplaatsing in verticale richting. Een negatieve waarde verplaatst de afbeelding naar boven.

De thumbnail die in de tweede <span> van boven moet komen, staat iets naar onderen op de grote afbeelding, onder de thumbnail die in de bovenste <span> moet komen. Daarom moet de achtergrond-afbeelding nu 159 px naar boven worden neergezet. Hierdoor komt de tweede thumbnail precies binnen deze <span> te staan.

Op de afbeelding is de achtergrond-afbeelding geen 159px, maar slechts 80 px omhoog gezet. Hierdoor staat op de plaats van de bovenste helft van de tweede thumbnail het onderste deel van de eerste thumbnail. De tweede thumbnail begint pas ongeveer halverwege, waar hij hoort te staan.

Als je de achtergrond-afbeelding geen 80, maar 159 px naar boven verplaatst, komt de tweede thumbnail precies goed te staan. Op deze manier kunnen alle dertien thumbnails op de juiste plaats worden neergezet.

#nr-3 span:first-child

Voor dit element geldt ook de eerder bij #thumbs span:first-child opgegeven css.

De <span> die het eerste kind is van het element met id=”nr-3”. De eerste <span> binnen de <div> die bij de derde thumbnail hoort. In deze <span> komt de derde thumbnail als achtergrond-afbeelding te staan. De grootte van de <span> en dergelijke is al opgegeven bij #thumbs span:first-child.

background: url(../017-pics/thumbnails.png) 0 -321px;

Precies hetzelfde verhaal als gelijk hierboven voor de tweede thumbnail. Alleen moet hier de achtergrond-afbeelding 321 px naar boven worden gezet, zodat de derde thumbnail precies binnen de <span> komt te staan.

#nr-4 span:first-child

{background: url(../017-pics/thumbnails.png) 0 -481px;}

tot en met

#nr-13 span:first-child

{background: url(../017-pics/thumbnails.png) 0 -2154px;}

Voor de vierde tot en met de dertiende thumbnail geldt precies hetzelfde verhaal als hierboven staat, alleen wordt de achtergrond-afbeelding met de thumbnails steeds een stukje verder omhoog gezet, zodat de juiste thumbnail in de juiste <span> komt te staan.

Het enige dat verder nog verandert, is de id van de <div>, waarin de span zit. En voor de vierde en achtste thumbnail, dat zijn de twee staande thumbnails, geldt ook de eerder bij #thumbs .staand span:first-child opgegeven css.

css voor vensters minimaal 340 px breed

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

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

De css die binnen deze media query staat, geldt alleen voor vensters die minimaal 340 px breed zijn. In deze vensters komen de thumbnails niet onder, maar rechts naast de tekst te staan. Bovendien wordt in deze vensters bij hoveren over, aanraken van, klikken op of tabben naar een thumbnail een grotere afbeelding hiervan geopend.

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

screen: deze regel geldt alleen voor schermweergave.

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

(min-width: 340px): het venster moet minimaal 340 px breed zijn. Is het venster smaller, dan wordt de css die binnen deze media-regel staat genegeerd.

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

@media screen and (min-width: 340px) { 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 }.

main

Het element waar de belangrijkste inhoud van de pagina in staat. Dit element komt maar één keer voor op de pagina.

max-width: 900px;

Maximumbreedte 900 px.

Een <main> is een blok-element. Als je geen breedte opgeeft aan een blok-element, wordt dit normaal genomen even breed als zijn ouder. Dat is hier <body>, ook een blok-element zonder breedte. De ouder daarvan is ook weer een blok-element zonder breedte: <html>. <html> is het buitenste element. Daardoor wordt <html> even breed als het venster van de browser.

In smallere browservensters is dat precies de bedoeling, maar op een breedbeeldmonitor zou je hierdoor onleesbaar brede tekst kunnen krijgen. Daarom wordt de breedte beperkt tot maximaal 900 px.

margin: 0 auto;

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

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

position: relative;

Om nakomelingen van een element te kunnen positioneren ten opzichte van dat element, moet het element zelf zijn gepositioneerd. Omdat verder niets wordt opgeven bij top en dergelijke, heeft dit verder geen enkele invloed op <main> zelf.

#tekst

Het element met id=”tekst”. De <div> waarbinnen alle tekst staat.

position: absolute;

Om de <div>, en daarmee de daarin zittende tekst, op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf is gepositioneerd. Dat is hier <main>.

right: 210px;

210 px vanaf de rechterkant van <main> neerzetten. Hierdoor komt er aan de rechterkant van div#tekst ruimte voor de thumbnails.

Voor left wordt geen waarde opgegeven. Dat is in dit geval ook niet nodig, omdat bij het ontbreken van left in dit geval de <div> standaard op left: 0; wordt neergezet. Waarmee deze <div> dus de linkerkant van <main> tot 210 px vanaf de rechterkant van <main> beslaat.

#thumbs

Het element met id=”thumbs”. De <div> waarbinnen de thumbnails en dergelijke staan.

float: right;

Zo hoog mogelijk en zover mogelijk naar rechts neerzetten.

div#thumbs is een blok-element. Normaal genomen wordt dit automatisch even breed als z’n ouder. Dat is hier <main>, dat even hierboven een maximale breedte van 900 px heeft gekregen. Dat is ’n tikkeltje overdreven voor thumbnails die slechts 200 px breed zijn.

Als een blok-element echter wordt gefloat, zoals hier gebeurt, wordt het niet meer automatisch even breed als z’n ouder. Het krijgt dan niet meer dan de breedte die nodig is om de inhoud weer te kunnen geven.

Bij #thumbs span:first-child en #thumbs span:last-child zijn de thumbnails en onderschriften 200 px breed gemaakt. Hierdoor wordt div#thumbs ook 200 px breed, niet meer dan nodig is om thumbs en onderschriften weer te kunnen geven.

Hier gelijk boven bij #tekst is rechts van div#tekst een ruimte van 210 px vrij gemaakt met behulp van right: 210px;. En hoera, daar past deze div#thumbs en dus de daarin zittende thumbnails en onderschriften precies in! Met een kleine ruimte van 10 px tussen de tekst en de thumbnails.

margin: 25px 10px 240px;

Omdat voor links geen waarde is opgegeven, krijgt dit automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 25px 10px 240px 10px in de volgorde boven – rechts – links – onder.

Marge bovenaan 25 px: hiermee komen de thumbnails iets van de bovenkant van het venster van de browser te staan, op gelijke hoogte als de tekst links van de thumbs.

(Die tekst hoeft geen marge aan de bovenkant te krijgen. De tekst staat in <p>’s, en die hebben standaard een marge aan boven- en onderkant.)

Marge rechts 10 px: de maximumbreedte van <main> is 900 px. Als een browservenster nou precies 900 px breed is, staan de thumbs precies tegen de rechterkant van het venster aan, wat foeilelijk is. Met deze kleine marge is er altijd wat afstand tussen de rand van het venster en de thumbs. En in bredere vensters maakt het niets uit.

Afbeelding 6: een grote marge aan de onderkant voorkomt dat de grote afbeelding gedeeltelijk verdwijnt aan de onderkant

Marge onderaan 240 px: de bovenkant van de grote afbeelding staat gelijk met de bovenkant van de thumbnails. De onderste grote afbeelding is 360 px hoog, de thumbnail maar 150 px. Als er wat weinig tekst is en de onderste grote afbeelding wordt geopend, zou die hierdoor onder het venster van de browser komen te staan, zoals op de afbeelding is te zien: de halve kop van het arme beestje wordt bloeddorstig afgehakt door de onderkant van het venster van de browser.

Door onderaan div#thumbs een ruime marge te geven, wordt dit voorkomen. In dit geval is er genoeg tekst, maar ik ben er altijd voor dit soort dingen ’preventief’ te doen. Als er later tekst wordt verwijderden er wordt vergeten zo’n marge aan te brengen, wordt het arme beestje alsnog onthalfhoofd.

Marge links 10 px: die marge links maakt hier niets uit, omdat div#tekst absoluut is gepositioneerd. Daardoor houden andere elementen, zoals hier div#thumbs, er geen rekening meer mee. De regel had ook margin: 25px 10px 240px 0; mogen zijn, maar omdat die laatste ’0’ niet nodig is, heb ik hem weggelaten.

#thumbs div

De <div>’s binnen het element met id=”thumbs”. Dit zijn de dertien <div>’s boven de thumbnails.

position: relative;

Om nakomelingen van een element te kunnen positioneren ten opzichte van dat element, moet het element zijn gepositioneerd. Omdat verder niets wordt opgeven bij top en dergelijke, heeft dit verder geen enkele invloed op de <div>’s zelf.

#thumbs span

De <span>’s binnen het element met id=”thumbs”. Er is een <span> voor elke thumbnail en een <span> voor elk onderschrift.

pointer-events: none;

Deze css-eigenschap moet niet worden verward met pointer-events uit JavaScript, die iets heel anders zijn.

Welkom in de Wondere Wereld van Internet Explorer. Deze regel is nodig voor Internet Explorer 11 op touchscreens en voor UC browser op Windows Phone. (Deze laatste browser lijkt de weergave-machine van Internet Explorer te gebruiken, vandaar dat deze dezelfde eigenaardige kuren heeft.)

Als bij aanraken een afbeelding moet worden getoond die er eerst niet was, en als op een of andere manier een <span> is betrokken bij dat aanraken, dan weigert Internet Explorer (en UC browser op Windows Phone) die afbeelding te tonen.

In dit geval moet de afbeelding worden getoond bij hoveren over of focus op een van de dertien <div>’s binnen div#thumbs. En binnen die <div>’s zitten dus helaas ook twee <span>’s: eentje voor de achtergrond-afbeelding met de thumbnail en eentje voor het onderschrift.

In andere voorbeelden op deze site heb ik de meest krankzinnige oplossingen moeten bedenken, want zelfs het volledig buiten het scherm positioneren of het met behulp van display: none; volledig verbergen van de <span>’s hielp meestal niet.

Hier is het relatief eenvoudig.

Deze regel zorgt ervoor dat hoveren over, aanraken van en klikken op een element als het ware door dat element heengaan en op het onderliggende element terecht komen. In dit geval is dat onderliggende element de <div> die op hoveren en dergelijke moet reageren, dus dat werkt prima.

#thumbs div:focus::after, #thumbs div:hover::after

De eerste selector, voor de komma:

#thumbs: het element met id=”thumbs”. De <div> waar de dertien <div>’s met thumbnails en dergelijke in staan.

div:focus: als de <div> focus heeft.

#thumbs: div:focus: samen: Als een <div> binnen het element met id=”thumbs” focus heeft.

::after: maak dan met behulp van ::after een pseudo-element aan.

#thumbs div:focus::after: de hele eerste selector. Als een div binnen het element met id=”thumbs” focus heeft, maak dan een pseudo-element aan. In dit pseudo-element wordt de grote foto weergegeven.

De tweede selector, na de komma, is precies hetzelfde, maar dan als er over de <div> wordt gehoverd.

Dat in de selector :focus én ::after of :hover én ::after worden gebruikt, is geen enkel probleem. Je zet ze gewoon achter elkaar.

In dit pseudo-element wordt de grote afbeelding getoond. Die grote afbeelding is voor elk van de dertien <div>’s anders, maar de rest van de css is voor alle dertien hetzelfde, dus die kan hier in één keer worden opgegeven.

content: "";

Het pseudo-element is leeg. Althans: er staat niet meer dan een achtergrond-afbeelding in. Toch moet je content gebruiken. Om aan te geven dat er geen tekst in staat, gebruik je twee aanhalingstekens zonder iets ertussen.

background-position: right;

In bepaalde exotische maten schermen kan bij zoomen de afbeelding te veel naar links komen te staan. Het is netter als de afbeelding altijd rechts blijft staan. Hiermee blijft de achtergrond-afbeelding altijd aan de rechterkant van het element staan.

Normaal genomen zou ik de ’shorthandbackground gebruiken: een verkorte manier om álle eigenschappen van een achtergrond in één keer op te geven. Maar omdat elke <span> later een eigen background-image krijgt, kan dat hier niet.

background-repeat: no-repeat;

Een achtergrond wordt normaal genomen automatisch herhaald, totdat de achtergrond van het element helemaal is gevuld. In principe is het pseudo-element even groot als de achtergrond-afbeelding en zou dus niet worden herhaald. Maar in bepaalde exotische maten schermen kan bij zoomen de afbeelding toch worden herhaald. Hiermee wordt dat voorkomen.

Normaal genomen zou ik de ’shorthandbackground gebruiken: een verkorte manier om álle eigenschappen van een achtergrond in één keer op te geven. Maar omdat elk pseudo-element later een eigen background-image krijgt, kan dat hier niet.

background-size: contain;
Afbeelding 7
Afbeelding 7: links zonder background-size: contain; Een groot deel van de foto valt weg. Rechts met background-size: contain; De hele afbeelding is verkleind tot hij past, waarbij de juiste verhouding intact blijft.

Als een browservenster groot genoeg is om de hele grote afbeelding weer te geven, is deze eigenschap niet nodig. Maar als de grote afbeelding niet in het venster past, ontstaat er een probleem.

Hieronder wordt een breedte van 480 px opgegeven voor het pseudo-element. (Er wordt ook een hoogte opgegeven. Dat werkt precies hetzelfde, wat dit probleem betreft.) Ook als het element te groot is, wordt dit normaal genomen toch weergegeven. Ook als het niet in het venster van de browser past.

Op bovenstaande afbeelding is het venster 341 px breed en 270 px hoog. Het pseudo-element, waarin de foto als achtergrond-afbeelding zit, is 480 bij 360 px en past dus duidelijk niet in het browservenster. De achtergrond-afbeelding, die ook 480 px breed en 360 px hoog is, past bij lange na niet.

Iets hieronder wordt met behulp van max-width en max-height gezorgd dat het pseudo-element altijd in het venster past: het pseudo-element wordt verkleind, totdat het past. Maar de achtergrond-afbeelding wordt niet verkleind. Die wordt gewoon op normale grootte weergegeven. Waardoor een deel van de achtergrond-afbeelding buiten het pseudo-element verdwijnt.

Links het tot grote droefenis stemmende resultaat zonder ingrijpen: het deel van de achtergrond-afbeelding dat niet past, wordt gewoon weggelaten. Als Stalin deze techniek al had gekend, had het hem veel minder moeite gekost Trotzki van foto’s te laten verdwijnen.

(Da’s vreemd. Mijn spellingcontrole keurt wel een boef als Stalin goed, maar een veel minder grote boef als Trotzki wordt afgekeurd. Is open source dan toch stalinistisch? Ja, rustig maar, ik dwaal af, ik weet het Pfff, ik ga al weer verder. Mag ik misschien even, mopper, mag-ook-nooit-wat, grom...)

Rechts is background-size: contain; gebruikt: de achtergrond-afbeelding wordt volledig weergegeven. Als de afbeelding te breed is, wordt de breedte verminderd tot de afbeelding past. Als de afbeelding te hoog is, wordt de hoogte verminderd tot de afbeelding past. Als hoogte of breedte wordt verminderd, wordt de andere richting automatisch evenveel verminderd, zodat de verhoudingen intact blijven. Hierdoor wordt een lachspiegel-effect voorkomen.

width: 480px;

Breedte van het pseudo-element.

Dit is ook de breedte van de grote afbeeldingen. Deze afbeeldingen worden als achtergrond-afbeelding weergegeven. Een achtergrond-afbeelding heeft van zichzelf geen breedte of hoogte, maar vult alleen de achtergrond van het element. Daarom moet een maat aan dat element worden gegeven. Bij een breedte van 480 px is de volledige achtergrond-afbeelding te zien.

Voor staande foto’s wordt de breedte (en de hoogte) verderop bij #thumbs div.staand:focus::after, #thumbs div.staand:hover::after aangepast.

max-width: 96vw;

Hier gelijk boven is een breedte van 480 px opgegeven. Als het venster van de browser smaller is dan 480 px, past het pseudo-element – en dus de daarin zittende achtergrond-afbeelding – niet binnen het venster. Waardoor een deel van de achtergrond-afbeelding zou verdwijnen. Daarom wordt een maximumbreedte opgegeven.

De eenheid vw is vrij onbekend, terwijl deze uiterst bruikbaar kan zijn, zoals in dit geval. Als een maximumbreedte van 100% wordt opgegeven, zou het pseudo-element niet breder worden dan zijn ouder. Dat is hier div#thumbs, die slechts 200 px breed is. Dat werkt dus niet.

Een vw is 1% van de breedte van het venster van de browser, ongeacht hoe breed eventuele voorouders van het element zijn. Een breedte van 96 vw is dus altijd 96% van de breedte van het browservensters, ongeacht de breedte van div#thumbs of eventuele andere voorouders van het pseudo-element.

96 vw, geen 100, omdat div#thumbs bij #thumbs rechts een marge van 10 px heeft gekregen. Hierdoor staan de <div>’s waar dit pseudo-element bij hoort ook 10 px naar links. Bij een breedte van 100 vw zou hierdoor een klein stukje van het pseudo-element links buiten het venster komen te staan. Met 96 vw past het net.

UC browser op Android en oudere versies van Android browser kennen de eenheid vw (en het even hieronder gebruikte vh) niet. Hierdoor valt een deel van de foto buiten het venster en is dit deel alleen met scrollen te zien. Meer hierover bij Bekende problemen (en oplossingen).

height: 360px;

Zelfde verhaal als iets hierboven bij width, maar dan voor de hoogte.

max-height: 100vh;

Zelfde als iets hierboven bij max-width, maar dan voor de hoogte. De eenheid vh is hetzelfde als vw, maar dan in de hoogte: 1 vh is 1% van de hoogte van het browservenster. Omdat er geen marge aan boven- of onderkant is, kan hier 100 vh worden gebruikt.

position: absolute;

Om het pseudo-element op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf is gepositioneerd. Dat is hier de <div> waar het pseudo-element bij hoort.

Een pseudo-element is van zichzelf een inline-element. Hierdoor kunnen eigenschappen als hoogte en breedte niet worden gebruikt. Door het absoluut te positioneren, verandert het in een soort blok-element en kunnen deze eigenschappen wel worden gebruikt.

top: 0; right: 0;

Helemaal bovenaan en rechts neerzetten. De rechterbovenhoek van de grote afbeelding komt hierdoor op dezelfde plaats als de rechterbovenhoek van de thumbnail.

z-index: 10; Afbeelding 8: door een z-index staat de grote afbeelding bij focus bovenaan

In principe komen elementen die later in de html staan boven eerdere elementen uit de html te staan. Op de afbeelding hiernaast is de eerste grote foto geopend. Omdat de <span> met de tweede thumbnail later in de html staat, komt deze gewoon over de grote foto heen te staan. Niet helemaal de bedoeling.

Door de z-index van het pseudo-element met de grote foto te verhogen, komt deze toch boven de thumbnail te staan.

Een z-index werkt alleen, als het element voldoet aan één of meer voorwaarden. Eén van die voorwaarden is een absolute of fixed positie. Dat is hier het geval, want iets hoger is het pseudo-element absoluut gepositioneerd.

#thumbs div:hover::after

Voor deze elementen geldt ook de eerder bij #thumbs div:focus::after, #thumbs div:hover::after opgegeven css, voor zover die hier niet wordt gewijzigd.

Doe iets met het pseudo-element dat met behulp van ::after wordt gemaakt bij hoveren over een <div> binnen het element met id=”thumbs”. Bij hoveren over een van de dertien <div>’s binnen div#thumbs wordt een pseudo-element met de grote foto geopend.

z-index: 15; Afbeelding 9: door een hoge z-index staat de grote afbeelding bij hoveren helemaal bovenaan

Als een <div> focus heeft, is de bijbehorende grote foto zichtbaar. Als je, terwijl die <div> nog focus heeft, over een later in de html <div> staande hovert, is de grote foto van die <div> volledig zichtbaar. Maar als je over een eerder in de html staande <div> hovert, is die grote foto maar gedeeltelijk zichtbaar. De onderste helft verdwijnt, omdat later in de html staande elementen normaal genomen boven eerdere worden geplaatst.

Op de afbeelding heeft de tweede <div> focus en wordt de daarbij horende grote foto getoond. Terwijl die foto wordt getoond, wordt gehoverd over de eerste <div>. De daarbij horende grote foto opent ook, maar verdwijnt half onder de tweede foto.

Om te zorgen dat hoveren altijd ’wint’, wordt de z-index van het pseudo-element bij hoveren verhoogd. Omdat bij #thumbs div:focus::after, #thumbs div:hover::after de z-index van het pseudo-element al is verhoogd tot 10, moet de z-index hier meer dan 10 worden, zodat hoveren ’wint’ van focus. En 15 is meer dan 10.

(Het is verstandig tussen de verschillende z-indexen getallen over te slaan. Als er later een z-index moet worden tussengevoegd, hoef je dan niet alles opnieuw te nummeren. Ooit, lang geleden, heb ik eens honderden opeenvolgende z-indexen aangebracht. Keurig aaneensluitend. En toen moest er helemaal aan het begin eentje worden tussengevoegd. Ééntje...)

Een z-index werkt alleen, als het element voldoet aan één of meer voorwaarden. Eén van die voorwaarden is een absolute of fixed positie. Dat is hier het geval, want bij #thumbs div:focus::after, #thumbs div:hover::after is het pseudo-element absoluut gepositioneerd.

#thumbs div.staand:focus::after, #thumbs div.staand:hover::after

Voor deze elementen geldt ook de eerder bij #thumbs div:focus::after, #thumbs div:hover::after en #thumbs div:hover::after opgegeven css, voor zover die hier niet wordt gewijzigd.

Deze selectors zijn vrijwel hetzelfde als die bij #thumbs div:focus::after, #thumbs div:hover::after: bij hoveren over of focus van een <div> binnen het element met id=”thumbs” iets met het bijbehorende pseudo-element doen. Alleen is hier aan toegevoegd, dat die <div> class=”staand” moet hebben. Alleen de vierde en de achtste <div> hebben die class: ze horen bij de twee staande thumbnails.

width: 360px; height: 480px;

Voor de staande grote foto’s worden breedte en hoogte aangepast.

#thumbs div:hover span:first-child, #thumbs div:focus span:first-child

{}

Als over een <div> binnen het element met id=”thumbs” wordt gehoverd, of als een van die <div>’s focus heeft, doe dan iets met de <span> binnen die <div>’s die eerste kind zijn.

Dit heeft betrekking op de dertien <div>’s met de thumbnails en dergelijke. Binnen elk van die dertien <div>’s zitten twee <span>’s. In de eerste van die twee <span>’, het eerste kind, zit de thumbnail.

’doe dan iets’, schreef ik. En wat moet er dan worden gedaan? Niets. Nada. Noppes. Niente.

Omdat er niets tussen de accolades staat, is dat precies wat er wordt gedaan: niets. Waarbij ik het aan filosofen overlaat, om uit te vogelen of je wel iets doet, als je niets doet.

Deze absurde regel is nodig voor Internet Explorer 10. Zonder deze regel openen in Internet Explorer 10 geen grote foto’s. In Internet Explorer 9 en Internet Explorer 11 is deze regel niet nodig. Op een of andere manier heeft Microsoft nogal wat krankzinnige bugs wat betreft het tonen van afbeeldingen bij elkaar weten te harken.

#nr-1:focus::after, #nr-1:hover::after

Voor deze elementen geldt ook de eerder bij #thumbs div:focus::after, #thumbs div:hover::after en #thumbs div:hover::after opgegeven css. Voor de <div>’s boven de staande thumbnails (#nr-4 en #nr-8) geldt ook de eerder bij #thumbs div.staand:focus::after, #thumbs div:staand:hover::after opgegeven css.

Als het element met id=”nr-1” focus heeft, of als daarover wordt gehoverd, doe dan iets met het met behulp van ::after gemaakte pseudo-element.

De grote foto wordt binnen dit pseudo-element als achtergrond-afbeelding weergegeven. Alleen die achtergrond-afbeelding wordt hier opgegeven, want de rest van de css is voor alle dertien pseudo-elementen hetzelfde en kon dus eerder in één keer worden opgegeven.

Je zou de grote foto’s ook in een <img> kunnen stoppen, of zonder focus of hover al kunnen toevoegen. Als je ze dan verbergt met display: none; of zoiets, hoef je ze bij hoveren of focus alleen nog maar zichtbaar te maken.

Maar in dat geval worden alle dertien grote foto’s bij openen van de pagina gelijk gedownload, ook als je ze verbergt met display: none; of zoiets. Door ze pas toe te voegen bij hoveren of focus, worden ze pas gedownload op het moment dat je ze daadwerkelijk bekijkt. Voor mobiele apparaten is dat niet onbelangrijk.

background-image: url(../017-pics/foto-01.jpg);

De achtergrond-afbeelding die bij div#nr-1, de eerste <div> met thumbnails en dergelijke, hoort.

#nr-2:focus::after, #nr-2:hover::after

{background-image: url(../017-pics/foto-02.jpg);}

(...) tot en met (...)

#nr-13:focus::after, #nr-13:hover::after

{background-image: url(../017-pics/foto-13.jpg);}

Dit werkt precies hetzelfde als hierboven bij #nr-1:focus::after, #nr-1:hover::after gelijk hierboven, maar dan voor de tweede tot en met dertiende <div> en grote foto.

css voor vensters minimaal 340 px breed en hoge resolutie

@media screen and (min-width: 340px) and (-webkit-min-device-pixel-ratio: 1.5), screen and (min-width: 340px) and (min-resolution: 144dpi)

Omdat deze media query (mede door toedoen van Apple) nogal ingewikkeld is, verwijs ik niet naar een eerdere uitleg, maar beschrijf hem hier volledig opnieuw.

De css die binnen deze media query staat zorgt ervoor dat op een hogeresolutiescherm met een breedte van minimaal 340 px een betere kwaliteit afbeelding wordt gebruikt.

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

Er zijn hier twee voorwaarden. Als aan één van die voorwaarden wordt voldaan, is de hieronder staande css van toepassing op deze browservensters: als aan ... OF ... is voldaan, pas dan de hieronder staande css toe. In zo’n regel gebruik je niet het woord ’of’, maar een komma.

De eerste voorwaarde is:

screen and (min-width: 340px) and (-webkit-min-device-pixel-ratio: 1.5)

De tweede voorwaarde is:

screen and (min-width: 340px) and (min-resolution: 144dpi)

screen: in beide voorwaarden hetzelfde. Deze regel geldt alleen voor schermweergave.

and: ook dit komt in beide voorwaarden voor. Er komt nog een voorwaarde, waaraan moet worden voldaan.

(min-width: 340px): ook weer hetzelfde. Het venster moet minstens 340 px breed zijn.

and: er komt nog een voorwaarde.

Na dit gemeenschappelijke begin verschillen beide voorwaarden.

(-webkit-min-device-pixel-ratio: 1.5): het laatste deel van de eerste voorwaarde. Deze is speciaal voor Safari en de browsers op iOS (omdat die gebruik maken van de weergave-machine van Safari). Apple houdt zich hier niet aan de standaard, maar gebruikt een eigen bedenksel: het deel dat met -webkit- begint. De dichtheid van de pixels moet minstens anderhalf keer zo groot zijn als normaal. Oftewel: een hogeresolutiescherm, wat Apple ’retina’ noemt.

(min-resolution: 144dpi): het laatste deel van de tweede voorwaarde. Deze geldt voor alle browsers, behalve Safari en de browsers op iOS. Er moeten minstens 144 dots per inch zijn. Oftewel: een hogeresolutiescherm.

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 aan het begin van dit stukje weggevallen, maar het geheel ziet er zo uit:

@media screen and (min-width: 340px) and (-webkit-min-device-pixel-ratio: 1.5), screen and (min-width: 340px) and (min-resolution: 144dpi) { 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 }.

Deze css is voor hogeresolutieschermen. Voor die schermen worden andere afbeeldingen gebruikt, omdat deze schermen een (veel) betere kwaliteit weer kunnen geven. Er is meer over te lezen bij Hogeresolutieschermen.

Er wordt een afbeelding gebruikt die twee keer zo groot is als op een gewoon scherm. Op een hogeresolutiescherm wordt die grotere foto twee keer zo klein weergegeven, waardoor de afmetingen van de foto even groot zijn als bij de gewone foto. Maar de kwaliteit is veel beter.

#nr-1:focus::after, #nr-1:hover::after

{background-image: url(../017-pics/foto-01-2x.jpg);}

tot en met

#nr-13:focus::after, #nr-13:hover::after

{background-image: url(../017-pics/foto-13-2x.jpg);}

Bij hoveren over of focus van één van de dertien <div>’s boven een thumbnail de grote afbeelding weergeven. Dit werkt precies hetzelfde als bij #nr-1:focus::after, #nr-1:hover::after. Het enige verschil is dat een andere afbeelding wordt gebruikt. Bij de ’normale’ weergave wordt voor bijvoorbeeld de eerste afbeelding ’foto-01.jpg’ gebruikt, hier ’foto-01-2x.jpg’.

css voor vensters minimaal 500 px breed en hoog

@media screen and (min-width: 500px) and (min-height: 500px)

De opbouw van deze regel staat beschreven bij @media screen and (min-width: 340px). Er zijn twee verschillen: de minimale breedte moet hier 500 px zijn, en er is een extra voorwaarde: het browservenster moet minimaal 500 px hoog zijn (min-height: 500px).

De css binnen deze media query zorgt voor een randje rondom de grote foto’s.

#thumbs div:focus::after, #thumbs div:hover::after

De eerste selector, voor de komma:

#thumbs: het element met id=”thumbs”. De <div> waar de dertien <div>’s met thumbnails en dergelijke in staan.

div:focus: als de <div> focus heeft.

#thumbs: div:focus: samen: Als een <div> binnen het element met id=”thumbs” focus heeft.

::after: maak dan met behulp van ::after een pseudo-element aan.

#thumbs div:focus::after: de hele eerste selector. Als een div binnen het element met id=”thumbs” focus heeft, maak dan een pseudo-element aan. In dit pseudo-element wordt de grote foto weergegeven.

De tweede selector, na de komma, is precies hetzelfde, maar dan als er over de <div> wordt gehoverd.

Dat in de selector :focus én ::after of :hover én ::after worden gebruikt, is geen enkel probleem. Je zet ze gewoon achter elkaar.

border: black solid 1px; Afbeelding 10: in kleine vensters kan een border te ver van de afbeelding komen te staan

Zwart randje rondom het pseudo-element.

Dat zwarte randje zou ook in browservensters smaller en lager dan 500 px niet misstaan, maar dat wordt heel lastig. In de grotere vensters waarvoor deze css is bedoeld, wordt de grote foto volledig getoond. Dat betekent dat de grote foto de achtergrond van het pseudo-element volledig vult. Waardoor het randje rondom het pseudo-element netjes rond de foto staat.

In smallere en lagere vensters wordt de foto verkleind, zodat die altijd volledig is te zien. Daardoor kan er ruimte tussen de buitenkant van het pseudo-element en de foto ontstaan. Het randje staat dan niet om de foto, maar om het pseudo-element.

Op de afbeelding is het randje rood en dik gemaakt, zodat het beter opvalt. De foto is verkleind, zodat die volledig is te zien. Maar daardoor is aan boven- en onderkant lege ruimte ontstaan tussen foto en pseudo-element. Het randje staat keurig rondom die lege ruimte en heeft niet in de gaten dat het zo nogal in het luchtledige hangt. Daarom kan het randje pas worden gebruikt in grotere vensters, waarin de achtergrond-afbeelding even groot is als het pseudo-element.

JavaScript

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

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

<script> en </script>

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

document.getElementsByTagName("body")

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

[0]

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

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

document.getElementsByTagName("body")[0]

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

addEventListener

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

"touchstart"

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

function () {return null; }

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

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

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

In feite wordt hier gewoon gezegd: als het scherm wordt aangeraakt, blijf dan niet dom tot het jaar 3017 wachten op wat er verder gebeurt, maar reageer gelijk. Zonder dit stukje JavaScript openen de grote afbeeldingen en onderschriften niet, omdat de browser blijft wachten op het vervolg van de 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.