Uitleg flexibele lay-out met header, menu en footer. Past zich aan breedte van venster aan
Laatst aangepast: .

Korte omschrijving
Een-, twee of driekoloms lay-out met (vaste) header, (vast) menu en (vaste) footer. De precieze indeling is afhankelijk van de breedte van het venster van de browser.
Deze lay-out vult altijd het hele venster van de browser, zowel in de hoogte als in de breedte. Alleen bij heel weinig inhoud kan in vensters smaller dan 810 px en op alle touchscreens ruimte aan de onderkant van het venster leeg blijven.
Header (geel)
Altijd even breed als het venster.
Vensters smaller dan 810 px en alle touchscreens: de header scrolt mee met de rest van de pagina. Niet hoger dan nodig om de inhoud van de header weer te kunnen geven.
Vensters breder dan 810 px, behalve touchscreens: staat altijd bovenaan het venster, scrolt niet mee. Hoogte afhankelijk van lettergrootte.
Menu (grijs/zwart op groen)
Vensters smaller dan 600 px: het menu staat onderaan de pagina, gelijk boven de footer en scrolt mee met de rest van de pagina. De links staan in rijen onder elkaar. Elke rij bevat twee links in de vorm van twee knoppen, die elk de halve breedte van het venster vullen.
Een link in de header bovenin brengt je naar dit menu. Een link in het menu brengt je weer terug naar boven. Deze twee links zijn alleen zichtbaar in deze smalle vensters.
Vensters tussen 600 en 810 px breed en op alle touchscreens breder dan 600 px: het menu staat gelijk onder de header en scrolt mee met de rest van de pagina. De links staan naast elkaar in de vorm van acht naast elkaar staande knoppen.
Vensters breder dan 810 px, behalve touchscreens: het menu staat altijd aan de linkerkant van het venster en scrolt niet mee. De breedte is afhankelijk van de breedte van het venster. De links staan onder elkaar in de vorm van acht onder elkaar staande knoppen.
Linkerkolom (tekst, oranje)
Als er genoeg tekst en dergelijke aanwezig is, kan deze kolom worden gescrold.
Als er genoeg ruimte is, komen rechts van de tekst foto's te staan.
Vensters smaller dan 810 px: de tekst wordt even breed als het venster.
Vensters met een breedte van 810 px tot 1400px: de tekst wordt 73% breed.
Vensters breder dan 1400 px: de tekst wordt 58% breed.
Vensters breder dan 1600px: de tekst wordt 48% breed.
Vensters breder dan 1800px: de tekst wordt maximaal 50 em breed om lange, slecht leesbare regels te voorkomen.
Rechterkolom (foto's, roze)
Als er genoeg ruimte is, komen rechts van de tekst foto's te staan. De foto's waarvoor op die plaats geen ruimte is, komen onder de tekst te staan.
Vensters smaller dan 810 px: alle foto's komen onder de tekst te staan. Afhankelijk van de breedte van het venster en de browser staan de foto's in één tot vier kolommen onder de tekst.
Vensters met een breedte van 810 tot 1400 px: er komt naast de tekst één kolom foto's te staan.
Vensters breder dan 1400 px: er komen naast de tekst twee kolommen foto's te staan.
Vensters breder dan 1600 px: er komen naast de tekst drie kolommen foto's te staan.
Vensters breder dan 1800 px: er komen naast de tekst zoveel kolommen foto's te staan, als er in het venster passen.
Footer (blauw)
Altijd even breed als het venster.
Vensters smaller dan 810 px en alle touchscreens: de footer scrolt mee met de rest van de pagina. Niet hoger dan nodig om de inhoud van de footer weer te kunnen geven.
Vensters breder dan 810 px, behalve touchscreens: staat altijd onderaan het venster, scrolt niet mee. Hoogte afhankelijk van lettergrootte.
BELANGRIJK
Alles op deze site kan vrij worden gebruikt, met twee beperkingen:
* Je gebruikt het materiaal op deze site volledig op eigen risico. Het kan prima zijn dat er fouten in de hier verstrekte info zitten. Voor eventuele schade die door gebruik van materiaal van deze site ontstaat, in welke vorm dan ook, zijn www.css-voorbeelden.nl en medewerkers daarvan op geen enkele manier verantwoordelijk.
* Deze uitleg wordt regelmatig bijgewerkt. Het is daarom niet toegestaan deze uitleg op welke manier dan ook te verspreiden, zonder daarbij duidelijk te vermelden dat de uitleg afkomstig is van www.css-voorbeelden.nl en dat daar altijd de nieuwste versie is te vinden. Dit is om te voorkomen dat er verouderde versies worden verspreid.
Een link naar www.css-voorbeelden.nl wordt trouwens altijd op prijs gesteld.
Opmerkingen
- Alle gebruikte foto's zijn genomen op Koninginnedag 30 april 2010 in het Vondelpark in Amsterdam. Als je jezelf herkent en de originele foto wilt hebben, stuur dan even 'n mailtje naar info@css-voorbeelden.nl.
-
Op de site en in de download is gebruik gemaakt van JavaScript. Dit JavaScript is niet essentieel voor de goede werking. Op touchscreens ziet het er altijd hetzelfde uit. Op niet-touchscreens breder dan 810 px ziet het er zonder JavaScript anders uit, maar alles werkt gewoon. Mensen die JavaScript uit hebben staan zijn dit soort verschillen gewend. (Ik kan het weten, ik surf al jaren met NoScript.)
Deze JavaScript komt van de volgende sites:
modernizr-touch-html5shiv.js: om touch events te herkennen en om in Internet Explorer 7 en 8 nieuwere html5-elementen te herkennen;
css3-mediaqueries-js: om Internet Explorer 8 media queries te laten herkennen;
respond.js: om Internet Explorer 7 en 8 media queries te laten herkennen.
css3-mediaqueries.js en modernizr-touch-html5shiv.js zijn bijgesloten in de download, respond.js wordt alleen op de site gebruikt. Omdat dit soort scripts voortdurend wordt bijgewerkt, is het absoluut noodzakelijk dat je zélf nieuwe scripts ophaalt. Meer hierover staat bij Touchscreens herkennen met behulp van modernizr.
- Voor het maken van de gradiënten is gebruik gemaakt van de gradiënt-editor op colorzilla.com.
- Als je ankers (links binnen de pagina zelf) gebruikt, kan dit in deze lay-out (hele grote) problemen opleveren. Zie verder bij Bekende problemen.
-
Bij deze constructie staan in een breder venster de header, de footer en het menu stil. Tekst en afbeeldingen kunnen scrollen. Deze constructie kan op touchscreens grote problemen opleveren, zoals het wegvallen van (grote) delen van de pagina. Dit speelt vooral in oudere browsers, dus op termijn zal dit probleem niet meer bestaan. Maar daar heb je nu nog niets aan. Een volledig overzicht van de problemen staat bij Bekende problemen.
Deze problemen zijn zo ernstig, dat het beter is om dit voorbeeld aan te passen voor álle touchscreens. Hoe je dat kunt doen, staat bij Touchscreens herkennen met behulp van modernizr.
- Er zitten in dit voorbeeld 32 thumbnails. Omdat het voor de werking niet nodig is dat dit allemaal verschillende thumbs zijn, heb ik elke thumbnail vier keer gebruikt. Dat maakt de download 'n stuk kleiner.
-
Als je wilt zien, hoe deze lay-out verandert bij verschillende breedtes, kun je het venster van de browser breder en smaller maken. Als je scherm niet breed genoeg is voor de grotere breedtes, kun je deze simuleren op infobyip.com.
Overigens werkt in- en uitzoomen in Opera, Firefox en Internet Explorer 8 en 9 (alle vier alleen op de desktop) hetzelfde als een smaller of breder venster. In Google Chrome en Safari op de desktop werkt zoomen ook, maar de lay-out ziet er daarin bij uitzoomen (verkleinen) totaal anders uit dan in een echt smaller of breder venster.
- Omdat Microsoft graag haar tradities in ere houdt en dus haar browsers nooit update, zijn er afwijkingen in Internet Explorer 7 en 8. Zie verder bij Bekende problemen.
- In bredere vensters worden in dit voorbeeld rechts van de tekst thumbnails neergezet. Dat is zomaar 'n idee. Je kunt er ook blokken tekst neerzetten. Of toelichtingen. Of noten. Of in bredere vensters de tekst in kolommen naast elkaar zetten met behulp van de css3-eigenschap
columns
. (Hoewel je bij kolommen wel op moet passen. Als er veel tekst in staat, moet je vanaf de onderkant van de eerste kolom weer terug naar de bovenkant van de tweede kolom, van onderaan de tweede naar bovenaan de derde, enz. Dat is niet echt heel prettig lezen, voorzichtig uitgedrukt.)
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 Quanta Plus, GIMP en Firefox met extensies. De pdf-bestanden zijn gemaakt met LibreOffice.
Vragen of opmerkingen? Fout gevonden? Ga naar het forum.
Achterliggend idee
Tot niet zo heel lang geleden kon je bij het maken van 'n website enigszins uitgaan van een bepaalde maat. Dat is steeds minder zo. Op de desktop verschijnen steeds meer brede schermen en bij mobiele apparaten is er helemaal een totale wildgroei aan maten, waaronder heel kleine.
Deze lay-out past zich min of meer aan de breedte van het venster van de browser aan. Om dat mogelijk te maken, zijn vrijwel alle maten niet opgegeven in een absolute eenheid als px, maar in relatieve eenheden als % en em. Dit maakt het mogelijk om onderdelen een breedte te geven, die relatief is ten opzichte van de breedte van het browservenster.
Door met behulp van css3 de breedte van het venster van de browser op te vragen, kan de lay-out worden aangepast aan de breedte van het venster.
Boven een bepaalde breedte heeft deze lay-out in principe een vaste header, menu en footer: ze scrollen niet mee met de pagina. Maar in veel mobiele browsers levert dit (grote) problemen op. Nieuwere browsers kunnen hier vaak wel mee overweg, maar het zal nog wel even duren voordat iedereen zo'n nieuwere browser heeft.
Daarom wordt met behulp van JavaScript geprobeerd vast te stellen, of de browser 'touch events' herkent: aanrakingen van een touchscreen. Als dat zo is, wordt waarschijnlijk een mobiele browser gebruikt en scrollen header, menu en footer mee met de rest van de pagina. Deze methode is niet waterdicht, maar de meeste mobiele browsers worden hier wel mee herkend.
Heel simpele mobiele apparaten, of heel oude mobiele browsers, kunnen de breedte van het venster niet doorgeven. Daarom wordt er, om aan de veilige kant te blijven, standaard vanuit gegaan dat het om een heel smal venster gaat. Pas als door de browser een grotere breedte wordt doorgegeven, wordt de lay-out aangepast aan die grotere breedte.
Niet alle mobiele apparaten kunnen goed met JavaScript uit de voeten. Daarom wordt er standaard vanuit gegaan dat het om een mobiele browser gaat. Pas als de browser meldt dat touch events niet worden ondersteund, worden - in bredere vensters - header, menu en footer op een vaste positie gezet.
Deze volgorde zorgt ervoor dat ook de simpelste mobiele apparaten met de lay-out overweg kunnen: pas als er daadwerkelijk meer mogelijkheden aanwezig zijn, worden die gebruikt.
Het opvragen van bijvoorbeeld de breedte van het venster kan met behulp van de zogenaamde 'media queries' uit css3: een regel die begint met @media
. Met zo'n regel kun je css schrijven, die bijvoorbeeld alleen voor vensters met een bepaalde breedte geldt. Op tablets en dergelijke is de breedte van het venster van de browser normaal genomen ook de breedte van het scherm.
Door het gebruik van media queries kun je bij een bepaalde breedte de lay-out aanpassen. Ik meet niet op de specifieke breedte van één of meer apparaten, maar gewoon 'hoe het er uitziet'. Als iets te klein wordt, moet het anders worden weergegeven. Specifieke breedtes zijn meestal gericht op één fabrikant (Apple), terwijl er tientallen verschillende resoluties zijn.
De nieuwste mobiele apparaten hebben vaak een hogere resolutie dan oudere apparaten of monitors voor de desktop: de pixels staan dichter op elkaar, tot wel vier keer zo dicht. Dat zou betekenen dat een lijn van 4 px breedte op zo'n nieuwer scherm maar 1 px breed zou worden. Dat is echter niet zo, want deze apparaten doen net alsof ze 'n 'normale' pixeldichtheid hebben. Alles wordt alleen veel mooier weergegeven, omdat de pixels kleiner zijn.
(Alles? Nou, nee. Bij afbeeldingen werkt dit alleen maar als je de afbeeldingen hebt aangepast voor zo'n hoge pixeldichtheid. Als de pixels gewoon niet in de afbeelding zitten, kunnen ze ook niet worden weergegeven. Maar voor bijvoorbeeld tekst werkt het fantastisch. In dit voorbeeld zijn de afbeeldingen niet aangepast voor een eventuele hogere pixeldichtheid.)
Met behulp van media queries wordt de breedte van het venster opgevraagd en kan de lay-out worden aangepast. Daarnaast wordt geprobeerd mobiele browsers te onderscheiden van desktopbrowsers.
Een mobiele browser wordt in de regel gebruikt op een touchscreen. Een mobiele browser moet daarom zogenaamde 'touch events', aanrakingen van het scherm, herkennen. Door te kijken of een browser touch events herkent, kun je met vrij grote zekerheid vaststellen, of een browser een mobiele browser is of niet.
Om te kijken of een browser touch events herkent, wordt gebruik gemaakt van modernizr. Dat is een JavaScript, waarmee je kunt vaststellen of een browser bepaalde nieuwere eigenschappen wel of niet ondersteunt. In deze lay-out wordt alleen gekeken of touch events worden ondersteund, maar je kunt nog veel meer met dit script.
Als de browser touch events ondersteunt, wordt door modernizr aan het <html>-element de class "touch" toegevoegd. Als de browser touch events niet ondersteunt, wordt de class "no-touch" toegevoegd.
Door nu in de css bepaalde selectors te beginnen met .touch
of .no-touch
, kan verschil worden gemaakt tussen browsers die wel en die geen touch events ondersteunen. Browsers die touch events niet ondersteunen zijn in principe ook de browsers die geen problemen hebben met een vaste header, menu en footer. Die kunnen er nu met behulp van de class "no-touch" uitgefilterd worden, waardoor andere browsers deze css niet krijgen.
De css bestaat uit twee delen: algemene css, die de basis vormt voor de pagina en overal het zelfde is. Daarnaast css voor de verschillende breedtes, en voor mobiele en desktopbrowsers. Je zou voor elke breedte een eigen stylesheet kunnen maken, maar normaal genomen is dat niet zo handig. Als je aparte stylesheets maakt voor elke breedte, moet voor elke breedte een extra aanroep naar de server worden gedaan. Omdat het maar om kleine stukjes aparte css gaat, is het efficiënter alles in één stylesheet te zetten. Er wordt dan wel wat meer gedownload dan strikt noodzakelijk is, maar dat is nog altijd efficiënter dan de extra aanroep.
Ogenschijnlijk lijkt deze lay-out een samenhangend geheel: het venster wordt volledig gevuld door header, menu, tekst, foto's en footer. In werkelijkheid gaat het om vier totaal van elkaar losstaande vlakken, die toevallig enigszins samenhangend op het scherm worden gezet.
Toevallig? Nou ja, de plaats waar ze staan, is natuurlijk niet toevallig. Maar ze hebben verder niets met elkaar te maken. Zonder enig probleem zou je de header links kunnen neerzetten, of de footer bovenaan. Wat voor het oog een samenhangend geheel is, bestaat in werkelijkheid uit vier losse blokken.
Omdat de pagina in werkelijkheid uit losse blokken bestaat, geeft dat de mogelijkheid de weergave van die blokken met behulp van css aan te passen. En af te laten hangen van de breedte van het venster.
Het eerste blok is de header aan de bovenkant van het venster, die ook in de html helemaal bovenaan staat. Voor de herkenbaarheid is de achtergrond van de header geel gemaakt. De header staat in de tag <header>, wat eigenlijk een doodgewone div is, maar met een speciale semantische betekenis: de header zit erin. Omdat <header> een blok-element is, vult het normaal genomen automatisch de volle breedte van het venster van de browser.
Standaard scrolt de header gewoon mee met de rest van de pagina. De hoogte is niet meer, dan nodig is om de inhoud van de header weer te kunnen geven.
Pas als wordt vastgesteld dat het venster breder is dan 810 px en dat de browser geen touch events herkent, scrolt de header niet meer mee, maar blijft altijd bovenin het venster staan. Dit ontstaat niet door iets aan de header te veranderen, maar door het deel gelijk onder de header absoluut te positioneren. Binnen dat deel kan worden gescrold, maar de pagina in z'n geheel scrolt niet. Dus de header scrolt ook niet en blijft altijd op z'n plaats bovenin het venster staan.
Om alle onderdelen goed ten opzichte van elkaar te kunnen plaatsen, krijgt <header> nu een vaste hoogte. Bij een heel grote letter zou de inhoud van <header> daardoor onder de header kunnen komen te staan. Om dat te voorkomen, wordt overflow
op auto
gezet: als de inhoud niet in <header> past, verschijnt rechts van de header een verticale scrollbalk.
Voor de footer geldt ongeveer hetzelfde verhaal als voor de header. De footer staat in een blok-element <footer>. Ook <footer> is eigenlijk 'n doodgewone div met een speciale semantische betekenis. Voor de herkenbaarheid is de achtergrond van de footer blauw gekleurd.
Standaard staat de footer onderaan de pagina en scrolt mee met de rest van de pagina. De hoogte van <footer> is niet meer, dan nodig is om de inhoud ervan weer te kunnen geven.
Pas als wordt vastgesteld dat het venster breder is dan 810 px en dat de browser geen touch events herkent, wordt de footer absoluut aan de onderkant van het venster gepositioneerd. De footer scrolt nu niet meer mee met de rest van de pagina, maar blijft altijd aan de onderkant van het venster staan.
Om alle onderdelen goed ten opzichte van elkaar te kunnen plaatsen, krijgt <footer> nu een vaste hoogte. Bij een heel grote letter zou de inhoud van <footer> daardoor boven de footer kunnen komen te staan. Om dat te voorkomen, wordt overflow
op auto
gezet: als de inhoud niet in <footer> past, verschijnt rechts van de footer een verticale scrollbalk.
Normaal genomen wordt een blok-element als <footer> automatisch even breed als z'n ouder. Dat is hier <body>. Maar omdat <footer> absoluut gepositioneerd is, is dat hier niet het geval. Daarom moet <footer> een breedte van 100% krijgen, dan wordt hij wel even breed als <body> en dus de pagina.
Dan houden we het middendeel tussen header en footer nog over.
<header> en <footer> kunnen relatief simpel een breedte krijgen, omdat ze gewoon altijd even breed als het venster moeten zijn. Voor het middendeel ligt het iets ingewikkelder, omdat de plaatsing van menu, tekst en foto's afhankelijk is van de breedte van het venster en van of de browser touch events herkent of niet. En dan moet het geheel er ook nog 'n beetje netjes uitgelijnd en zo uitzien.
Ook hier wordt weer uitgegaan van het smalste venster in een browser die touch events herkent. Pas als daadwerkelijk wordt vastgesteld dat het venster breder is, en dat de browser touch events niet herkent, wordt de lay-out aangepast.
De kleinste lay-out is bedoeld voor vensters smaller dan 600 px. Zulke kleine vensters zijn (vrijwel) altijd touchscreens. Dus het menu moet worden bediend met de vingers, en niet iedereen heeft lieflijke kleutervingertjes, waarmee je heerlijk kunt priegelen in voor bouwvakkersklauwen onbereikbare hoekjes.
(Ik wil ooit nog eens openhartig mijn diepste gevoelens uitwisselen met de gediplomeerde gek die meende op m'n test-Samsung van 320x240 een virtueel toetsenbord te moeten aanbrengen. Dat alleen op vingers reageert. Enthousiast reageert. Met één aanraking bedien je soms wel vijf toetsen tegelijk. Wauw. Zo bezoek je echt spontaan de meest exotische sites. Als je ooit iemand ziet die z'n vingers heeft bijgepunt: dat is de bezitter van 'n Samsung smartphone.)
Kortom: het menu heeft op hele kleine vensters relatief veel ruimte nodig. Zoveel, dat het al snel het hele venster vult. Daarom wordt het menu onderaan de pagina neergezet, gelijk boven de footer. Het vult daar inderdaad (vrijwel) het hele venster, maar dat is op die plaats niet erg. Zou het gelijk bovenaan de pagina staan, dan zou je bij openen van de pagina in eerste instantie alleen het menu zien.


De links uit het menu zijn elk even breed als het halve venster. Ze kunnen nu makkelijk met de vingers worden bediend, ook door bouwvakkers. Om snel weer terug naar boven te kunnen verschijnt een extra link: 'Top'. Dit menu scrolt gewoon mee met de pagina, net als de footer. De knoppen in het menu zijn zo simpel mogelijk gehouden: rechthoekige grijze vlakken.
Bovenaan de pagina verschijnt linksboven in de de header een extra link 'Menu', die je in één keer naar het menu onderaan brengt.
Dit is ook de reden dat het menu in de html onder de tekst en de afbeeldingen staat, gelijk boven de footer: om er 'n link naartoe te kunnen maken, moet het menu een id krijgen. Je kunt dan naar dat id linken, een zogenaamd 'anker'. Dat anker komt uit op de plaats waar die id staat. Als ik naar de onderkant van de pagina wil gaan, moet die id dus onderaan de pagina staan. En omdat de id in het menu staat, moet ook het menu onderaan staan.
In deze vensters smaller dan 600 px vult de tekst de volle breedte van het venster. De foto's staan in één lange kolom onder de tekst.
Als het venster van de browser breder dan 600 px is, is er (iets) meer ruimte. De knoppen uit het menu kunnen naast elkaar worden gezet en zijn toch nog goed met de vingers te bedienen. Omdat de knoppen nu niet meer onder elkaar, maar naast elkaar staan, kunnen ze absoluut bovenaan worden gepositioneerd, gelijk onder de header. Ze vullen nu niet meer het hele venster, en bovenaan is een logischer plaats dan helemaal onderaan.
De extra link bovenin de header naar het menu aan de onderkant, en de link vanuit het menu terug naar de bovenkant van de pagina, zijn nu niet meer nodig en worden verborgen.
Het menu scrolt nog steeds mee met de rest van de pagina. Er is nog steeds relatief weinig ruimte in het venster, en mensen zullen niet dol van geluk worden als die weinige ruimte dan ook nog 'ns schuilgaat achter header, menu en footer. Zelfs de subtiele, gevoelige, kunstzinnige samenstelling van de achtergrondkleuren verhelpt daar niets aan.

De kleine stukjes groen die je achter het menu ziet, zijn de achtergrondkleur van het menu. De knoppen in het menu zijn hier iets verfraaid met een achtergrond-gradiënt en ronde hoeken.
De tekst vult de volle breedte van het venster van de browser. De foto's staan in vier kolommen onder de tekst, waarbij elke kolom 25% van de breedte van het venster vult. In smallere vensters zijn de foto's iets kleiner dan in bredere vensters.
In vensters breder dan 810 px worden de regels met tekst veel te lang. Daardoor worden ze lastig te lezen. Daarom wordt de breedte van de div met de tekst begrensd tot 73%. 73 is een minder willekeurig getal dan het lijkt. Met wat padding en zo wordt het 75, driekwart.
Er blijft nu rechts een lege ruimte over. Die kun je leeg laten, maar je kunt hem ook vullen met iets anders dan tekst de tekst op de oranje achtergrond. In het voorbeeld zijn hier afbeeldingen neergezet, maar je kunt er ook 'n tweede kolom met tekst neerzetten, of noten, of 'n tweede menu, of wat dan ook.

De tekst wordt naar links gefloat, en de afbeeldingen ook. Door een breedte aan de elementen met de afbeeldingen te geven, wordt gezorgd dat tekst en afbeelding naast elkaar passen. Nu wordt de tekst niet te breed, terwijl toch het hele venster wordt gebruikt. De foto's die niet naast de tekst passen, komen weer gewoon onder de tekst te staan, in vier kolommen.
Hoewel het bij de tekst en de foto's om twee kolommen lijkt te gaan, is het in werkelijkheid één kolom, die in twee delen is gesplitst: eentje met de tekst, en eentje met de foto's.
Ook op deze breedte scrollen header, menu en footer mee met de rest van de pagina. Als de letters heel sterk vergroot zouden worden, zouden sommige links op twee regels komen te staan, omdat de tekst niet meer binnen de knop past. Daarom is tussen de woorden binnen een link een vaste spatie gebruikt. Nu komt de tekst mogelijk aan de rechterkant iets buiten de knop te staan, maar dat is beter dan dat de tekst onder de knop komt te staan, want dan komt hij over de inhoud van de pagina te staan.
In vensters breder dan 810 px is het eigenlijk de bedoeling dat header, menu en footer blijven staan en alleen de tekst en afbeeldingen kunnen scrollen. Maar omdat dat in mobiele browsers tot (grote) problemen kan leiden, is daarvoor een aanvullende voorwaarde nodig. Als met behulp van het JavaScript modernizr is vastgesteld dat de browser touch events niet herkent, is het vermoedelijk geen mobiele browser. Vermoedelijk gaat het dan om een desktop of soortgelijk apparaat. Pas in dat geval scrollen header, menu en footer niet mee.
Tekst en afbeeldingen staan binnen <article>. Dat is in feite een gewone div, bedoeld voor de een min of meer samenhangend geheel. Hier is maar één <article>, dat absoluut wordt gepositioneerd tussen header en footer. Aan de linkerkant wordt ruimte overgelaten voor een absoluut gepositioneerde kolom, waarin het menu komt.
De footer wordt absoluut onderaan het venster van de browser gepositioneerd. Als er heel weinig inhoud op de pagina staat en er niet gescrold hoeft te worden, staat de footer toch onderaan het venster.

Op de desktop komt de lay-out er nu heel anders uit te zien.
Header en footer hebben een vaste hoogte met overflow
op auto
, omdat anders bij grote letters de inhoud buiten footer en header kan komen te staan. Als de inhoud nu niet in footer of header past, verschijnt naast footer en header een verticale scrollbalk.
Ook het menu heeft om dezelfde reden overflow
op auto
, maar zonder vaste hoogte. Dat is niet nodig, omdat het menu absoluut is gepositioneerd tussen header en footer.
Het uiterlijk van het menu is ook anders. De knoppen staan onder elkaar. Bij hoveren over de knoppen verandert de kleur. Hoveren werkt nauwelijks of niet op touchscreens, daarom wordt het alleen ingeschakeld als de browser geen touch events herkent. Je mag aannemen dat er dan sprake is van 'n muis of iets soortgelijks, waarmee je wel kunt hoveren.
Met JavaScript uit kan niet worden getest, of de browser touch events herkent of niet. Daardoor wordt de standaard-css gebruikt, waarbij er vanuit wordt gegaan dat de browser touch events niet herkent. Het ziet er dan op de desktop net zo uit als in een mobiele browser.
In vensters breder dan 1400 px is ruimte voor twee kolommen met afbeeldingen rechts van de tekst. In vensters breder dan 1600 px passen drie kolommen. En in vensters breder dan 1800 px komen zoveel foto's naast de tekst te staan, als er in de lege ruimte passen. Bij deze hele brede vensters zijn de foto's niet meer volledig uitgelijnd, omdat de precieze breedte daar onbekend is.
Bij floaten wordt niet meer naast elkaar gezet, dan op dezelfde regel past. Als het venster breder is dan 810 px, wordt de tekst 73% breed gemaakt. In de resterende ruimte past één foto. Door de tekst en de elementen waarin de foto's staan smaller te maken, passen er meer foto's op dezelfde regel naast de tekst. Hoe smaller de tekst en hoe smaller de elementen met de foto's, hoe meer er op dezelfde regel naast elkaar past.
De breedte van het browservenster wordt weer met behulp van een @media-regel opgevraagd. De breekpunten van 1400, 1600 en 1800 px zijn min of meer willekeurig gekozen. Op deze afstanden bleek het er netjes uit te zien en zo.


Op de afbeeldingen hiernaast staat een screenshot van de lay-out, zoals deze er op een venster tussen 1600 en 1800 px breed uitziet: drie kolommen met foto's naast de tekst.
Op de bovenste afbeelding ziet het eruit zoals in een browser die touch events herkent. Dat zal meestal een touchscreen zijn, maar het kan ook een desktopbrowser zijn, waar JavaScript uitstaat.
Op de onderste afbeelding ziet het eruit, zoals in een browser die touchscreens niet herkent, en waarin JavaScript aan staat.
Dit zal meestal een desktopbrowser zijn.
Los van de belangrijkste onderdelen zijn nog wat extra's aangebracht voor het uiterlijk, zoals een overgang tussen oranje en roze. De tekst staat op een oranje achtergrond, de afbeeldingen op een roze. Hoewel dit volgens mijn kleurgevoel een fantastisch harmonieuze kleurenkeuze is, blijkt de browser daar iets anders over te denken en is de overgang van oranje naar roze onderaan de tekst ietwat, eh, z'n tijd te ver vooruit. Omdat er op die overgang ook nog foto's staan, wordt het effect nog 'ns versterkt. Daarom is daar een gradiënt aangebracht, die de overgang verzacht.
Zo is er nog een aantal van dat soort niet-essentiële dingen.
Voor Internet Explorer 7, 8 en 9 is vanzelfsprekend een heel scala aan extra's nodig. Dat is een van de weinige echte zekerheden in het leven: Microsoft maakt geen browsers, maar gehaktmolens.
Gehaktmolens? Microsoft? Maakt die gehaktmolens? Ja. Zonder die extra's wordt de pagina namelijk in gehakt veranderd in Internet Explorer 7 en 8. In Internet Explorer 9 valt dat mee, daar is alleen hogere wiskunde nodig voor de gradiënt in het menu, want zo'n verlopende kleur maken met alleen css was kennelijk te hoog gegrepen voor Microsoft.
Voor Internet Explorer 7 en 8 is extra JavaScript nodig om de nieuwe html5-elementen te herkennen. Voor Internet Explorer 8 is ook nog extra JavaScript nodig om @media-regels te herkennen. Internet Explorer 7 lukt dat helemaal niet, dus die heeft ook nog 'n berg aparte css nodig.
De voorvoegsels -moz-, -ms-, -o- 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.
Google Chrome en Safari: -webkit-
, naar de gebruikte weergave-machine: webkit.
Opera: -o-
, je mag zelf bedenken waar de letter o vandaan komt (hint: Opera wordt door Opera Software gemaakt).
Internet Explorer: -ms-
, naar de maker: Microsoft. Traditiegetrouw heeft Microsoft zich hier jarenlang niets van aangetrokken, pas bij Internet Explorer 8 is Microsoft -ms-
gaan gebruiken. Omdat het ook zonder -ms-
werkt en de speciale css voor Internet Explorer toch in een aparte stylesheet staat, gebruik ik -ms-
nooit voor oudere versies dan Internet Explorer 9.
Als je css valideert met de w3c css-validator, moet je even instellen dat je geen foutmelding krijgt voor het gebruik van deze voorvoegsels.
In dit voorbeeld wordt linear-gradient
gebruikt. Dit werkt in nog geen enkele browser zonder voorvoegsel. In Internet Explorer werkt het nog helemaal niet, maar het lijkt te worden opgenomen in Internet Explorer 10. Vooruitlopend daarop gebruik ik ook al het voorvoegsel -ms-
. Onduidelijk is namelijk nog of Microsoft het met of zonder dit voorvoegsel gaat implementeren.
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 linear-gradient
erbij. Deze wordt als laatste opgegeven. Bijvoorbeeld Firefox herkent -moz-linear-gradient
. Zodra Firefox linear-gradient
gaat herkennen, zal dit -moz-linear-gradient
overrulen, omdat het er later in staat. Dat ze er beide in staan, is dus geen enkel probleem.
Op dit moment moet je nog het volgende schrijven:
{-moz-linear-gradient: ...; -ms-linear-gradient: ...; -o-linear-gradient: ...; -webkit-linear-gradient: ...; linear-gradient: ...;}
In de toekomst kun je volstaan met:
{linear-gradient: ...;}
Internet Explorer 7, 8 en 9 kennen linear-gradient
helemaal niet, die krijgen eigen css.
Semantische elementen en WAI-ARIA
Ik heb deze twee onderwerpen samengevoegd, omdat ze veel met elkaar te maken hebben.
Semantische elementen
De meeste elementen die in html worden gebruikt, hebben een semantische betekenis. Dat wil zeggen dat je aan de gebruikte tag al (enigszins) kunt zien, wat voor soort inhoud er in het element staat. In een <h1> staat een belangrijke kop. In een <h2> staat een iets minder belangrijke kop. In een <p> staat een alinea. In een <table> staat een tabel (en geen lay-out, als het goed is!). Enz.
Door het op de goede manier gebruiken van semantische elementen, kunnen zoekmachines, screenreaders, enz. de structuur van een pagina begrijpen. De spider van een zoekmachine is redelijk te vergelijken met een blinde. Het is dus ook in je eigen belang om semantische elementen zo goed mogelijk te gebruiken. Een site die toegankelijk is voor mensen met een handicap, is in de regel ook goed te verwerken voor een zoekmachine en maakt dus een grotere kans gevonden en bezocht te worden.
Als het goed is, wordt het uiterlijk van de pagina bepaald met behulp van css. Het uiterlijk staat hierdoor (vrijwel) los van de semantische inhoud van de pagina. Met behulp van css kun je een <h1> heel klein weergeven en een <h6> heel groot, terwijl screenreaders, zoekmachines, en dergelijke nog steeds weten dat de <h1> een belangrijke kop is.
Slechts enkele elementen, zoals <div> en <span>, hebben geen semantische betekenis. Daardoor zijn deze elementen uitstekend geschikt om met behulp van css het uiterlijk van de pagina aan te passen: de semantische betekenis verandert niet, maar het uiterlijk wel. Voor een screenreader of zoekmachine verandert er (vrijwel) niets, voor de gemiddelde bezoeker krijgt het door de css een heel ander uiterlijk.
(De derde laag, naast html voor de inhoud en css voor het uiterlijk, is JavaScript. Die zorgt voor de interactie tussen site en bezoeker. De min of meer strikte scheiding tussen css en html aan de ene kant en JavaScript aan de andere kant is met de komst van css3 en html5 veel vager geworden. Je kunt nu bijvoorbeeld ook met css dingen langzaam verplaatsen en met html deels de invoer in formulieren controleren. Maar op JavaScript ga ik op deze site verder niet echt in.)
html5 heeft een aantal nieuwe elementen, die speciaal zijn bedoeld om de opbouw van een pagina aan te geven. In dit voorbeeld worden hiervan <header>, <nav>, <article>, <section> en <footer> gebruikt. Alle vijf gedragen zich als een gewone <div>, maar dan een <div> met een semantische betekenis. Hierdoor kunnen screenreaders, zoekmachines, en dergelijke beter zien hoe de pagina is samengesteld.
<header>: bedoeld om een header in te zetten.
<nav>: bedoeld om een serie links voor navigeren in te zetten.
<article>: tekst en dergelijke die als een zelfstandig geheel kan worden gezien. In dit voorbeeld is de tekst in de rechterkolom samen met de afbeeldingen een <article>.
<section>: deel van een tekst. In dit voorbeeld is <article> in de rechterkolom onderverdeeld in een aantal <section>'s.
<article>'s en <section>'s kunnen worden genest. Het gaat er alleen om dat een <article> een afgerond geheel is, en ook een deel van een <article> of <section> kan dat zijn.
Een pagina van een krant kan binnen een <article> staan. Binnen dat <article> kan een <section> Sport staan. Binnen die <section> Sport kan weer een <article> met een wedstrijdverslag staan. Binnen een <article>, want zo'n verslag is een afgerond geheel. En binnen dat verslag zouden weer <section>'s kunnen staan voor het deel voor de rust, het deel na de rust, enz.:
<article id="krant">
<section id="sport">
<article id="verslag-1">
<section id="voor-de-rust">tekst</section>
<section id="na-de-rust">tekst</section>
</article>
<article id="verslag-2">
<section id="voor-de-rust">tekst</section>
<section id="het-doelpunt">tekst</section>
<section id="de-rellen">tekst</section>
</article>
</section>
</section id="economie">
<article id="de-grootgraaiers">tekst</article>
</section>
</article>
<footer>: bedoeld om een footer in te zetten.
Ook <header> en <footer> mogen vaker op één pagina worden gebruikt. Een <article> zou bijvoorbeeld een eigen <header> en <footer> kunnen hebben, naast de <header> en <footer> voor de hele pagina.
Het is nog niet helemaal duidelijk of dit wel op grote schaal gaat gebeuren, want er zitten fors wat haken en ogen aan, bijvoorbeeld voor zoekmachines. Daar ga ik hier dus verder niet op in. Persoonlijk denk ik vooralsnog dat één <header> en <footer> per pagina het beste is.
Met behulp van dit soort nieuwe semantische elementen kan bijvoorbeeld een screenreader in één keer een hele <header> of <nav> passeren. Alleen hebben deze nieuwe elementen één probleem: ze hebben in de praktijk nog weinig nut, omdat screenreaders en dergelijke ze nog niet herkennen. En voordat alle screenreaders en dergelijke ze herkennen, zijn we jaren verder, want screenreaders zijn peperduur (behalve het uitstekende open source NVDA).
Maar er is niets op tegen om ze nu vast te gaan gebruiken. Op het moment dat screenreaders, zoekmachines, enz. ze gaan herkennen, is de pagina dan al hierop voorbereid. Extra werk is het eigenlijk niet. Het intypen van <nav> gaat even snel als het intypen van <div>, en het intypen van <header> gaat zelfs nog sneller dan <div id="header">, zoals nu vaak gebeurt.
WAI-ARIA
Los van semantische elementen is er nog een hulpmiddel om pagina's beter toegankelijk te maken voor screenreaders en dergelijke: WAI-ARIA-ondersteuning. WAI-ARIA staat voor Web Accessibility Initiative - Accessible Rich Internet Applications.
WAI-ARIA is een hele serie codes die bijvoorbeeld aangeven, welk deel van een pagina een menu, een header, een footer, enz. is. Daarnaast kan WAI-ARIA bij bijvoorbeeld een formulier aangeven of iets is aangevinkt of niet. Voor blinden zijn dit soort zaken uiterst belangrijk (en dus ook voor zoekmachines).
Screenreaders en dergelijke kunnen al jaren WAI-ARIA-codes herkennen. Dat is nog niet het geval met de nieuwe semantische elementen uit html5, en dat zal ook nog wel even duren, want screenreaders zijn peperduur (behalve het uitstekende NVDA).
Een van de groepen met codes binnen WAI-ARIA bestaat uit de zogenaamde landmarks. Daarmee worden belangrijke onderdelen van een pagina gemarkeerd. De landmarks komen gedeeltelijk overeen met de nieuwe semantische html5-elementen. Omdat screenreaders deze landmarks al wel herkennen, zet ik ze bij de corresponderende html-elementen. In de toekomst zijn ze niet meer nodig, maar dat zal nog wel even duren.
Op deze pagina is dit enigszins van belang, omdat de volgorde op het scherm iets afwijkt van de volgorde in de html, en dat kan knap verwarrend zijn. Een screenreader kan niet alleen van kop naar kop, maar ook van landmark naar landmark springen. Daardoor kan bijvoorbeeld het menu toch snel worden gevonden.
In dit voorbeeld gebruik ik de landmarks banner, navigation, contentinfo en main. Elke landmark wordt voorafgegaan door role=
, op dezelfde manier als dat bij classes of id's gebeurt:
<header role="banner">
<nav role="navigation">
<article role="main">
<footer role="contentinfo">
De namen zijn wat eigenaardig, maar dat is historisch zo gegroeid. 'main' geeft aan dat daar de belangrijkste content van de pagina begint, de andere roles spreken voor zich.
Op de pagina met links vind je onder het kopje Toegankelijkheid → Forums, richtlijnen, links, artikelen en dergelijke meer info over WAI-ARIA.
Alleen :hover of :hover, :focus en :active?
Het eerste deel van deze tekst is voor alle voorbeelden met links en dergelijke hetzelfde, het laatste deel (onder het kopje Speciaal bij dit voorbeeld) is speciaal voor dit voorbeeld.
De meeste mensen openen 'n link door erop te klikken of door de link met de vinger aan te raken. Bij gebruik van een toetsenbord is er echter 'n tweede manier: met behulp van de Tab-toets (sommige browsers gebruiken andere toetsen, maar het principe is hetzelfde). Met behulp van de Tab-toets kun je van link naar link 'springen'. Op welke link je staat, wordt door alle browsers aangegeven met een of ander kadertje rondom de link.
De link met het kadertje eromheen heeft focus. Dat wil zeggen dat je die link volgt als je op de enter-toets drukt. In principe werkt dit precies hetzelfde als gewoon klikken op de link.
Als iemand geen muis wil of kan gebruiken, bijvoorbeeld door 'n handicap, is deze manier om 'n link te openen erg handig. Als de volgorde van de links in de code niet logisch is, kun je eventueel met behulp van tabindex
'n afwijkende volgorde van de links opgeven. De Tab-toets volgt dan die afwijkende volgorde.
Tot zover is er nauwelijks verschil tussen het gebruik van de Tab-toets of van de muis.
Als je echter extra dingen onder de link hebt gestopt, die pas gaan werken als je over de link hovert, is er wel 'n verschil. Je geeft dat aan met :hover
: als je over de link hovert. Met de Tab-toets alleen kun je niet over 'n link hoveren. Dus als er bijvoorbeeld 'n pop-up wordt geopend, zul je die niet zien als je de Tab-toets gebruik om naar 'n link te gaan.
Om dit op te lossen kun je op dezelfde manier als je :hover
gebruikt :focus
gebruiken: als de link focus heeft. Dat is dus als er 'n kadertje rondom de link staat en de link wordt gevolgd bij het indrukken van enter.
Door dus a:hover, a:focus {...}
te gebruiken, opent bijvoorbeeld 'n pop-up ook als je de Tab-toets gebruikt. Maar er zitten 'n paar adders onder het gras.
* Naast :hover
en :focus
is er nog :active
. Deze laatste zou horen te werken als de muis wordt ingedrukt op de link. Dat werkt ook zo in alle browsers, behalve in Internet Explorer vóór versie 8. In haar onmetelijke wijsheid heeft Microsoft besloten af te wijken van de standaard: :active
werkt in oudere versies zoals :focus
hoort te werken, en :focus
werkt gewoon helemaal niet vóór versie 8. In alle andere browsers werken :focus
en :active
dus wel volgens de standaard, en met ingang van versie 8 van Internet Explorer houdt Microsoft zich ook eindelijk aan de standaard.
Dit betekent dat je niet kunt volstaan met a:hover, a:focus {...}
, maar dat je a:hover, a:focus, a:active {...}
moet gebruiken, want anders werkt het niet in oudere versies van Internet Explorer. Het zal nog jaren duren voor deze oude versies niet meer worden gebruikt, maar omdat Microsoft zich nu eindelijk ook aan de standaard houdt op dit punt, wordt :active
nu ook langzaamaan bruikbaar voor waar het voor is bedoeld.
* Belangrijke informatie moet je niet geven via :focus
of :active
, omdat dit niet werkt als css uit staat. En op 'n touchscreen is de kans dat het helemaal niet werkt heel erg groot.
* Een pop-up of zoiets kan gruwelijk in de weg komen te staan, bijvoorbeeld door de rest van de pagina af te dekken. Iemand die gewoon de muis kan gebruiken, verplaatst deze even en de pagina is weer zichtbaar. Iemand die moeite heeft met het gebruik van de muis, heeft deze mogelijkheid niet of minder. Als je buiten de link en de daarbij horende pop-up en dergelijke klikt, sluit deze weliswaar, maar dat is nu juist het probleem: mensen die de muis niet goed kunnen gebruiken, hebben nou net daar problemen mee.
Als je via de Terug-toets teruggaat naar de vorige pagina, heeft de link waar je vandaan kwam nog steeds focus, en dus staan pop-up en dergelijke ook nog open. Wat ook heel storend kan zijn als andere delen van de pagina daardoor niet te zien zijn. Op het moment dat ik dit schreef, werkte de Terug-toets bij alle browsers zo, met uitzondering van Google Chrome. Maar 't kan best zijn dat Google Chrome het inmiddels ook doet, of 'n andere juist weer niet, want dit schijnt nogal te veranderen.
* Bij een touchscreen wordt geen muis gebruikt, dus je kunt ook niet over een link hoveren. In sommige browsers is er wel 'n soort imitatie van :hover
, maar bij lange na niet in allemaal, dus de werking van :hover
(en ook :active
) is op mobiel volstrekt onbetrouwbaar.
Om al deze redenen is het goed je even af te vragen of de voordelen van 'n pop-up en dergelijke wel opwegen tegen de nadelen. Ik zet zelf mijn eigen overwegingen bij elk voorbeeld steeds even erbij. Wat natuurlijk niet wil zeggen dat je daar geen andere mening over zou kunnen hebben.
Speciaal bij dit voorbeeld
:focus
en :hover
werken in dit voorbeeld alleen als de browser touch events niet herkent, dus niet op touchscreens. Dat is ook precies de bedoeling, want op touchscreens kun je niet hoveren, en :focus
werkt ook niet of niet goed, omdat het samenwerkt met een toetsenbord. Het hier onderstaande geldt dus niet voor touchscreens. Verder moet het venster van de browser minstens 810 px breed zijn.
In dit geval verkleurt alleen de link, als erover wordt gehoverd of als deze focus heeft. Dit is op geen enkele manier hinderlijk. Daarom gebruik ik hier :focus
en :hover
beide.
Internet Explorer 7 heeft grotendeels eigen css. Voor dit tranentrekkende satansjong worden in die eigen css :hover
en :active
gebruikt.
Beschrijving van code en css
De code die te maken heeft met de basis van dit voorbeeld is onderstippeld blauw
. Alle voor dit voorbeeld niet-essentiële code is bruin
.
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 ontbreken bijvoorbeeld de knoppen voor navigeren op de site. Ook in de kopregels zit vaak wat verschil. Daarnaast kunnen er nog andere (meestal kleine) verschillen zijn.
Als je deze uitleg leest naast de broncode van het voorbeeld op de site, kan het dus bijvoorbeeld zijn dat 'n <h1> uit de css bij 'n <h2> uit de html hoort. Maar het gaat niet om hele grote, fundamentele afwijkingen.
Als je dit lastig vindt, kun je bovenaan de pagina de hele handel downloaden. In de download zit 'n voorbeeld dat wel naadloos aansluit op de uitleg in de download.
<!DOCTYPE html>
<html lang="nl">
Een document moet met een doctype beginnen om weergaveverschillen tussen browsers te voorkomen. Zonder doctype is de kans op verschillende (en soms volkomen verkeerde) weergave tussen verschillende browsers heel erg groot.
Geldige doctypes vind je op www.w3.org/QA/2002/04/valid-dtd-list.
Gebruik het volledige doctype, inclusief de eventuele url, anders werkt het niet goed.
Het hier gebruikte doctype is dat van html5.
<meta charset="utf-8">
Zorgt dat de browser letters met accenten en dergelijke goed kan weergeven.
utf-8 is de beste charset (tekenset), omdat deze alle talen van de wereld (en nog heel veel andere extra tekens) bestrijkt, maar toch niet meer ruimte inneemt voor de code, dan nodig is. Als je utf-8 gebruikt, hoef je veel minder entiteiten (ä
en dergelijke) te gebruiken, maar kun je bijvoorbeeld gewoon ä gebruiken.
Deze regel moet zo hoog mogelijk komen te staan, als eerste regel binnen de head, omdat hij anders door sommige browsers niet wordt gelezen.
In html5 hoeft deze regel niet langer te zijn, dan wat hier staat.
<meta name="viewport" content="width=device-width, initial-scale=1">
Mobiele apparaten variëren enorm in breedte. En dat is een probleem. Sites waren, in ieder geval tot voor kort, gemaakt voor desktopbrowsers. En die hebben, in vergelijking met bijvoorbeeld een smartphone, heel brede vensters. Hoe moet je op 'n smartphone een pagina weergeven, die is gemaakt voor de breedte van een desktop? Je kunt natuurlijk wachten tot álle sites zijn omgebouwd voor smartphones, tablets, enz., maar dan moet je waarschijnlijk heel erg lang wachten.
Mobiele browsers gokken erop dat een pagina een bepaalde breedte heeft. Safari voor mobiel bijvoorbeeld gaat ervan uit dat een pagina 980 px breed is. De pagina wordt vervolgens zoveel versmald, dat hij binnen het venster van het apparaat past. Op een iPhone wordt de pagina dus veel smaller dan op een iPad. Vervolgens kan de gebruiker inzoomen op het deel van de pagina dat hij of zij wil zien.
Dit betekent ook dat bij het openen van de pagina de tekst meestal heel erg klein wordt weergegeven. (Meestal, want niet alle browsers en apparaten doen het op dezelfde manier.) Niet erg fraai, maar bedenk maar 'ns 'n betere oplossing voor bestaande sites.
Nieuwe sites of pagina's kunnen echter wel rekening houden met de veel kleinere vensters van mobiele apparaten. Deze lay-out bijvoorbeeld past zich aan de breedte van het venster aan, ook bij heel smalle vensters. Maar die stomme mobiele browser weet dat niet, dus die gaat ervan uit dat ook de heel smalle lay-out 980 px breed is, en verkleint die dan. Dat is ongeveer even behulpzaam als de gedienstige kelner die behulpzaam de stoel naar achteren trekt, net als jij wilt gaan zitten.
Om de door de browser aangeboden hulp vriendelijk maar beslist te weigeren, wordt deze tag gebruikt. Hiermee geef je aan dat de pagina is geoptimaliseerd voor mobiele apparaten.
Een iPad in portretstand bijvoorbeeld is 768 px breed. De kreet width=device-width
zegt tegen de mobiele browser dat de breedte van de weer te geven pagina gelijk is aan de breedte van het apparaat. Voor een iPad in portretstand dus 768 px. En dat klopt, want de weer te geven pagina past zich automatisch aan de breedte van het apparaat aan, omdat de pagina altijd 100% breed is. Als het apparaat 300 px breed is, is de pagina ook 300 px breed, maar nog altijd 100%.
Simpeler gezegd: je zegt tegen het mobiele apparaat dat de pagina geen vaste breedte heeft, en dat het dus niet nodig is om de weergave aan te passen.
Steeds meer mobiele apparaten krijgen een hogere resolutiedichtheid: er staan meer pixels in een inch dan bij een monitor voor de desktop het geval is. Als een lijn 4 px breed is, en de pixels staan vier keer zo dicht op elkaar als op de desktop, zou de lijn maar 1 px breed zijn op een mobiel apparaat. Het is wel een supermooie en strakke lijn, omdat je met vier dicht bij elkaar staande pixels fantastisch scherp kunt weergeven. Alleen is de lijn helaas nauwelijks te zien, omdat hij in al z'n pracht maar 1 px breed is.
Ook niet echt geweldig. Daarom geven ook deze apparaten de breedte weer, alsof de resolutie een standaarddichtheid heeft. Een retina-scherm (een scherm met een hoge resolutiedichtheid) jokt een beetje. Ook een venster van 2048 of 4096 px breed beweert 1024 px breed te zijn. Hierdoor ziet een lijn van 4 px breed er ook op zo'n scherm als 4 px breed uit, en niet als 1 of 2 px breed.
Die hoge resolutiedichtheid heeft wel zin, maar dan op een andere manier. Letters bijvoorbeeld worden al jaren getekend aan de hand van wiskundige formules, het zijn allang geen statische afbeeldingen meer. Die formules kunnen prima met die hoge resolutiedichtheid uit de voeten: een ronding in een letter is veel fijner dan op de desktop. Ook voor hoge kwaliteit afbeeldingen is een hoge resolutiedichtheid zinvol. Het enige waar het niet zinvol is, is bij het aangeven van een maat. Een lijn van 4 px breed moet 4 px breed zijn, en niet 1 px breed in superkwaliteit.
Er staat nog een tweede deel in de tag: initial-scale=1
. Sommige mobiele apparaten zoomen een pagina gelijk in of uit. Ook weer in een poging behulpzaam te zijn. Ook dat is hier niet nodig, want de pagina past zich aan het apparaat aan. Er is ook een instructie om zoomen helemaal onmogelijk te maken, maar die gebruik ik niet. De bezoeker kan zelf nog gewoon zoomen, wat belangrijk is voor mensen die wat slechter zien.
<link rel="stylesheet" href="../../css/naam-van-stylesheet.css">
<!-- Instellingen voor Internet Explorer -->
<!--[if IE]>
<link rel="stylesheet" href="../../css/naam-van-ie-stylesheet.css">
<![endif]-->
Dit stukje code heeft in dit voorbeeldbestand geen enkel nut. Normaal genomen is het een verwijzing naar een extern stylesheet, waarin de style staat. In dit voorbeeld verwijst de href
naar een niet bestaand bestand. In html5 is de toevoeging type="text/css"
niet meer nodig, omdat dit standaard al zo staat ingesteld.
De bedoeling is dat je bovenstaande regels aanpast voor je eigen bestand. De hele style, die onder deze regels in de <head> staat, wordt dan in het externe bestand geplaatst, waar de href
naar verwijst. In dat bestand komt de style precies zo te staan, zoals die nu in de <head> staat. Het bestand moet eindigen op .css.
Voordeel van een externe stylesheet is onder andere, dat deze geldig is voor alle pagina's, waaraan deze is gelinkt. 'n Verandering in de lay-out hoef je dan maar op één enkele centrale plek te aan te brengen.
In die externe stylesheet zet je alles dat in dit voorbeeld tussen <style> en </style> staat (zonder deze begin- en eindregel).
De bovenste regel is voor de algemene stylesheet, geldig voor alle browsers. Dit is gewoon 'n link die naar 'n bestand elders verwijst, waar de css in staat. Op de plaats van "../../css/naam-van-stylesheet.css"
moet je pad naar en naam van jouw stylesheet invullen.
Het eigenaardige stukje code daaronder heet een 'conditional comment' en wordt door alle browsers gezien als commentaar, omdat het tussen <!--
en -->
staat. Maar Internet Explorer herkent het, door de extra toevoegingen, als speciaal voor Internet Explorer bedoeld en zal het dus uitvoeren. Het is veiliger dan een zogenaamde 'hack', waarbij vaak gebruik wordt gemaakt van 'n fout (bug) in de browser. Dit is opzettelijk aangebracht door Microsoft en zal dus blijven bestaan, terwijl 'n bug gerepareerd kan worden. Op deze manier kun je 'n stylesheet alleen voor Internet Explorer opnemen.
Dit stukje geldt voor alle versies van Internet Explorer, maar je kunt het ook per versie aangeven.
De link verwijst naar een aparte stylesheet voor Internet Explorer, waarin je css speciaal voor die browser zet. Op de plaats van "../../naam-van-ie-stylesheet.css"
moet je pad naar en naam van je stylesheet voor Internet Explorer invullen.
De link naar het aparte stylesheet voor Internet Explorer moet ná de link naar het algemene stylesheet komen, omdat de opdrachten voor Internet Explorer die uit de algemene stylesheet dan in principe overrulen.
<style>
In html5 is de toevoeging type="text/css"
niet meer nodig.
Voor de duidelijkheid staat de style hier in het bestand zelf, maar het is beter deze in een apart stylesheet te zetten, zoals hierboven beschreven. In die stylesheet komt alles wat tussen bovenstaande regel en </style> staat.
Technisch gezien is er geen enkel bezwaar om het in die stylesheet te zetten met dezelfde vreselijke lay-out, zoals ik die in dit voorbeeld gebruik. Maar als je dat doet, garandeer ik je hele grote problemen, omdat het volstrekt onoverzichtelijk is. Ik gebruik deze lay-out alleen, omdat het anders veel te veel regels worden.
Voorbeeld van 'n goede lay-out in je css:
div#header-buiten {
position: absolute;
right: 16px;
width: 100%;
height: 120px;
background: yellow;
}
div#header-binnen {
margin-left: 16px;
height: 120px;
text-align: center;
}
css voor alle breedtes
body
Het element waarbinnen de hele pagina staat. Veel instellingen die hier worden opgegeven, worden geërfd door de kinderen 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: #fcc;
Dit is de roze achtergrondkleur achter de afbeeldingen. In dit geval is het simpeler om die kleur gewoon aan de hele pagina te geven. Als je aan alle andere onderdelen een andere kleur geeft, blijft alleen de achtergrond achter de afbeeldingen roze.
Omdat er nogal veel met float
wordt gewerkt, kan deze achtergrondkleur niet aan <article> worden gegeven. <article> is door al het gefloat niet altijd even hoog als de erin zittende afbeeldingen. De <body> is dat per definitie wel.
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.
Ik gebruik hier % als eenheid, en voor alle andere lettergroottes gebruik ik em. Dat komt door Internet Explorer. Als ik als maateenheid iets als px neem, kunnen gebruikers van Internet Explorer de lettergrootte niet veranderen.
Maar als ik overal em neem als maateenheid, wat dan voor de hand zou liggen, kom ik in de problemen met versies van Internet Explorer ouder dan versie 8. De stappen van de verkleining of vergroting zijn in die browsers zo groot, dat 't gelijk onleesbaar klein of absurd groot is.
Als je nou echter bij body geen em gebruikt (font-size: 1.1em;
zou hetzelfde moeten zijn als font-size: 110%;
), dan is de lettergrootte in Internet Explorer te veranderen, en in oudere versies dan versie 8 zijn de tussenstappen teruggebracht tot normale grootte.
Dit werkt ook als je als lettergrootte 100% invult. Dat heeft geen enkele invloed op de lettergrootte, behalve dus dat de tussenstappen in oudere versies nu normaal werken.
In Internet Explorer 8 is deze bug eindelijk gerepareerd. Aangezien we waarschijnlijk nog vele jaren met oudere versies dan Internet Explorer 8 zitten opgescheept, zal deze truc ook nog jaren moeten worden toegepast.
margin: 0; padding: 0;
Verschillende browsers hebben verschillende standaard-instellingen hiervoor. Door ze gewoon op 0 te zetten, zijn ze overal hetzelfde. Bij deze lay-out is dat nog meer van belang dan normaal, omdat de pagina het hele venster van de browser vult. Als daar dan nog marges of padding bijkomen, kan dat soms overbodige horizontale scrollbalken opleveren, omdat het geheel net niet meer binnen het venster past.
header
Alle <header>'s. Dat is er hier maar een: het deel met de gele achtergrond.
background: yellow;
Gele achtergrond.
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 voorgrond- 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.
Ik heb dit ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.
text-align: center;
Tekst horizontaal centreren.
padding: 0 4px;
Omdat voor onder en links geen waarden zijn opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 4px 0 4px
in de volgorde boven - rechts - onder - links. Boven en onder geen padding, links en rechts 4 px padding.
Als eenheid neem ik de absolute eenheid px en geen procent of een andere relatieve eenheid, omdat de padding in een smal venster anders wel heel erg smal zou worden, en in een breed venster wel heel erg breed. Er staan ook geen andere dingen naast de header, waarvoor wat afstand nodig zou kunnen zijn.
Het gaat alleen maar om de afstand tussen de tekst en de rand van de header. Maar er is verder weinig op tegen, als je ook hier 'n relatieve eenheid als procent zou willen gebruiken.
#top
Het element met id="top". Dit is de link bovenin de header naar het menu onderin de pagina. Hij is alleen zichtbaar in vensters smaller dan 600 px, want alleen daar staat het menu onderaan de pagina.
background: black;
Zwarte achtergrond.
color: white;
Witte voorgrondkleur, waardoor ook de tekst wit wordt.
float: left;
Zo hoog mogelijk en dan zover mogelijk naar links zetten. Hierdoor komt hij helemaal in de linkerbovenhoek, links van de bovenste kop, te staan.
margin: 2px 0 0 2px;
Kleine marge aan boven- en linkerkant, zodat hij niet helemaal tegen de zijkant van het venster staat.
Als eenheid neem ik de absolute eenheid px en geen relatieve eenheid als procent of zo, omdat deze kleine afstand van 2 px altijd goed is.
padding: 3px 5px;
Omdat voor onder en links geen waarde is ingevuld, krijgen deze automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 3px 5px 3px 5px
in de volgorde boven - rechts - onder - links.
Dit is relatief vrij veel padding. Hierdoor wordt het zwarte vlak wat hoger en breder, want de zwarte achtergrondkleur loopt door onder de padding. Het valt hierdoor wat meer op, dan wanneer het niet groter zou zijn dan het woord 'Menu'. Bovendien is het nu makkelijker met de vinger te bedienen.
Als eenheid neem ik de absolute eenheid px en geen relatieve eenheid als procent, omdat de link een bepaalde maat moet hebben, groot genoeg om makkelijk met de vinger te bedienen, maar ook niet groter dan dat. Een absolute eenheid is daarvoor beter dan een relatieve.
h1
Belangrijkste kop van de pagina.
font-size: 1.2em;
Iets kleinere letter dan een <h1> standaard krijgt. Door de lettergrootte aan te passen met behulp van css, kan ik het uiterlijk aanpassen, terwijl voor zoekmachines, spraakbrowsers, en dergelijke toch duidelijk blijft dat het om de belangrijkste kop gaat.
Dit is een vrij kleine letter voor zo'n belangrijke kop. Voor grotere vensters wordt de lettergrootte later weer verhoogd.
Als eenheid neem ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
margin: 0;
Een <h> heeft standaard een marge aan boven- en onderkant. Die is hier niet welkom.
header p
De paragrafen binnen <header>.
margin: 0;
Een paragraaf heeft standaard een marge aan boven- en onderkant. Die wil ik hier niet hebben.
h2
Alle <h2>'s. Iets minder belangrijke kopjes dan de <h1>. Ze worden hier gebruikt om de verschillende onderdelen zoals header, footer en beschrijving aan te geven.
font-size: 1.1em;
Iets kleinere letter dan een <h2> standaard heeft. Door de lettergrootte aan te passen met behulp van css, kan ik het uiterlijk aanpassen, terwijl voor zoekmachines, spraakbrowsers, en dergelijke toch duidelijk blijft dat het om een belangrijk onderdeel gaat.
Als eenheid neem ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
margin: 0;
Een <h> heeft standaard een marge aan boven- en onderkant. Die is hier niet welkom.
#tekst
Het element met id="tekst". Dit is de div met de oranje achtergrond, waarbinnen de tekst staat.
background: orange;
Oranje achtergrond.
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 voorgrond- 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.
Ik heb dit ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.
max-width: 50em;
In brede vensters zou de tekst heel breed kunnen worden, waardoor je heel lange regels krijgt. Te lange regels zijn bijzonder lastig te lezen. Door een maximumbreedte aan #tekst
te geven, wordt dat voorkomen. Als eenheid neem ik em. Hierdoor wordt bij een grotere letter de regellengte ook langer, zodat het aantal tekens op een regel hetzelfde blijft, ongeacht de lettergrootte.
padding: 2% 1%;
Omdat voor onder en links geen waarde is ingevuld, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 2% 1% 2% 1%
in de volgorde boven - rechts - onder - links.
Als eenheid gebruik ik hier de relatieve eenheid procent, waardoor de padding in een breder venster groter is dan in een smaller venster. Dat is mooier dan een absolute eenheid, omdat er boven, onder en soms ook naast de tekst andere onderdelen van de pagina kunnen staan. In een groter venster wordt de padding nu ook groter, waardoor de verhoudingen beter bewaard blijven.
position: relative;
Onderaan div#tekst
staat div#onderaan
. Deze div wordt alleen gebruikt om de overgang van het oranje onder de tekst naar het roze onder de foto's te verzachten. div#onderaan
wordt absoluut gepositioneerd ten opzichte van div#tekst
. Om dat te kunnen doen, moet div#tekst
zelf absoluut, fixed of relatief zijn gepositioneerd. Omdat ik verder niets opgeef, heeft dit verder geen enkele invloed op div#tekst zelf.
h3
Alle <h3>'s. Deze kopjes worden hier gebruikt boven de hoofdstukjes binnen de Beschrijving van de onderdelen.
font-size: 1em;
Normaal genomen heeft een <h3> een iets grotere letter. Hier verander ik de lettergrootte naar standaard. Door de lettergrootte aan te passen met behulp van css, kan ik het uiterlijk aanpassen, terwijl voor zoekmachines, spraakbrowsers, en dergelijke toch duidelijk blijft dat het om kopjes gaat.
Als eenheid neem ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
margin-bottom: 0;
Een <h> heeft standaard een marge aan boven- en onderkant. De marge aan de onderkant is hier niet welkom.
article p
De paragrafen binnen <article>. Op deze pagina is maar één <article>, waarbinnen de tekst met oranje achtergrond en de afbeeldingen staan.
text-indent: 1em;
Elke eerste regel 1 em laten inspringen.
margin: 0;
Een <p> heeft standaard een marge aan boven- en onderkant. Die is hier niet welkom.
#onderaan

Het element met id="onderaan". Dit is een div die alleen voor de sier wordt gebruikt. Door de idiote achtergrondkleuren die worden gebruikt om de diverse onderdelen van elkaar te kunnen onderscheiden, grenst aan de onderkant de oranje achtergrond onder de tekst aan de roze achtergrond onder de foto's. Daar staan dan ook nog 'ns de foto's doorheen. Zelfs ik, met mijn onderontwikkelde kleurgevoel, krijg daar schele migraine van.
Daarom is onderaan een extra div neergezet, waarin de achtergrondkleur geleidelijk verandert van oranje naar roze. Ik zal niet zeggen dat het nu 'n Rembrandt is, maar, in alle bescheidenheid, 'n Karel Appel zou er nu toch wel voor tekenen.
Op de afbeelding hierboven is div#onderaan
doorzichtig gemaakt, boven de afbeeldingen gezet en van een blauwe border voorzien. Hierdoor is de omtrek zichtbaar geworden. Normaal genomen staat div#onderaan onder de foto's en zorgt alleen maar voor de overgang van oranje naar roze, zoals op de afbeelding op de stukken tussen de foto's nog is te zien.
background: -moz-linear-gradient(orange, #fcc); background: -ms-linear-gradient(orange, #fcc); background: -o-linear-gradient(orange, #fcc); background: -webkit-linear-gradient(orange, #fcc); background: linear-gradient(orange, #fcc);
Als je goed kijkt, zie je dat hier in feite vijf keer hetzelfde staat: background: linear-gradient (orange, #fcc);
. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-.
Tot de nieuwe eigenschappen van css3 horen gradiënten. Een gradiënt is een geleidelijk verlopende kleur. Een lineaire gradiënt is een in rechte lijn verlopende kleur. (Je hebt ook radiale gradiënten.)
In dit geval is aan de achtergrond van de div geen gewone kleur, maar een gradiënt gegeven. Omdat verder niets is opgegeven over de richting, verloopt deze gradiënt van boven naar onder, de standaardrichting. Bovenaan oranje, onderaan #fcc
, wat de roze kleur onder de foto's is. Vóór css3 kon zoiets alleen maar met een extra afbeelding worden gedaan.
Je kunt een gradiënt zelf uitvogelen, maar makkelijker is het, om gebruik te maken van een gradiënt-editor. Ik heb gebruik gemaakt van de gradiënt-editor op colorzilla.com.
width: 100%;
Een blok-element zoals een div wordt normaal genomen automatisch even breed als z'n ouder, dat is hier div#tekst
, dus dat komt prima uit. Helaas geldt dat niet als de div absoluut is gepositioneerd, zoals hier het geval is: hij wordt dan niet breder dan nodig is om de inhoud van de div weer te kunnen geven. div#onderaan
heeft geen enkele inhoud, want een achtergrondkleur telt niet mee en verder staat er niets in. Dus zou de breedte van deze div 0 worden.
Dat schiet niet op, als je de div juist wilt gebruiken om een achtergrondkleur zichtbaar te maken. Daarom geef ik handmatig een breedte op. Een breedte in procenten wordt altijd genomen ten opzichte van z'n ouder, hier div#tekst
. De verlopende achtergrondkleur beslaat nu dus de volle breedte van de div waar de tekst in zit: precies de bedoeling.
height: 100px;
Een blok-element zoals een div wordt normaal genomen precies zo hoog, als nodig is om de inhoud van de div weer te geven. Hier is geen inhoud, alleen een achtergrondkleur, en die telt niet mee als inhoud. De div zou dus een hoogte van 0 krijgen. Daarom geef ik met de hand een hoogte van 100 px op.
Ik gebruik hier de absolute eenheid px en geen relatieve eenheid als procent, omdat de overgang tussen de kleuren altijd even hoog mag zijn, ongeacht de hoogte van het venster van de browser.
Zonder css-gradiënt had ik een afbeelding moeten gebruiken om een verlopende kleur te krijgen. Dat is een extra aanroep naar de server. Bovendien zou die afbeelding moeten worden aangepast als de hoogte van div#onderaan
verandert. Bij een css-gradiënt kun je probleemloos de hoogte veranderen: de gradiënt verandert automatisch mee.
position: absolute;
Er wordt gepositioneerd ten opzichte van de eerste ouder die zelf een relatieve, absolute of fixed positie heeft. Dat is hier div#tekst
.
bottom: -100px;
De div is 100 px hoog. Als ik hem gewoon aan de onderkant binnen div#tekst
zou zetten, zou ik aan de onderkant van div#tekst
een lege ruimte van 100 px krijgen, omdat div#onderaan
de onderkant van div#tekst
100 px omlaag duwt. Pas daaronder zouden dan de afbeeldingen komen te staan. Hierdoor zou er altijd een extra lege ruimte van 100 px tussen tekst en afbeeldingen ontstaan.
Daarom wordt div#onderaan
absoluut gepositioneerd en 100 px naar beneden neergezet. Nu komt hij beneden div#tekst
te staan en ontstaat er geen extra lege ruimte aan de onderkant van div#tekst
.
(Dat de foto's toch af en toe toch onder div#onderaan
komen te staan, heeft niets met div#onderaan
te maken, maar met het floaten van de foto's in combinatie met de breedte van het venster van de browser. In een venster van bijvoorbeeld 1280 px breed worden, zonder zoomen en dergelijke, de foto's over div#onderaan
gezet. Zonder absolute positie zou ook hier een extra ruimte van 100 px boven de foto's verschijnen.)
left: 0;

Deze positie is ten opzichte van de eerste ouder die zelf een relatieve, fixed of absolute positie heeft. Dat is hier div#tekst
, die een padding heeft aan onder andere de linkerkant. Door die padding zou div#onderaan
iets te veel naar links komen te staan, waardoor je links door een 'kier' de roze achtergrondkleur achter de foto's te zien zou krijgen. Dat is op de afbeelding de roze baan tussen het groen en de verlopende kleur. Nu wordt div#onderaan
helemaal links binnen div#tekst
gezet en wordt deze roze streep voorkomen.
Omdat hierboven div#onderaan
100 % breed is gemaakt, is hij even breed als z'n ouder div#tekst
. Aan de rechterkant speelt hierdoor deze kier niet. Maar als div#onderaan
niet helemaal links zou worden neergezet, zou aan de rechterkant wel een stukje buiten div#tekst
komen te staan. Als het beginpunt links te veel naar rechts staat en div#onderaan
is even breed als div#tekst
, dan móét er rechts wel 'n stukje buiten div#tekst
uitsteken.
#foto
Het element met id="foto". Dit is de div waarbinnen de foto's staan.
position: relative;
div#foto
komt in de html na div#tekst
. Daardoor zou normaal genomen deze div, met de daarin zittende afbeeldingen, over div#tekst
komen te staan. En dus ook over de in div#tekst
zittende div#onderaan
.
div#tekst
heeft echter een relatieve positie gekregen. Daardoor krijgt div#tekst
ook automatisch een z-index van 1. De z-index geeft de volgorde in de hoogte aan: als twee of meer elementen op dezelfde plaats op het scherm staan, bepaalt de z-index welk van de elementen zichtbaar is.

z-index
komt div#onderaan
over de foto's te staan. div#onderaan
heeft even 'n blauw randje gekregen om hem zichtbaar te maken. Alleen kinderhaters kunnen tevreden zijn met dit resultaat.In dit geval kunnen div#onderaan
en div#foto
over elkaar heen komen te staan, op dezelfde plaats. div#onderaan
staat binnen div#tekst
, die een z-index van 1 heeft gekregen door z'n relatieve positie.
div#foto
heeft geen z-index, omdat hij niet relatief, absoluut of fixed is gepositioneerd.
Daardoor komt div#foto
, en dus ook de afbeeldingen en tekst daarbinnen, toch ónder div#onderaan
te staan, ondanks dat div#foto
in de volgorde van de html na div#onderaan
staat. Door ook div#onderaan
een relatieve positie te geven, krijgt ook div#foto
een z-index van 1. En staat nu dus boven div#onderaan
, want nu geldt de volgorde in de html gewoon weer.
#foto h2
De <h2>'s binnen het element met id="foto". Dat is er hier maar eentje: het kopje waar 'Foto's' in staat.
text-align: center;
Tekst horizontaal centreren.
Een <h2> is een blok-element en krijgt daardoor normaal genomen automatisch dezelfde breedte als z'n ouder. Als de afbeeldingen onder de tekst komen te staan, is de <h2> daardoor even breed als het venster en zal de tekst 'Foto's' dus horizontaal gecentreerd boven de foto's komen te staan.
Als de afbeeldingen naast de tekst komen te staan, staat het kopje horizontaal gecentreerd boven de ruimte naast de tekst. De <h2> wordt even breed als z'n ouder #foto
, maar omdat div#tekst
met de daarin zittende tekst nu naar links wordt gefloat, wordt bij het centreren alleen gekeken naar de lege ruimte rechts van de tekst. En staat het kopje dus weer gecentreerd boven de foto of foto's.
Het kopje staat dus altijd horizontaal gecentreerd boven de foto's, ongeacht de breedte van het venster van de browser.
#foto p
De paragrafen binnen het element met id="foto". Dat is er hier maar eentje. De tekst gelijk onder het kopje 'Foto's' staat erin.
text-align: center;
Tekst horizontaal centreren. Hiervoor geldt hetzelfde verhaal als gelijk hierboven bij #foto h2
.
text-indent: 0;
Bij article p hebben de <p>'s binnen <article> een text-indent gekregen. Omdat div#foto
binnen <article> staat, krijgen ook de <p>'s binnen div#foto
die text-indent. Dat is niet handig als je ook wilt centreren, dus weg ermee.
margin-bottom: 5px;
Kleine ruimte tussen de onderkant van de tekst en de bovenst afbeelding(en).
padding: 0 5px;
Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 5px 0 5px
in de volgorde boven - rechts - onder - links. Boven en onder geen padding, rechts en links 5 px.
figure
Alle <figure>'s. Binnen elk van deze elementen staat een <img> met een afbeelding en een <figcaption> met het bijbehorende onderschrift.
<figure> is een blok-element. Normaal genomen wordt een blok-element even breed als zijn ouder. Dat is hier div#foto
. Omdat deze div geen breedte heeft, wordt die normaal genomen ook weer even breed als z'n ouder. Dat is <article>. Ook die heeft geen breedte. Het wordt eentonig: ook die wordt daarom weer even breed als z'n ouder. Dat is div#wrapper
. En je raadt het al: die heeft ook weer geen breedte. De ouder van div#wrapper
is <body>, de pagina. Daardoor wordt div#wrapper
even breed als <body> en daarmee het venster van de browser. Via deze hele ketting terug wordt <figure> uiteindelijk ook even breed als het venster.
Voor bredere vensters is dit niet de bedoeling. Daarvoor volgt later aparte css. Maar voor smalle vensters is dit wel de bedoeling. De <figure> komt in smalle vensters beneden de tekst te staan en mag daar het hele venster in de breedte vullen.
text-align: center;
<figure> heeft een variabele breedte, afhankelijk van de breedte van het venster van de browser. Binnen <figure> staan <img>'s en <figcaption>'s met tekst, die altijd horizontaal gecentreerd moeten staan. Bovendien mogen die <img>'s en <figcaption>'s nooit breder zijn dan <figure>, maar de <figcaption>'s moeten wel altijd breed genoeg zijn om de onderschriften op één regel neer te kunnen zetten. Om het feest compleet te maken, blijkt Opera Mobiel op Android 4.0.3 dan ook nog 'ns spontaan de lettergrootte te verhogen.
Dan wordt ook nog van de <img> een blok-element gemaakt om van de ingebakken regelhoogte af te komen. En de <figcaption> heeft een witte achtergrond die netjes midden onder de afbeelding moet komen te staan.
Enig experimenteren met de combinatie <figure>, <img> en <figcaption> leerde dat dit de oplossing is voor een deel van het probleem. De onderschriften in de <figcaption>'s staan nu horizontaal gecentreerd.
Mogelijk had dit ook bij <figcaption> kunnen staan, maar dankzij een dreigende lichte overspannenheid, opgelopen bij het oplossen van dit raadsel, besloot ik het zo te laten. Het werkt. Overal. Punt.
margin: 0;
Een <figure> blijkt standaard een marge aan alle kanten te hebben. Dat is ongetwijfeld meestal fantastisch, maar hier even niet. Weg ermee.
figure img
De <img>'s binnen <figure>. Binnen elke <figure> staat één <img>: een thumbnail.
display: block;
In tegenstelling tot wat veel mensen denken, is een <img> een inline-element. Met wat aparte eigenschappen, maar het blijft een inline-element. Daardoor heeft een <img> een regelhoogte. Door die regelhoogte ontstaat ook wat ruimte onder de <img>, omdat staartletters als de 'g' en de 'p' iets onder de regel uitsteken.

Dat veroorzaakt problemen, omdat er een opening ontstaat tussen de afbeelding en de witte achtergrond van het onderschrift. De roze kier onder de foto op de afbeelding hiernaast is de ruimte die wordt gereserveerd voor de staartletters. Heel vriendelijk, maar in dit geval is er helemaal geen tekst, dus die ruimte is niet nodig.
De <img> staat in een <figure>. <figure> heeft niet apart een regelhoogte gekregen, maar elk blok-element waar een inline-element in staat, heeft automatisch een regelhoogte. Als je geen regelhoogte opgeeft, krijgt <figure> gewoon de standaardregelhoogte van ongeveer 1,2 em.
Een <img> is een inline-element. Een inline-element kan nooit een kleinere regelhoogte krijgen dan het blok-element waar hij in staat. De <img> kan dus nooit een regelhoogte van minder dan 1,2 em krijgen. (Dit lijkt misschien vreemd, maar meestal is dit juist handig.)
Ik kan de regelhoogte bij <figure> op 0 zetten, maar dan geldt die ook voor <figcaption>, want dat zit ook binnen <figure>. En daar wil ik wel een regelhoogte hebben.
De simpelste manier is om gewoon van de <img> zelf een blok-element te maken. Omdat er in de tot blok-element gepromoveerde <img> verder niets staat, is de regelhoogte nu weg. (In een <img> kán niets staan, omdat het gewoon een gesloten afbeelding is. Behalve de src
en de alt
en zo staat er niets binnen de <img>, en die hebben geen invloed op de regelhoogte.)
width: 200px;
Alle afbeeldingen zijn 200 px breed. Daarom is het in dit geval efficiënter om die breedte hier centraal op één plaats te geven, dan apart bij elke afbeelding.
Bovendien wordt de breedte soms iets aangepast aan de breedte van het venster van de browser. Een breedte die wordt opgegeven in de css overrulet weliswaar een breedte die wordt opgegeven bij de <img> in de html, maar het is nogal verwarrend als je op twee plaatsen een breedte opgeeft.
Ik geef geen hoogte op. Daardoor wordt de hoogte automatisch evenveel aangepast als de breedte, waardoor je een lachspiegel-effect voorkomt.
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 betekent: evenveel. De afbeelding staat nu altijd horizontaal gecentreerd binnen z'n ouder <figure>, ongeacht de breedte van <figure>.
Deze manier van horizontaal centreren van een blok-element (de <img> is hierboven veranderd in een blok-element) werkt alleen, als het te centreren blok-element een breedte heeft.
border:white solid 1px;
Klein wit randje rondom de afbeelding.
figcaption
Alle <figcaption>'s. Binnen elke <figure> staat één <figcaption>, waarbinnen het onderschrift onder de afbeelding staat.
background: white;
Witte achtergrond.
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 voorgrond- 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.
Ik heb dit ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin, als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.
width: 60%;
Een percentage in breedte wordt altijd genomen ten opzichte van de ouder van het element. Die ouder is hier <figure>. Het onderschrift wordt dus niet breder dan 60 procent van de breedte van <figure>. Dit is smaller dan de afbeelding, maar breed genoeg om alle onderschriften op één regel weer te kunnen geven.
max-width: 190px;
Dat verhaal hier gelijk boven over die breedte is mooi, maar het gaat niet altijd op. Als er, in een smal venster, maar één rij foto's onder de tekst staat, dan wordt <figure> even breed als het venster. Maar de <img> wordt nooit breder dan 200 px. Een <figcaption> van 60% breedte kan dan breder worden dan de erboven staande foto, waardoor ook de witte achtergrond breder wordt dan de foto. En dat is foeilelijk. Voor dit soort situaties geef ik een maximumbreedte op, die net iets minder is dan de breedte van 200 px van de <img>.
font-size: 0.7em;
Kleinere letter. Als eenheid neem ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
font-style: italic;
Cursief.
margin: 0 auto 10px;
Omdat voor links geen waarde is ingevuld, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 0 auto 10px auto
in de volgorde boven - rechts - onder - links.
Aan de onderkant een marge van 10 px, waardoor er wat ruimte komt tussen het onderschrift en de afbeelding eronder.
Rechts en links auto
, wat hier betekent: evenveel. Hierdoor staat de <figcaption> altijd horizontaal gecentreerd binnen <figure>. En omdat bij figure text-align: center;
is opgegeven, staat de tekst weer horizontaal gecentreerd binnen <figcaption>.
Deze manier van horizontaal centreren van een blok-element (<figcaption> is een blok-element) werkt alleen, als het te centreren blok-element een breedte heeft.
Omdat bij figure img ook de <img>'s horizontaal gecentreerd zijn binnen <figure>, staan de onderschriften ook ten opzichte van de <img>'s horizontaal gecentreerd.
border: black solid;
Zwart randje. De breedte geef ik gelijk hieronder op.
border-width: 0 1px 1px;
De kleur en stijl heb ik gelijk hierboven al opgegeven.
Omdat voor links geen waarde is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 0 1px 1px 1px
in de volgorde boven - rechts - onder - links. Aan alle kanten een border, behalve aan de bovenkant.
Deze manier van een border opgeven is simpeler dan het schrijven van css voor drie aparte borders.
footer p
De paragrafen binnen <footer>.
margin: 0 4px;
Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 4px 0 4px
in de volgorde boven - rechts - onder - links.
Een <p> heeft van zichzelf een marge aan boven- en onderkant. Die wordt hier weggehaald.
Links en rechts een kleine afstand tussen <p>'s, en dus de tekst daarin, en zijkant van de footer.
css voor vensters breder dan 600 px
@media screen and (min-width: 600px)
De css die hier tot nu toe staat, geldt voor alle browservensters. De css die hieronder staat, geldt alleen voor browservensters breder dan 600 px. Voor een deel is dit nieuwe css, voor een deel wordt hierboven staande css aangepast.
@media
: geeft aan dat het om css gaat, die alleen van toepassing is, als aan bepaalde voorwaarden wordt voldaan. Al langer bestond de mogelijkheid om met behulp van zo'n 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. Als je wilt printen, is het beter een stylesheet daarvoor te baseren op de algemene css die hierboven staat.
and
: er komt nog een voorwaarde, waar aan moet worden voldaan.
(min-width: 600px)
: het browservenster moet minstens 600 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: 600px) {
body {color: silver;}
(...) rest van de css voor deze @media-regel (...)
footer {color: gold;}
}
Voor de eerste css binnen deze media-regel staat dus een extra {
, en aan het eind staat een extra }
.
#wrapper
Het element met id="wrapper". Dit is een div, waarbinnen tekst, afbeeldingen en menu staan. Deze div vult de ruimte tussen <header> en <footer>.
position: relative;
Het menu wordt gepositioneerd ten opzichte van deze div. Om dat te kunnen doen, moet deze div zelf een relatieve, absolute of fixed positie hebben. Omdat ik hier verder niets bij opgeef, heeft dit voor div#wrapper
zelf verder geen enkele invloed.
#top
Het element met id="top". Dit is de link bovenin de header naar het menu onderin de pagina. Hij is alleen zichtbaar in vensters smaller dan 600 px, want alleen daar staat het menu onderaan de pagina.
display: none;
In vensters breder dan 600 px staat het menu bovenaan de pagina, of het staat op een vaste plaats aan de linkerkant en scrolt niet mee. In beide gevallen is de link naar het menu aan de onderkant van de pagina niet nodig, dus wordt hij verborgen.
h1
Belangrijkste kop van de pagina.
font-size: 1.6em;
Hierboven is de lettergrootte verkleind tot 1,2 em. Dat is veel kleiner dan de standaardlettergrootte van een <h1>. In vensters breder dan 600 px is er meer ruimte, daarom wordt de lettergrootte hier weer verhoogd. 1,6 em is nog steeds kleiner dan de standaardlettergrootte van een <h1>, maar die is ook wel érg groot.
Door de lettergrootte aan te passen met behulp van css, kan ik het uiterlijk aanpassen, terwijl voor zoekmachines, spraakbrowsers, en dergelijke toch duidelijk blijft dat het om de belangrijkste kop gaat.
Als eenheid gebruik ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
h2
Alle <h2>'s. Iets minder belangrijke kopjes dan de <h1>. Ze worden hier gebruikt om de verschillende onderdelen zoals header, footer en beschrijving aan te geven.
font-size: 1.2em;
Hierboven is de lettergrootte verkleind tot 1,1 em. Dat is veel kleiner dan de standaardlettergrootte van een <h2>. In vensters breder dan 600 px is er meer ruimte, daarom wordt de lettergrootte hier weer verhoogd. 1,2 em is nog steeds kleiner dan de standaardlettergrootte van een <h2>, maar hier groot genoeg.
Door de lettergrootte aan te passen met behulp van css, kan ik het uiterlijk aanpassen, terwijl voor zoekmachines, spraakbrowsers, en dergelijke toch duidelijk blijft dat het om een belangrijk onderdeel gaat.
Als eenheid gebruik ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.
article
Alle <article>'s. Dat is er hier maar eentje. De tekst en de afbeeldingen staan erin.
padding-top: 2.2em;
Verderop wordt het menu absoluut gepositioneerd aan de bovenkant van <article>, in de vorm van een horizontale balk met knoppen. Daardoor zou het over de tekst in <article> heen komen te staan. Deze padding zet de tekst een stukje lager, zodat dat wordt voorkomen.
figure
Alle <figure>'s. Binnen elke <figure> staan een <img> en een <figcaption> met het onderschrift bij de afbeelding.
width: 25%;
Bovenin div#tekst
, waarin de tekst met de oranje achtergrond staat. Onder div#tekst
staan de <figure>'s met de afbeeldingen. Omdat de tekst de volle breedte van het venster vult, is er geen ruimte naast de tekst voor afbeeldingen. Dat komt pas in nog bredere vensters.
De <figure>'s met de afbeeldingen komen dus noodgedwongen onder de tekst te staan. Door ze 25% breed te maken, passen er precies vier naast elkaar, netjes verdeeld over de breedte van het venster van de browser.
float: left;
Een <figure> is een blok-element. Een blok-element komt normaal genomen op een nieuwe regel te staan. Door ze naar links te floaten, komen ze naast elkaar te staan. En omdat elke <figure> hierboven 25% breed is gemaakt, passen er precies vier naast elkaar op elke regel.
figure img
Alle <img>'s binnen een <figure>. Binnen elke <figure> staat een <img>: de kleine foto's.
max-width: 94%;

De <figure>'s hebben bij figure een breedte van 25% gekregen, zodat er vier naast elkaar passen. Maar ze staan dan wel helemaal tegen elkaar aan. Op de afbeelding hebben de <figure>'s een blauwe outline gekregen, zodat dat zichtbaar wordt.
Door de <img> een maximumbreedte van 94% te geven, ontstaat er toch wat ruimte tussen de afbeeldingen. Een breedte in procenten wordt altijd genomen ten opzichte van de ouder, dus de <img> is altijd minstens 6% smaller dan de <figure>.
Bij figure img is de <img> horizontaal gecentreerd binnen <figure>, zodat de marge links en rechts altijd even groot is. In bredere browservensters wordt de <figure> breder. Maar de <img> wordt nooit breder dan de 200 px, die de afbeelding breed is, en blijft altijd horizontaal gecentreerd binnen <figure>.
figcaption
Alle <figcaption>'s. Binnen elke <figure> staat een <img>. Het onderschrift bij de <img> staat in een <figcaption> binnen de <figure>.
width: 70%;
Bij de css voor alle breedtes hierboven is de breedte 60% gemaakt. Dat is in principe genoeg om het onderschrift op één regel weer te geven.

Maar Opera Mobiel op Android 4.0.3 maakt de letters om een of andere reden groter, en dan passen de onderschriften niet meer op één regel. Door de breedte van de <figcaption> iets groter te maken, past alles weer op dezelfde regel.
Als een onderschrift niet op één regel past, verstoort dit het floaten van de <figure>'s. De nieuwe regel met <figure>'s wordt niet aan het begin begonnen, maar gelijk na het onderschrift dat op twee regels staat. Daarom is het beter dat te voorkomen. Overigens gebeurt dit in meerdere browsers, maar dan pas als de letters heel sterk worden vergroot.
#naar-top
Het element met id="naar-top". Dit is de laatste <li> binnen het menu met de tekst 'Top'. Als het menu onderaan de pagina staat, zoals in browservensters smaller dan 600 px het geval is, kun je met deze link weer terug naar boven gaan.
Omdat het de laatste <li> binnen de <ul> met het menu is, zou je ook de pseudo-class :last-child
kunnen gebruiken, maar die wordt niet herkend door Internet Explorer 7 en 8. Daarom is een class gebruikt.
display: none;
De link naar boven is alleen nodig in vensters smaller dan 600 px, waar het menu onderaan komt te staan. In bredere vensters is hij overbodig en kan dus worden verborgen.
css voor vensters breder dan 810 px
@media screen and (min-width: 810px)
De css die hier tot nu toe staat, geldt ook voor browserfvensters breder dan 810 px. Elk venster dat minimaal 600 px breed is, is immers ook 810 px breed. De css die hieronder staat, geldt alleen voor browservensters breder dan 810 px. Voor een deel is dit nieuwe css, voor een deel wordt hierboven staande css aangepast.
De opbouw van de regel staat beschreven bij @media screen and (min-width 600px), het enige verschil is dat het hier om een minimumbreedte van 810 px gaat.
.no-touch header
De <header>'s binnen een element met class="no-touch". Er is hier maar één <header>, het vlak met de gele achtergrond.
Als je in de broncode kijkt, zul je de class "no-touch" niet vinden. Deze class wordt door het JavaScript modernizr toegevoegd aan <html> bij browsers, die touch events niet herkennen. In principe werkt deze regel daardoor alleen in browsers, die touch events niet herkennen. Dat zijn (meestal) mobiele browsers.
Hoe dat precies werkt, staat bij Touchscreens herkennen met behulp van modernizr.
Om <html class="no-touch">
te kunnen zien in de broncode, moet je de gegenereerde code bekijken. In Firefox kan dat met behulp van bijvoorbeeld de extensies Firebug of Web Developer onder View Source → View Generated Source. Of met het in Firefox ingebouwde 'Element inspecteren'. Andere browsers hebben andere manieren om gegenereerde code te bekijken.
Doordat div#wrapper
hieronder bij .no-touch #wrapper absoluut wordt gepositioneerd, scrollen tekst en foto's binnen die div. Daardoor blijft de header, ook bij scrollen, bovenaan het venster van de browser staan. Mobiele browsers hebben vaak moeite met dit soort constructies. Omdat mobiele browsers meestal touch events herkennen, missen die de class "no-touch" in <html> en negeren deze regel dus.
height: 7em;
Hoogte. Omdat deze css voor bredere vensters is, is er wat meer ruimte voor een iets hogere header dan misschien strikt nodig is. Als eenheid wordt em gebruikt, zodat bij een andere lettergrootte de verhoudingen zo goed mogelijk intact blijven.
overflow: auto;
Als de letters heel sterk worden vergroot, kan de tekst beneden de header komen te staan, over de rest van de pagina heen. Dit voorkomt dat. Als de tekst nu niet in de header past, verschijnt naast de header een verticale scrollbalk.
Dit werkt alleen maar, als het element een hoogte heeft, zoals hier het geval is.
border-bottom: black solid 1px;
Zwart randje aan de onderkant.
position: relative;
De header heeft een z-index nodig, omdat je anders het zwarte randje aan de onderkant niet overal ziet. Een z-index kan alleen worden gegeven aan een element dat absoluut, relatief of fixed is gepositioneerd. Omdat ik hier verder niets bij opgeef, heeft dit verder geen enkele invloed op <header>.
z-index: 10;
<header> is 7 em hoog. div#wrapper
wordt hieronder absoluut gepositioneerd op 7 em van de bovenkant, dus sluit precies aan op <header>. Maar <header> heeft nog een border van 1 px aan de onderkant. Die komt nog bij die 7 em. Daardoor staat div#wrapper
precies over die zwarte border heen.
Door <header> een hogere z-index te geven, komt hij boven div#wrapper
te staan, en de zwarte border aan de onderkant dus ook. Een z-index van 1 zou ook al genoeg zijn, maar de afdeling Schade en Schande heeft geleerd dat het goed is om openingen in de volgorde van de z-index te houden, zodat je er later nog 'n z-index tussen kunt stoppen.
(Ooit honderden z-indexen aangebracht. Netjes op volgorde. En toen moest er helemaal aan het begin eentje tussen. Dat doe je maar één keer...)
Een z-index kan alleen worden gebruikt als het element relatief, absoluut of fixed is gepositioneerd. Gelijk hierboven is het relatief gepositioneerd, dus dat is geregeld.
.no-touch #wrapper
Het element met id="wrapper" binnen een element met class="no-touch". Dit is een div, waarbinnen tekst, afbeeldingen en menu staan. Deze div vult de ruimte tussen <header> en <footer>.
Als je in de broncode kijkt, zul je de class "no-touch" niet vinden. Deze class wordt door het JavaScript modernizr toegevoegd aan <html> bij browsers, die touch events niet herkennen. In principe werkt deze regel daardoor alleen in browsers, die touch events niet herkennen. Dat zijn (meestal) mobiele browsers.
Hoe dit verder precies werkt, staat bij Touchscreens herkennen met behulp van modernizr.
Om <html class="no-touch">
te kunnen zien in de broncode, moet je de gegenereerde code bekijken. In Firefox kan dat met behulp van bijvoorbeeld de extensies Firebug of Web Developer onder View Source → View Generated Source. Of met het in Firefox ingebouwde 'Element inspecteren'. Andere browsers hebben andere manieren om gegenereerde code te bekijken.
Omdat div#wrapper
hieronder absoluut wordt gepositioneerd, scrollen tekst en foto's binnen die div. Daardoor blijven header, menu en footer altijd op dezelfde plaats staan. Mobiele browsers hebben vaak moeite met dit soort constructies. Omdat mobiele browsers meestal touch events herkennen, missen die de class "no-touch" in <html> en negeren deze regel dus.
width: 100%;
div#wrapper
is een blok-element en zou automatisch dezelfde breedte als z'n ouder moeten krijgen. Dat is <body>, dus de div zou even breed als de pagina moeten worden. Dat is ook zo, maar niet in Internet Explorer 9.
In Internet Explorer 9 wordt de pagina ongeveer drie keer zo breed als het venster van de browser. Pardon? Om het spannend te maken wordt hij, ogenschijnlijk willekeurig, af en toe ook wel 'ns veel smaller dan het venster. De oorzaak kan ik niet vinden, want zodra de debugger aan staat, voelt de bug kennelijk nattigheid en verstopt zich, waardoor de pagina correct wordt weergegeven. Maar alleen met de debugger aan dus.
Door een breedte op te geven, verdwijnt deze bug. Omdat dit de normale situatie is, hebben andere browsers hier verder geen last van.
position: absolute;
Door div#wrapper
absoluut te positioneren tussen de header en de footer, wordt hij op een bepaalde plaats op het scherm gezet. Vervolgens worden binnen div#wrapper
de tekst en de afbeeldingen binnen <article> gezet. (<article> is eigenlijk 'n gewone div, maar dan met semantische betekenis.)
Door <article> even hoog te maken als div#wrapper
en overflow
op auto
te zetten bij <article>, krijgt <article> bij voldoende content een verticale scrollbalk. Als je gaat scrollen, scrol je alleen de inhoud van <article>. div#wrapper
blijft op z'n plaats staan. Hierdoor blijven ook header, footer en menu op hun plaats staan: alleen de tekst en de foto's scrollen.
top: 7em;
<header>, dat gelijk boven div#wrapper
staat, is 7 em hoog. Daarom moet div#wrapper
op 7 em vanaf de bovenkant beginnen om goed op <header> aan te sluiten.
bottom: 5em;
<footer>, dat gelijk onder div#wrapper
staat, is 5 em hoog. Daarom moet div#wrapper
tot 5 em vanaf de onderkant doorlopen om goed op <footer> aan te sluiten.
.no-touch article
De <article>'s binnen een element met class="no-touch". Er is hier maar één <article>. De tekst en de afbeeldingen staan erin.
Als je in de broncode kijkt, zul je de class "no-touch" niet vinden. Deze class wordt door het JavaScript modernizr toegevoegd aan <html> bij browsers, die touch events niet herkennen. In principe werkt deze regel daardoor alleen in browsers, die touch events niet herkennen. Dat zijn (meestal) mobiele browsers.
Hoe dit verder precies werkt, staat bij Touchscreens herkennen met behulp van modernizr.
Om <html class="no-touch">
te kunnen zien in de broncode, moet je de gegenereerde code bekijken. In Firefox kan dat met behulp van bijvoorbeeld de extensies Firebug of Web Developer onder View Source → View Generated Source. Of met het in Firefox ingebouwde 'Element inspecteren'. Andere browsers hebben andere manieren om gegenereerde code te bekijken.
Bij .no-touch #wrapper is div#wrapper
absoluut gepositioneerd, wat de mogelijkheid geeft om alleen tekst en foto's te scrollen, terwijl header, menu en footer altijd op dezelfde plaats blijven staan. Mobiele browsers hebben vaak moeite met dit soort constructies. Omdat mobiele browsers meestal touch events herkennen, missen die de class "no-touch" in <html>.
Daardoor wordt door die browsers deze regel genegeerd, en dat is precies de bedoeling. Als div#wrapper
niet absoluut is gepositioneerd, is deze regel ook niet nodig.
width: 80%;
Een breedte in procenten wordt altijd genomen ten opzichte van de ouder van het element. Dat is hier div#wrapper
, dat de volle breedte van de pagina heeft: 100%. Door <article> een vijfde smaller te maken, komt er ruimte vrij om het menu naast <article> met de daarin zittende tekst en afbeeldingen te kunnen zetten.
height: 100%;

In dit voorbeeld staan behoorlijk wat tekst en afbeeldingen binnen <article>. Normaal genomen zijn die altijd zichtbaar, ook als ze niet binnen het element passen. Normaal genomen is dat ook prima. Het is meestal beter dat de lay-out misschien wat wordt verstoord, dan dat er tekst en dergelijke gewoon verdwijnt.
Hier is dit echter niet de bedoeling. Als de tekst en dergelijke niet in het venster van de browser past, moet er rechts van <article> een scrollbalk verschijnen. Om dat voor elkaar te krijgen, moet een hoogte worden opgegeven.
Als je geen hoogte aan <article> geeft, gebeurt er wat op de afbeelding is te zien. Omdat niet alles in het venster past, verschijnt er netjes een verticale scrollbalk. Maar dat is geen scrollbalk bij <article>, het is de standaardscrollbalk die verschijnt als niet alles in het venster past. Een scrollbalk die bij de pagina, bij <body> hoort.
Omdat niet alleen <article>, maar de hele <body> scrolt, scrollen ook <header>, <nav> en <footer> mee. Vooral het meescrollen van <footer> is rampzalig.
Door aan <article> een hoogte te geven, is duidelijk dat <article> een scrollbalk moet krijgen, en niet de hele pagina.
Een hoogte in procenten wordt altijd genomen ten opzichte van de ouder, hier div#wrapper
, die tussen <header> en <footer> staat. Als <article> even hoog wordt als div#wrapper
, komt <article> daardoor ook tussen <header> en <footer> te staan. En daarmee een eventuele scrollbalk naast <article> ook.
Om de scrollbalk te laten verschijnen, moet ook de eigenschap overflow
nog worden gebruikt, wat gelijk hieronder gebeurt.
overflow: auto;
Samen met de gelijk hierboven opgegeven hoogte zorgt deze eigenschap voor het verschijnen van een verticale scrollbalk naast <article>, als er zoveel tekst en dergelijke binnen <article> staat, dat dit niet in één keer zichtbaar is.
Standaard staat overflow
op visible
: als de content niet allemaal binnen het element past, laat het dan toch zien. Dat is normaal genomen beter dan dat het verdwijnt. Door overflow
op auto
te zetten, verschijnt een scrollbalk, maar alleen als dat nodig is, als er genoeg tekst en dergelijke aanwezig is.
Hiervoor is ook nog een hoogte nodig, want anders weet de browser niet hoe hoog het element is en wanneer er een scrollbalk moet verschijnen.
margin-left: 20%;
Normaal genomen wordt een element gewoon links in de ouder, hier div#wrapper
, neergezet. Hiermee wordt de linkerkant van <article> 20% naar links geschoven, waardoor aan de linkerkant ruimte vrijkomt voor het menu.
Door als eenheid voor de vrije ruimte procenten te nemen, past de breedte zich aan de breedte van het venster van de browser aan, waardoor de verhoudingen beter intact blijven.
De <nav> waarin het menu staat wordt maar 18% breed. Maar door de padding en border die daar nog bij komen, sluiten <nav> en <article> toch goed op elkaar aan.
(Feitelijk staat <article> 'n heel klein fiebeltje achter <nav>, omdat procenten en px nou eenmaal moeilijk optellen. Maar daar zie je niets van. En bij 'n site geldt, anders dan bij religie: wat je niet ziet, bestaat niet. Dat optellen van verschillende soorten eenheden gaat in css3 ook ingrijpend verbeteren met behulp van calc()
, maar op dit moment wordt dat nog onvoldoende ondersteund door de verschillende browsers.)
padding-top: 0;
Bij article is bovenaan een padding van 2,2 em gegeven om ruimte te maken voor het menu, dat in smallere vensters bovenaan komt te staan. Hier wordt het menu links neergezet en is die padding dus niet nodig.
#tekst
Het element met id="tekst". Binnen <article> staan twee belangrijke divs: div#tekst
, waarin de tekst staat, en div#foto
, waar verrassenderwijs de foto's in blijken te staan.
Door de opdeling in twee divs kunnen de foto's, als het venster breed genoeg is, hierdoor naast de tekst komen te staan.
width: 73%;
Een breedte in procenten wordt altijd genomen ten opzichte van de ouder, dat is hier <article>. Voor de tekst wordt driekwart van de breedte van <article> gereserveerd, waardoor er aan de rechterkant van de tekst 'n kwart overblijft om foto's in te zetten.
De hier opgegeven breedte is slechts 73%, maar bij #tekst is een padding rechts en links opgegeven van 1%. Samen maakt dat 75%.
Binnen elke <figure> staat één foto met onderschrift. <figure> heeft bij figure een breedte van 25% gekregen, waardoor er precies één kolom met foto's naast de tekst past.
float: left;
Normaal genomen worden blok-elementen op een nieuwe regel gezet. Dit geldt ook voor de blok-elementen, waar de foto's in staan. Door div#tekst
naar links te floaten, gebeurt dat niet. Als er rechts van div#tekst
genoeg ruimte is, wordt die nu opgevuld. In dit geval met de foto's en de bijbehorende tekst.
#foto h2
De <h2>'s in het element met id="foto". Dat is hier maar één kopje met de tekst 'Foto's'.
Een <h2> is een blok-element en zou normaal genomen op een nieuwe regel onder de tekst komen te staan. Maar de tekst in div#tekst
is naar links gefloat, en daardoor komt de <h2> rechts naast de tekst te staan.
margin-top: 2%;
Kleine afstand tussen kopje en bovenkant van de kolom met foto's. Met deze marge komt het kopje gelijk te staan met de kopjes boven menu en tekst. Er is geen speciale reden om procent te gebruiken als eenheid, ik had ook em kunnen gebruiken.
Als het maar 'n relatieve eenheid is die mee verandert met de lettergrootte. Bij een absolute eenheid als px worden de verhoudingen in Safari en Internet Explorer verstoord bij een andere lettergrootte.
#foto p
De paragrafen binnen het element met id="foto". Dat is er hier maar eentje. De tekst boven de foto's staat erin.
width: 24%;
Er is ruimte voor een breedte van 25%, omdat de tekst 75% breed is. Door de <p> iets smaller te maken, krijg ik links en rechts ruimte voor een kleine marge.
float: left;
Zover mogelijk omhoog en dan zover mogelijk naar links zetten.
Ook zonder float
zou de tekst in deze paragraaf rechts van de tekst met de oranje achtergrond komen te staan, omdat div#tekst
, waarin de tekst met de oranje achtergrond zit, naar links is gefloat.
Maar de tekst uit deze <p> beslaat dan gewoon de volle breedte van de lege ruimte boven de foto's, en dat is te breed. De tekst uit deze <p> kan dan helemaal tegen de tekst met de oranje achtergrond komen te staan, of tegen de rechterkant van het venster. Daarom geef ik deze paragraaf hieronder een breedte, die iets minder is dan de breedte van de foto's. Hierdoor komt er ruimte voor een marge links en rechts.
Als ik dat doe, moet ik echter ook deze <p> floaten, omdat hij anders onder div#tekst
met de tekst op de oranje achtergrond komt te staan.
Waarom een marge wordt gebruikt en geen simpele padding, wordt bij de hieronder staande eigenschappen van #foto p
toegelicht.
margin: 0 0.5%;
Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 0.5% 0 0.5%
in de volgorde boven - rechts - onder - links.
Een <p> heeft van zichzelf een marge aan boven en onderkant. Die wordt hier weggehaald.
Links en rechts een kleine marge van 0,5%, zodat er wat ruimte links en rechts van de tekst komt.
padding: 0;
Bij #foto p is links en rechts een padding opgegeven. Die is nu overbodig, omdat al wat ruimte links en rechts is gekregen met behulp van de hierboven opgegeven marge.
Je zou denken dat ik dan, in plaats van al dat ingewikkelde gedoe hierboven met 'n marge, beter een padding aan de tekst had kunnen geven. Dat is ook zo. Alleen werkt dat niet. Door al het gefloat krijg je bij gebruik van een padding alleen rechts een padding, links niet. Dus links kan de tekst uit de <p> dan nog steeds tegen de tekst met de oranje achtergrond komen te staan.
.no-touch nav li:first-child a
De <a>'s binnen een <nav>, die weer binnen een element met class="no-touch" zit. Maar alleen als de <li> het eerste kind van de <nav> is. Er is hier maar één <nav>, waarin het menu zit. Binnen de eerste <li> zit de <a>, waarin 'Link een' staat. (Ja, ik heb een groots talent voor het bedenken van originele namen, al zeg ik het zelf.)
Als je in de broncode kijkt, zul je de class "no-touch" niet vinden. Deze class wordt door het JavaScript modernizr toegevoegd aan <html> bij browsers, die touch events niet herkennen. In principe werkt deze regel daardoor alleen in browsers, die touch events niet herkennen. Dat zijn (meestal) mobiele browsers.
Hoe dit verder precies werkt, staat bij Touchscreens herkennen met behulp van modernizr.
Om <html class="no-touch">
te kunnen zien in de broncode, moet je de gegenereerde code bekijken. In Firefox kan dat met behulp van bijvoorbeeld de extensies Firebug of Web Developer onder View Source → View Generated Source. Of met het in Firefox ingebouwde 'Element inspecteren'. Andere browsers hebben andere manieren om gegenereerde code te bekijken.
Bij .no-touch #wrapper is div#wrapper
absoluut gepositioneerd, wat de mogelijkheid geeft om alleen tekst en foto's te scrollen, terwijl header, menu en footer altijd op dezelfde plaats blijven staan. Mobiele browsers hebben vaak moeite met dit soort constructies. Omdat mobiele browsers meestal touch events herkennen, missen die de class "no-touch" in <html>.
Daardoor wordt door die browsers deze regel genegeerd, en dat is precies de bedoeling. De ronde hoeken die hier worden gegeven, moeten alleen worden aangebracht als <nav> links van de tekst wordt gepositioneerd.
border-radius: 10px 10px 0 0;
Links- en rechtsboven ronde hoek, rechts- en linksonder niet.
Omdat maar één maat is opgegeven, worden de ronde hoeken even hoog als breed. (Je kunt ook twee maten opgeven, dan krijg je 'n ellipsvormige hoek.)
In tegenstelling tot wat de naam van deze eigenschap suggereert, krijgen ook achtergrondkleur en een eventuele achtergrond-afbeelding ronde hoeken.
border: black solid 1px;
Bij .no-touch nav a hebben alle <a>'s een zwarte border gekregen, maar niet aan de bovenkant. Bij de bovenste knop zie je dat, omdat daar de horizontale border aan de bovenkant ontbreekt. Die wordt hier alsnog gegeven. Omdat er aan vier kanten een border moet komen, kan ik gewoon border
gebruiken, maar border-top
zou hier ook genoeg zijn.
.no-touch nav li:nth-last-child(2) a
Deze selector geldt alleen voor de links binnen één specifieke <li> binnen <nav>. Het gaat om de tweede <li> binnen <nav>, van achteraf geteld. :nth-last-child
wil simpelweg zeggen: van achteraf geteld. En de 2 staat voor: de tweede. (Je kunt ook ingewikkelder dingen met deze selector (eigenlijk een pseudo-class) doen, maar dat gebeurt hier niet.)
Het geheel moet binnen een element met class="no-touch" zitten.
In dit geval is het beter om de links vanaf de achterkant te tellen. Het gaat namelijk altijd om de een-na-laatste link, waar iets mee moet gebeuren. Als er ooit 'n link wordt tussengevoegd of weggehaald, zou je makkelijk kunnen vergeten deze selector aan te passen. Nu hoeft hij nooit aangepast te worden, want de een-na-laatste link is altijd de een-na-laatste, hoeveel links er ook nog bij zouden komen of zouden verdwijnen.
Als je in de broncode kijkt, zul je de class "no-touch" niet vinden. Deze class wordt door het JavaScript modernizr toegevoegd aan <html> bij browsers, die touch events niet herkennen. In principe werkt deze regel daardoor alleen in browsers, die touch events niet herkennen. Dat zijn (meestal) mobiele browsers.
Hoe dit verder precies werkt, staat bij Touchscreens herkennen met behulp van modernizr.
Om <html class="no-touch">
te kunnen zien in de broncode, moet je de gegenereerde code bekijken. In Firefox kan dat met behulp van bijvoorbeeld de extensies Firebug of Web Developer onder View Source → View Generated Source. Of met het in Firefox ingebouwde 'Element inspecteren'. Andere browsers hebben andere manieren om gegenereerde code te bekijken.
Bij .no-touch #wrapper is div#wrapper
absoluut gepositioneerd, wat de mogelijkheid geeft om alleen tekst en foto's te scrollen, terwijl header, menu en footer altijd op dezelfde plaats blijven staan. Mobiele browsers hebben vaak moeite met dit soort constructies. Omdat mobiele browsers meestal touch events herkennen, missen die de class "no-touch" in <html>.
Daardoor wordt door die browsers deze regel genegeerd, en dat is precies de bedoeling. De ronde hoeken die hier worden gegeven, hebben alleen nut als <nav> links van de tekst wordt gepositioneerd.
border-bottom: black solid 1px;
Hé, de <a>'s hadden toch al 'n border aan de onderkant gekregen bij .no-touch nav a?
Ja, maar dat is niet voldoende voor deze <a>. Eerder in de css is bij nav li:nth-last-child(2) a specifiek bij deze <a> de border aan de onderkant weggehaald.
De border is weggehaald met de selector nav li:nth-last-child(2) a
. Daarin zitten drie elementen (nav
, li
en a
), en één pseudo-class (:nth-last-child(2)
). Voor waar het hier om gaat, is een pseudo-class hetzelfde als een class. Deze selector bestaat dus uit drie elementen en één class.
Hierboven wordt een border gegeven met de selector .no-touch nav a
. Daarin zitten twee elementen (nav
en a
) en één class (.no-touch
).
In beide selectors zit één class. Maar in de eerste selector zitten drie elementen, en in de tweede maar twee. Daardoor heeft de eerste selector meer gewicht, meer specificiteit, en blijft van kracht, ook al staat de tweede selector later in de css.
En heeft deze <a> dus nog geen border aan de onderkant.
Om ook deze <a> een border aan de onderkant te geven, moet ik een selector gebruiken die evenveel of meer specificiteit heeft als de eerste selector. Evenveel is ook goed, want omdat hij later in de css staat overrulet hij de eerste selector dan ook. Bij dezelfde specificiteit wint de laatste selector.
De selector die ik hier gebruik is .no-touch nav li:nth-last-child(2) a
. Daarin zitten drie elementen (nav
, li
en a
), één pseudo-class (:nth-last-child(2)
), en één class (.no-touch
). De pseudo-class is voor waar het hier om gaat hetzelfde als een class, dus in deze selector zitten drie elementen en twee classes.
In de eerste selector, waarin de border werd verwijderd, zitten ook drie elementen. Maar er zit maar één class in, en in deze selector zitten er twee. Daardoor heeft deze selector meer specificiteit dan de eerste en heeft deze selector wel effect.
border-radius: 0 0 10px 10px;}
Links- en rechtsboven geen ronde hoek, rechts- en linksonder een ronde hoek.
Omdat maar één maat is opgegeven, worden de ronde hoeken even hoog als breed. (Je kunt ook twee maten opgeven, dan krijg je 'n ellipsvormige hoek.)
In tegenstelling tot wat de naam van deze eigenschap suggereert, krijgen ook achtergrondkleur en een eventuele achtergrond-afbeelding ronde hoeken.
css voor vensters breder dan 1400 px
@media screen and (min-width: 1400px)
De css die hier tot nu toe staat, geldt ook voor browservensters breder dan 1400 px. Elk venster dat minimaal 600 of 810 px breed is, is immers ook 1400 px breed. De css die hieronder staat, geldt alleen voor browservensters breder dan 1400 px. Voor een deel is dit nieuwe css, voor een deel wordt hierboven staande css aangepast.
De opbouw van de regel staat beschreven bij @media screen and (min-width 600px), het enige verschil is dat het hier om een minimumbreedte van 1400 px gaat.
#tekst
Het element met id="tekst". Dit is de div met de oranje achtergrond, waarbinnen de tekst staat.
width: 58%;
Bij de css voor vensters breder dan 810 px heeft div#tekst bij #tekst een breedte van 73% gekregen. Dat wordt in een venster met een minimale breedte van 1400 px behoorlijk breed en zou heel lange, lastig leesbare regels opleveren.
Die lange regels verschijnen niet, omdat bij de css voor alle breedtes bij #tekst een maximumbreedte van 50 em is opgegeven om dit te voorkomen.
In browservensters breder dan 810 px staat rechts van de tekst één kolom met foto's. Door de breedte van #tekst
te verlagen in deze bredere vensters, komt er ruimte voor twee kolommen met foto's.
#foto p
De paragrafen binnen het element met id="foto". Dat is er hier maar eentje. De tekst gelijk onder het kopje 'Foto's' staat erin.
width: 39%;
Bij de css voor vensters breder dan 810 px is deze paragraaf bij #foto p 24 % breed gemaakt. De tekst staat boven de foto's. Nu er twee kolommen foto's naast div#tekst
komen te staan, moet de <p> breder worden, anders zou hij maar boven één kolom komen te staan.
div#tekst
is 58% breed, samen met deze <p> van 39% is dat 97%. Bij div#tekst
komt nog een padding links en rechts van 1%, en bij deze <p> een padding van 0,5% links en rechts. Het totaal is dan 1 + 58 + 1 + 0,5 + 39 + 0,5 = 100%.
figure
Alle <figure>'s. Binnen elk van deze elementen staat een <img> met de afbeelding en een <figcaption> met het onderschrift.
width: 20%;
Bij figure heeft dit element een breedte van 25% gekregen, zodat er naast div#tekst
, die 73% breed is, één kolom <figure>'s kan komen te staan.
Bij de css hier, voor vensters breder dan 1400 px, is bij #tekst een breedte van 58% aan div#tekst
gegeven. Hierdoor is er nu ruimte voor twee kolommen <figure>'s, met de daarin zitten foto's en onderschriften.
Maar dan moet <figure> wel iets smaller worden gemaakt. Met een breedte van 20% passen er naast div#tekst
met een breedte van 58% twee stuks. 58 + 20 + 20 = 98%. De 2% die overblijft, wordt gevuld met de padding van 1% links en rechts bij div#tekst
.
<figure>'s die niet naast de tekst passen, worden onder de tekst gezet. Op elke regel onder de tekst passen vijf <figure>'s, en dus vijf foto's. En omdat de <figure> 20% breed is, staan ze netjes horizontaal verdeeld.
css voor vensters breder dan 1600 px
@media screen and (min-width: 1600px)
De css die hier tot nu toe staat, geldt ook voor browservensters breder dan 1600 px. Elk venster dat minimaal 600, 810 of 1400 px breed is, is immers ook 1600 px breed. De css die hieronder staat, geldt alleen voor browservensters breder dan 1600 px. Voor een deel is dit nieuwe css, voor een deel wordt hierboven staande css aangepast.
De opbouw van de regel staat beschreven bij @media screen and (min-width 600px), het enige verschil is dat het hier om een minimumbreedte van 1600 px gaat.
#tekst
Het element met id="tekst". Dit is de div met de oranje achtergrond, waarbinnen de tekst staat.
width: 48%;
Bij de css voor vensters breder dan 1400 px heeft div#tekst bij #tekst een breedte van 58% gekregen. Dat wordt in een venster met een minimale breedte van 1600 px behoorlijk breed en zou heel lange, lastig leesbare regels opleveren.
Maar dit gebeurt niet, omdat bij de css voor alle breedtes bij #tekst een maximumbreedte van 50 em is opgegeven, precies om dit te voorkomen.
In browservensters breder dan 1400 px staan rechts van de tekst twee kolommen met foto's. Door de breedte van #tekst
te verlagen in deze nog bredere vensters, komt er ruimte voor drie kolommen met foto's.
#foto p
De paragrafen binnen het element met id="foto". Dat is er hier maar eentje. De tekst gelijk onder het kopje 'Foto's' staat erin.
width: 49%;
Bij de css voor vensters breder dan 1400 px is deze paragraaf bij #foto p 39 % breed gemaakt. De tekst staat boven de foto's. Nu er drie kolommen foto's naast div#tekst
komen te staan, moet de <p> breder worden, anders zou hij maar boven twee kolommen komen te staan.
div#tekst
is 48% breed, samen met deze <p> van 49% is dat 97%. Bij div#tekst
komt nog een padding links en rechts van 1%, en bij deze <p> een padding van 0,5% links en rechts. Het totaal is dan 1 + 48 + 1 + 0,5 + 49 + 0,5 = 100%.
figure
Alle <figure>'s. Binnen elk van deze elementen staat een <img> met de afbeelding en een <figcaption> met het onderschrift.
width: 16.65%;
Bij figure heeft dit element een breedte van 20% gekregen, zodat er naast div#tekst
, die 48% breed is, drie kolommen <figure>'s kunnen komen te staan.
Bij de css hier, voor browservensters breder dan 1600 px, is aan div#tekst
bij #tekst een breedte van 48% gegeven. Hierdoor is er nu ruimte voor drie kolommen <figure>'s, met de daarin zitten foto's en onderschriften.
Maar dan moet <figure> wel iets smaller worden gemaakt. Met een breedte van 16,6% passen er naast div#tekst
met een breedte van 48% drie stuks. 48 + 3 x 16,6 = 97,8%. De 2,2% die overblijft wordt gevuld met de padding van 1% links en rechts bij div#tekst
.
(1 + 48 + 3 x 16,6 + 1 = 99,8%, en geen 100%. Maar die 0,2% zie je niet. Je zou 16,666666666666666...% kunnen nemen om steeds dichter bij de 100% te komen. Ik heb zoiets zelfs wel 'ns aangeraden gezien, nota bene in een peperduur papieren boek. Niet doen. Door afrondingsverschillen bij het omrekenen van procent naar pixel wordt de kans dan steeds groter dat de laatste <figure> nét niet meer op dezelfde regel past. Bovendien komt bij deze absurde precisie mijn weerzin voor vleselijke omgang met een bepaald zespotig sociaal insect weer naar boven.)
css voor vensters breder dan 1800 px
@media screen and (min-width: 1800px)
De css die hier tot nu toe staat, geldt ook browservensters breder dan 1800 px. Elk venster dat minimaal 600, 810, 1400 of 1600 px breed is, is immers ook 1800 px breed. De css die hieronder staat, geldt alleen voor browservensters breder dan 1800 px. Voor een deel is dit nieuwe css, voor een deel wordt hierboven staande css aangepast.
De opbouw van de regel staat beschreven bij @media screen and (min-width 600px), het enige verschil is dat het hier om een minimumbreedte van 1800 px gaat.
article
Alle <article>'s. Dat is er hier maar eentje. De tekst en de afbeeldingen zijn hierbinnen.
width: auto
Bij .no-touch article heeft <article> een breedte van 80% gekregen, zodat er aan de linkerkant een menu naast past. Bij vensters breder dan 1800 px wordt voor dat menu ruimte gemaakt met een marge aan de linkerkant. Bij een breedte van 80% blijft er veel te veel ruimte over voor dat menu.
auto
is de standaardinstelling van <article>. Standaard wordt een blok-element zoals <article> even breed als zijn ouder, dat is hier div#wrapper
. Die wordt standaard ook weer even breed als zijn ouder, dat is <body>. Via deze ketting wordt <article> ook even breed als de pagina.
Die ruimte van 80% werd alleen gegeven, als bij <html> de class "no-touch" stond. Hier krijgt <article> altijd auto
. Dat maakt niet uit, omdat de <article>'s die niet binnen de class "no-touch" staan, altijd deze standaardinstelling al hadden. Die hebben hier dus geen enkele last van.
.no-touch article
De <article>'s binnen een element met class="no-touch". Er is hier maar één <article>. De tekst en de afbeeldingen staan erin.
Als je in de broncode kijkt, zul je de class "no-touch" niet vinden. Deze class wordt door het JavaScript modernizr toegevoegd aan <html> bij browsers, die touch events niet herkennen. In principe werkt deze regel daardoor alleen in browsers, die touch events niet herkennen. Dat zijn (meestal) mobiele browsers.
Hoe dit verder precies werkt, staat bij Touchscreens herkennen met behulp van modernizr.
Om <html class="no-touch">
te kunnen zien in de broncode, moet je de gegenereerde code bekijken. In Firefox kan dat met behulp van bijvoorbeeld de extensies Firebug of Web Developer onder View Source → View Generated Source. Of met het in Firefox ingebouwde 'Element inspecteren'. Andere browsers hebben andere manieren om gegenereerde code te bekijken.
Bij .no-touch #wrapper is div#wrapper
absoluut gepositioneerd, wat de mogelijkheid geeft om alleen tekst en foto's te scrollen, terwijl header, menu en footer altijd op dezelfde plaats blijven staan. Mobiele browsers hebben vaak moeite met dit soort constructies. Omdat mobiele browsers meestal touch events herkennen, missen die de class "no-touch" in <html>.
Daardoor wordt door die browsers deze regel genegeerd, en dat is precies de bedoeling. Bij .no-touch nav is <nav> met daarin het menu aan de linkerkant van de tekst gezet, bij browser die touch events herkennen. De css hier is alleen voor die browsers nodig.
margin-left: 14%;
Aan de linkerkant een marge van 14% geven. Hierdoor komt daar ruimte om er <nav> met het menu neer te zetten.
#foto p
De paragrafen binnen het element met id="foto". Dat is er hier maar eentje. De tekst gelijk onder het kopje 'Foto's' staat erin.
width: auto;
Tot nu toe had deze <p> een breedte, zodat hij op de goede plaats boven één, twee of drie kolommen met foto's kwam te staan. In deze brede vensters is het aantal kolommen met foto's onbekend: er mogen er zoveel komen als in het venster passen.
Omdat het aantal onbekend is, is ook de gezamenlijke breedte van de kolom(men) met foto's onbekend. Dus is ook niet meer bekend, hoe breed deze <p> moet worden.
auto
is de standaardinstelling. Een blok-element zoals een <p> vult dan normaal genomen de volle breedte van de ouder. Omdat bij foto p de tekst met text-align: center;
horizontaal is gecentreerd, blijft de tekst toch horizontaal gecentreerd boven de foto's staan.
float: none;
Bij #foto p wordt deze <p> naar links gefloat om een marge te kunnen geven en zo. Dat is nu niet meer nodig. Maar als de <p> nog naar links wordt gefloat, komen <figure>'s en de foto's daarin niet onder, maar naast de <p> met tekst te staan, op dezelfde regel.
Door float
ongedaan te maken, wordt de <p> weer een normaal blok-element en komen de <figure>'s niet naast, maar onder de tekst te staan.
figure
Alle <figure>'s. Binnen elk van deze elementen staat een <img> met de afbeelding en een <figcaption> met het onderschrift.
width: auto;
Tot nu toe had <figure> steeds een bepaalde breedte, zodat er in browservensters vanaf een bepaalde breedte één, twee of drie foto's naast de tekst pasten. Door een bepaalde breedte te gebruiken, konden die foto's netjes horizontaal verdeeld worden.
Nu is de breedte van het venster onbekend. Het is minimaal 1800 px breed, maar de precieze breedte is onbekend. Daarom wordt de breedte van <figure> ook vrijgegeven.
<figure> is een blok-element. Normaal genomen zou dat automatisch even breed worden als de ouder van het blok-element. Dat is hier div#foto
. Die heeft geen breedte en wordt daardoor normaal genomen weer even breed als de ouder daarvan: <article>. Ook die heeft geen breedte en wordt dus even breed als de ouder daar weer van: div#wrapper
. Ook al geen breedte, dus die wordt ook weer even breed als de ouder, dat is <body>. Hèhè, we zijn er. Via deze hele keten zou <figure> dus even breed worden als de pagina.
En omdat <figure> een blok-element is, zou elke <figure> op een nieuwe regel komen te staan. Hier is dat niet zo, omdat ze bij figure naar links zijn gefloat. En in dat geval wordt de breedte niet meer dan nodig is om de inhoud weer te geven. Dat zijn hier alleen de afbeelding met met links en rechts daarvan een kleine marge, en het bijbehorende onderschrift.
De breedte kan dus veilig worden verwijderd, waardoor er zoveel foto's naast elkaar worden gezet, als in de breedte van het venster passen.
Enige nadeel is dat ze nu niet meer netjes horizontaal zijn verdeeld, omdat de breedte onbekend is.
Je zou ze nog wel netjes kunnen verdelen door een nieuwe categorie browservensters te maken van 1800 tot 2000 px breed, van 2000 tot 2200 px breed, enz. Maar ik vind breder dan 1800 px mooi genoeg. Zoveel mensen zullen het venster van hun browser niet zo onwijs breed geopend hebben.
Speciaal voor Internet Explorer 7
Voor het grootste deel is dit dezelfde css, die wordt gebruikt voor andere browsers die touch events niet kennen. Maar omdat Internet Explorer 7 niet met de nieuwe media queries uit de voeten kan, wordt die css hier herhaald zonder media queries. Alleen de afwijkende css wordt hier beschreven, bij de css die hetzelfde is als de eerdere staan alleen verwijzingen naar die eerdere css.
De JavaScripts css3-mediaqueries.js en respond.js die het gebruik van media queries in Internet Explorer 7 mogelijk moeten maken, blijken niet te werken in deze browser. Dat is niet omdat die scripts zo slecht zijn, maar omdat Internet Explorer 7 voortdurend het meest krankzinnige en onverwachte gedrag vertoont. Als je rechts onderin een 'o' typt, springt er bij wijze van spreken spontaan een barst in de linkerbovenhoek van de monitor. Zoiets zal hier ook wel spelen. Waarschijnlijk zouden ze, met mogelijk veel moeite, wel werkend zijn te krijgen. Maar het is sneller om voor dit onding gewoon even de css te kopiëren en apart op te geven.
Ik geef direct toe dat ik niet meer echt grondig heb gezocht naar redenen, waarom iets niet goed werkte, of naar oplossingen. De ondersteuning voor deze browser wordt door steeds meer sites gestopt. Binnenkort is dat ook hier het geval. Er is geen enkele reden te bedenken, waarom iemand beslist met dit verouderde monster zou willen surfen. Het werkt. Alles meer is zonde van m'n tijd.
<!--[if IE 7]>
<style>
html {overflow: hidden;}
header {max-width: 1280px; width: 100%; height: 7em; overflow: auto; border-bottom: black solid 1px; position: relative; z-index: 10;}
#wrapper {max-width: 1280px; overflow-x: hidden; overflow-y: auto; position: absolute; bottom: 5em; top: 7em;}
#top {display: none;}
h1 {font-size: 1.6em;}
h2 {font-size: 1.2em;}
article {background: url(100-pics/space-1x1.gif); width: 80%; overflow: auto; margin: 0 0 5em 20%; padding-top: 0;}
#tekst {background: url(100-pics/space-1x1.gif) orange; width: 73%; float: left;}
#foto h2 {margin-top: 2%;}
figure {width: 24.9%; float: left;}
figure img {display: block; max-width: 94%;}
nav {width: 18%; overflow: auto; font-size: 1em; margin-top: 0; border-right: black solid 1px; padding: 1.5% 1.1% 1% 1%; position: fixed; top: 7em; bottom: 5em;}
#naar-top {display: none;}
nav h2 {display: block;}
nav li {width: 100%; float: none;}
nav a {border-width: 0 1px 1px 0;}
nav a {height: 2.2em; line-height: 2.2em; border-width: 0 1px 1px;}
nav a:active, nav a:hover {background: black; color: white; outline: transparent solid 0;}
nav li:first-child a {border-top: black solid 1px;}
footer {width: 100%; max-width: 1280px; height: 5em; overflow: auto; position: fixed; bottom: 0;}
</style>
<![endif]-->
Dit eigenaardige stukje code heet een 'conditional comment' en wordt door alle browsers gezien als commentaar, omdat het tussen <!--
en -->
staat. Maar Internet Explorer herkent het, door de extra toevoegingen, als speciaal voor Internet Explorer bedoeld en zal het dus uitvoeren. Het is veiliger dan een zogenaamde 'hack', waarbij vaak gebruik wordt gemaakt van 'n fout (bug) in de browser. Dit is opzettelijk aangebracht door Microsoft en zal dus blijven bestaan, terwijl 'n bug gerepareerd kan worden.
De style voor Internet Explorer moet ná de normale komen, omdat de opdrachten voor Internet Explorer dan over de normale heen gaan.
Dit stukje geldt voor Internet Explorer 7, maar je kunt het ook voor andere versies aangeven.
In plaats van de style kun je ook 'n normale link naar 'n extern css-bestand aanbrengen:
<!--[if IE 7]>
<link rel="stylesheet" href="../../css/naam-van-ie-stylesheet.css">
<![endif]-->
Op de plaats van "../../css/naam-van-ie-stylesheet.css"
vul je pad naar en naam van jouw stylesheet voor Internet Explorer 7 in. De css voor Internet Explorer 7 komt dan apart in die stylesheet te staan, zodat het de andere browsers niet stoort.
Het is belangrijk dat de spaties in <!--[if IE 7]>
en <![endif]-->
precies zo worden overgenomen zoals ze hier staan.
De toevoeging type="text/css"
bij <style> of <link> is bij html5 niet meer nodig, omdat dit de standaardinstelling is.
html
{overflow: hidden;}
Internet Explorer 7 heeft altijd een verticale scrollbalk, of dat nou nodig is of niet. Hiermee haal je die weg. Normaal genomen zou ik dat niet meer doen voor deze verouderde browser, daar is het niet belangrijk genoeg voor. Maar hieronder staat css die wél belangrijk is, en dan is het 'n kleine moeite dit erbij te zetten.
Als je 'n externe stylesheet gebruikt, loop je tegen 'n apart probleem aan bij html
. Als je zonder meer html {overflow: hidden;}
in je stylesheet zet, geldt dit voor élke pagina van je site. Terwijl het vrijwel zeker is dat er ook pagina's zullen zijn, waar deze instelling niet moet worden gebruikt.
Normaal genomen is dit geen probleem, omdat je bijvoorbeeld <body> 'n id kunt geven. Maar <html> valt buiten de body. Om dit op te lossen, kun je op de pagina's waar html {overflow: hidden;}
moet worden gebruikt de html 'n id geven, bijvoorbeeld "ie-overflow-hidden". In je html wordt de regel dan iets als:
<html id="ie-overflow-hidden" lang="nl">
De precieze regel hangt af van het doctype dat je gebruikt. Dit is de regel die bij html5 hoort.
In de stylesheet gebruik je dan gewoon html#ie-overflow-hidden {...}
. Nu is dit alleen geldig voor de pagina's die bij html de juiste id hebben staan.
<mopper>
Zei ik 'kleine moeite'?</mopper>
header
Het vlak aan de bovenkant met de blauwe achtergrond.
max-width: 1280px;
Omdat media queries niet werken en de breedte van het browservenster dus onbekend is, wordt bij <header>, div#wrapper
en <footer> op deze manier een maximumbreedte opgegeven om te lange, moeilijk leesbare regels te voorkomen.
Door bij alle drie de 'hoofd-onderdelen' dezelfde maximumbreedte op te geven, blijft de rechterkant van de pagina altijd recht, omdat alle onderdelen op dezelfde breedte eindigen.
height: 7em; overflow: auto; border-bottom: black solid 1px; position: relative; z-index: 10;
Beschrijving zie .no-touch header.
#wrapper
Het element met id="wrapper". Dit is een div, waarbinnen tekst, afbeeldingen en menu staan. Deze div vult de ruimte tussen <header> en <footer>.
max-width: 1280px;
Omdat media queries niet werken en de breedte van het browservenster dus onbekend is, wordt bij <header>, div#wrapper
en <footer> op deze manier een maximumbreedte opgegeven om te lange, moeilijk leesbare regels te voorkomen.
Door bij alle drie de 'hoofd-onderdelen' dezelfde maximumbreedte op te geven, blijft de rechterkant van de pagina altijd recht, omdat alle onderdelen op dezelfde breedte eindigen.
overflow-x: hidden; overflow-y: auto;
Internet Explorer 7 krijgt een horizontale scrollbalk onder div#wrapper
. De reden daarvan heb ik verder niet uitgezocht, het ding is gewoon overbodig. Met overflow-x
wordt de horizontale scrollbalk verborgen.
Als ik gewoon overflow: hidden;
zou gebruiken, verschijnt er ook geen verticale scrollbalk. Daardoor kun je helemaal niet scrollen en zijn niet alle tekst en afbeeldingen te zien. Daarom wordt overflow-x
gebruikt: alleen de overflow in verticale richting.
Anders dan bij alle andere browsers moet hier de verticale scrollbalk niet naast <article>, maar hier naast div#wrapper
komen, anders werkt hij niet. Daar zorgt deze overflow-y: auto;
voor.
position: absolute; bottom: 5em; top: 7em;
Beschrijving zie .no-touch #wrapper.
#top
{display: none;}
Beschrijving zie #top.
h1
{font-size: 1.6em;}
Beschrijving zie h1.
h2
{font-size: 1.2em;}
Beschrijving zie h2.
article
Alle <article>'s. Er is hier maar één <article>. De tekst en de afbeeldingen staan erin.
background: url(100-pics/space-1x1.gif);
Internet Explorer 7 heeft vaak problemen met scrollen. Dat is vaak op te lossen door een achtergrondkleur aan het te scrollen element te geven. Ook een doorzichtige gif lost vaak het probleem op. Dat laatste is hier gedaan. space-1x1.gif is een doorzichtige gif van 1 x 1 px.
width: 80%; margin-left: 20%;
Beschrijving zie .no-touch article.
#tekst
{width: 73%; float: left;}
Beschrijving zie #tekst.
#foto h2
{margin-top: 2%;}
Beschrijving zie #foto h2.
figure
{width: 24.9%; float: left;}
Beschrijving zie figure. Het enige verschil is dat de breedte hier 24,9% is en geen 25%, omdat er anders onder de tekst maar drie <figure>'s naast elkaar worden gezet, en dus ook maar drie foto's.
nav
Alle <nav>'s. Dat is er hier maar eentje: de <nav> waar het menu in staat.
width: 18%; overflow: auto; font-size: 1em; border-right: black solid 1px; padding: 1.5% 1.1% 1% 1%;
Beschrijving zie .no-touch nav.
position: fixed;
Bij nav is <nav> absoluut gepositioneerd, maar in deze browser scrolt <nav> en dus het menu toch mee. Door <nav> fixed te positioneren, blijft het ook hier stilstaan, als tekst en afbeeldingen worden gescrold.
top: 7em; bottom: 5em;
Vanwege de fixed positie moet <nav>, anders dan bij andere browsers, precies tussen <header> en <footer> worden neergezet.
#naar-top {display: none;}
Beschrijving zie #naar-top.
nav h2 {display: block;}
Beschrijving zie .no-touch nav h2.
nav li {width: 100%; float: none;}
Beschrijving zie .no-touch nav li.
nav a {height: 2.2em; line-height: 2.2em; border-width: 0 1px 1px;}
Beschrijving .no-touch nav a.
nav a:active, nav a:hover
{background: black; color: white;}
Beschrijving zie .no-touch nav a:focus, .no-touch nav a:hover. Alleen wordt hier :active
gebruikt in plaats van :focus
.
nav li:first-child a
De link binnen het lijst-item dat het eerste kind is van <nav>. Dit is de link met 'Link een'.
border-top: black solid 1px;
Aan de bovenkant mist nog een zwarte border.
footer
Alle <footer>'s. Er is hier maar één <footer>, het blauwe vlak aan de onderkant.
width: 100%;
Beschrijving zie .no-touch footer.
max-width: 1280px;
Omdat media queries niet werken en de breedte van het browservenster dus onbekend is, wordt bij <header>, div#wrapper
en <footer> op deze manier een maximumbreedte opgegeven om te lange, moeilijk leesbare regels te voorkomen.
Door bij alle drie de 'hoofd-onderdelen' dezelfde maximumbreedte op te geven, blijft de rechterkant van de pagina altijd recht, omdat alle onderdelen op dezelfde breedte eindigen.
height: 5em; overflow: auto;
Beschrijving zie .no-touch footer.
position: fixed;
In alle browsers werkt position: absolute;
maar in deze browser scrolt de footer dan mee. Daarom wordt de footer fixed gepositioneerd.
bottom: 0;
Onderaan het venster van de browser zetten.
Speciaal voor Internet Explorer 9
<!--[if IE 9]>
<style>
@media screen and (min-width: 600px) {
nav a {background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iIzU5NTk1OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMzEzMTMiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);}
}
</style>
<![endif]-->
Deze code geldt alleen voor Internet Explorer 9. Uitleg zie bij Speciaal voor Internet Explorer 7.
@media screen and (min-width: 600px)
De opbouw van de regel staat beschreven bij @media screen and (min-width 600px).
nav a
De links binnen <nav>.
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzAwMDAwMCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjUwJSIgc3RvcC1jb2xvcj0iIzU5NTk1OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMxMzEzMTMiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
Tja, het is Internet Explorer, en dat zul je weten ook.
In de knoppen bij browservensters van 600 tot 810 px breed wordt een linear-gradient
gebruikt. Hierin zijn drie kleuren verwerkt. Helaas kent ook Internet Explorer 9 linear-gradient
niet. Daarvoor moet je dus iets aparts doen.
Als je de linear-gradient
in een andere browser exact honderd keer vergroot, zie je de afzonderlijke pixels. Een volledig witte pixel krijgt een waarde van 1, een zwarte pixel een waarde van 34.626. De tussenliggende kleuren krijgen simpelweg de tussenliggende waardes. Door deze decimale waarde te converteren naar de hexadecimale en tot de zevende macht te verheffen, krijgen we bovenstaande uitkomst, nadat we natuurlijk nog even zonder verdoving de wortel hebben getrokken. Het is niet lastig, want zelfs ik kan het. Heeft me maar drie weken gekost en het resultaat is indrukwekkend! Toch?
Als het aan Microsofts technologie zou liggen, zou je het inderdaad ongeveer zo doen, vrees ik. Gelukkig zijn er betere softwaremakers dan Microsoft. De gradiënt-editor op colorzilla.com levert gelijk met de normale linear-gradient
ook bovenstaande toverformule.
De data:image/svg + xml;base64
aan het begin geeft aan dat het hier om een afbeelding gaat met MIME-type svg + xml, gecodeerd als base64. Maak je geen zorgen, de browser weet, wat dat betekent. Zelfs Internet Explorer 9.
Op deze manier kun je afbeeldingen in de css opnemen en hoef je geen extra afbeelding van de server te halen. En het is een aardige illustratie van de mogelijkheden van SVG, want je kunt er nog veel meer mee dan deze constructie, die eigenlijk overbodig zou moeten zijn. Op de pagina met links kun je onder het kopje SVG meer hierover vinden.
Speciaal voor Internet Explorer 7, 8 en 9
<!--[if (lt IE 10)]>
<style>
#onderaan {filter: progid:DXImageTransform.Microsoft.gradient startColorstr='#ffa500', endColorstr='#ffcccc');}
</style>
<![endif]-->
Deze code geldt alleen voor Internet Explorer beneden versie 10 (lt IE 10). Uitleg zie bij Speciaal voor Internet Explorer 7.
#onderaan
Het element met id="onderaan". Dit is een div die alleen voor de sier wordt gebruikt om de overgang van het oranje onder de tekst naar het roze onder de afbeeldingen iets te verzachten.
Bij #onderaan is een linear-gradient
, een verlopende kleur, als achtergrond gegeven aan dit element. Internet Explorer 9 en eerder kennen dit niet. In Internet Explorer 10 is het waarschijnlijk eindelijk ingebouwd.
filter: progid:DXImageTransform.Microsoft.gradient startColorstr='#ffa500', endColorstr='#ffcccc');
Dit is Microsofts manier om verlopende kleuren aan te geven. De gradiënt-editor op colorzilla.com, die is gebruikt om de linear-gradient
te maken, levert automatisch ook dit abacadabra.
Normaal genomen kun je de laatste kleur #ffcccc
inkorten tot #fcc
, maar hier kan dat niet.
Html5-elementen en Internet Explorer 7 en 8
Tegen de standaard in kun je in Internet Explorer 8 en ouder geen css gebruiken bij onbekende elementen. Volgens de standaard hoort de browser niets te doen met een onbekend element, maar moet je er wel css aan toe kunnen kennen. Microsoft wist dit weer 'ns beter en de gevolgen daarvan zullen nog jaren blijven spelen.
In dit voorbeeld worden de voor Internet Explorer 7 en 8 onbekende html5-elementen <header>, <section>, <nav>, <article>, <footer>, <figure> en <figcaption> gebruikt. De css voor deze elementen zou dus niet werken in Internet Explorer 8 en ouder.
Maar als je via JavaScript deze elementen eerst even 'voorstelt' aan de browser, blijken ze plotsklaps wél herkend te worden. En kan dus gewoon css voor deze elementen worden gebruikt. (In feite worden de elementen aan de DOM toegevoegd, een soort inhoudsopgave van onder andere alle html-elementen in een pagina.)
Internet Explorer 9 kent deze elementen wel, dus hier speelt dit probleem niet meer. (Internet Explorer 9 herkent trouwens, zoals het hoort, ook onbekende elementen, zodat je daar hoe dan ook css en zo bij kunt gebruiken.)
Anders dan vaak het geval is, moet deze JavaScript in de <head> van de pagina staan. De browser moet de elementen al kennen, voordat ze kunnen worden weergegeven. Als de elementen worden gelezen, voordat ze zijn aangemaakt, worden ze gewoon genegeerd. En kan er dus ook geen css aan worden gegeven.
Het eigenlijke JavaScript is heel kort en simpel. Voor dit voorbeeld kun je in de <head> het volgende neerzetten:
<!--[if lt IE 9]>
<script>
document.createElement("header");
document.createElement("section");
document.createElement("nav");
document.createElement("article");
document.createElement("footer");
document.createElement("figure");
document.createElement("figcaption");
</script>
<![endif]-->
Deze code geldt alleen voor Internet Explorer beneden versie 9 (lt IE 9, less than). Uitleg zie bij Speciaal voor Internet Explorer 7.
<script>
en </script>
geven gewoon het begin en einde van het JavaScript aan. Bij html5 hoef je geen type meer op te geven, want het staat standaard op JavaScript ingesteld.
Het eigenlijke JavaScript bestaat uit:
document.createElement("header");
document.createElement("section");
document.createElement("nav");
document.createElement("article");
document.createElement("footer");
document.createElement("figure");
document.createElement("figcaption");
Door het toevoegen van zo'n regel voor een onbekend element, kan dat element nu gewoon worden gebruikt in Internet Explorer 7 en 8.
Deze JavaScript is uiterst beperkt: alleen de hier gebruikte html5-elementen worden aangemaakt, en dan alleen nog maar voor weergave op een scherm. Als je meer wilt doen dan alleen dit, is het mogelijk beter om voor Internet Explorer 7 en 8 het JavaScript op html5shiv te gebruiken. Voordeel van dit uitgebreidere script is onder andere dat standaard-instellingen als display: block;
bij bijvoorbeeld <header> ook al worden doorgegeven aan Internet Explorer 7 en 8, zodat die niet in de css hoeven.
In dit voorbeeld zul je dit soort JavaScript niet vinden in de <head>. Er wordt in dit voorbeeld ook gebruik gemaakt van het JavaScript modernizr. Het herkennen van de onbekende html5-elementen kan ook door modernizr worden gedaan, als je er de hierboven genoemde html5shiv instopt. Dat is in dit voorbeeld gedaan. Meer hierover kun je vinden bij Touchscreens herkennen met behulp van modernizr. Omdat dit soort scripts voortdurend wordt verbeterd, is het absoluut nodig dat je zélf modernizr opnieuw samenstelt en niet gewoon het script uit de download gebruikt.
Het gebruik van JavaScript betekent helaas ook dat de css in Internet Explorer 7 en 8 niet werkt, als de bezoeker JavaScript uit heeft staan. Maar normaal genomen staat JavaScript alleen uit vanwege de veiligheid. En als je ook maar enigszins met veiligheid bezig bent, dan zul je niet Internet Explorer 7 of 8 gebruiken. Dus het aantal mensen waarbij in deze verouderde browsers JavaScript uit zal staan, is waarschijnlijk te verwaarlozen.
Mocht dit wel een bezwaar zijn, dan zul je <nav> en dergelijke door een gewone <div> moeten vervangen.
Een andere mogelijkheid is het gebruik van <noscript>, zoals ik op de site heb gedaan. Dit moet dan alleen voor Internet Explorer 7 en 8 worden gebruikt, want andere browsers herkennen de nieuwe elementen en hebben geen JavaScript nodig. In Internet Explorer kan <noscript> alleen css krijgen via een inline-style. Het wordt dan zoiets:
<!--[if lt IE 9]>
<noscript>
<div style="border: dotted red 10px; padding: 5px; background: white;">
Helaas, deze pagina werkt niet goed met oudere versies van Internet Explorer zonder JavaScript.<br>
Drie mogelijkheden:<br>
* Schakel JavaScript in;<br>
* Installeer Internet Explorer 9;<br>
* Stop met die troep van Microsoft en installeer 'n échte browser zoals Firefox, Google Chrome, Opera of Safari.
</div>
</noscript>
<![endif]-->
Los van dat deze browsers bij <noscript> alleen css binnen 'n inline-style kunnen verwerken, moet ook nog 'n extra <div> worden gebruikt. Als je de style met <noscript style="...">
zou gebruiken, wordt een deel van de inhoud van <noscript> altijd getoond in Internet Explorer 8, ook al staat JavaScript aan.
Media queries en Internet Explorer 7 en 8
In css3 zijn de @media-regels fors uitgebreid. Met behulp van @media
kunnen nu dingen als de breedte en hoogte van het browservenster worden opgevraagd. Afhankelijk van het resultaat kan dan bepaalde css juist wel of juist niet worden gebruikt.
Helaas kunnen Internet Explorer 7 en 8 hier niet mee overweg, en omdat Microsoft bestaande browsers nooit update (op veiligheidsupdates na), zal dit ook niet veranderen. Wat Microsoft kennelijk niet kan, heeft een aantal programmeurs zelf dan maar geprobeerd voor elkaar te krijgen. Met behulp van JavaScript kunnen ook deze browsers gebruik maken van media queries.
Helemaal probleemloos werkt dit bepaald niet. Omdat de code van deze browsers geheim is en er bergen afwijkingen en bugs in zitten, werkt dit JavaScript ook niet altijd, of soms zelfs helemaal niet.
Er zijn twee veel gebruikte JavaScripts om media queries te kunnen gebruiken: css3-mediaqueries-js en respond.js.
respond.js wordt alleen op de site gebruikt bij de pagina's die achter de links in het menu zitten. Op de site zitten in die pagina's links. De opmaak van die links is afhankelijk van de breedte van het venster van de browser. In de download staan geen links op die pagina's, dus daar speelt dit niet.
Om onduidelijke redenen werkt css3-mediaqueries.js niet goed op deze pagina's, en respond.js wel. Het zijn uiterst simpele pagina's, maar om een of andere reden gaat het mis bij gebruik van css3-mediaqueries.js. In Internet Explorer 8 is de linkerknop leeg, de links daarin verschijnen pas als je op de knop klikt, en dan nog niet allemaal in één keer, maar een voor een. respond.js werkt wel goed.
Op de voorbeeldpagina met de lay-out is het net omgekeerd. respond.js werkt wel op de voorbeeldpagina in de download, maar doet helemaal niets in vrijwel dezelfde pagina op de site. css3-mediaqueries.js werkt goed op beide pagina's. Goed? Nou, dat wil zeggen: in Internet Explorer 8. In Internet Explorer 7 doen beide scripts helemaal niets. (respond.js werkt dus wel op de sites in de pagina's achter de links in het menu.)
Internet Explorer 7 krijgt daarom eigen css, waarbij niet wordt gekeken naar de breedte van het venster van de browser. Omdat binnenkort de ondersteuning voor die verouderde gedrocht toch stopt, vind ik het wel prima zo.
Hieruit blijkt weer dat je de roestbakken die Microsoft abusievelijk browser noemt, uiterst goed moet testen. En waarom deze scripts niet werken? Geen flauw idee. Mogelijk is daar wel achter te komen, maar het werkt, en ik kan m'n tijd beter gebruiken.
In de <head> staat het volgende stukje code:
<!--[if IE 8]>
<script src="100-files-dl/css3-mediaqueries.js"></script>
<![endif]-->
Deze code geldt alleen voor Internet Explorer beneden versie 8. Uitleg zie bij Speciaal voor Internet Explorer 7.
css3-mediaqueries.js is het in de download bijgesloten JavaScript, dat ervoor zorgt dat Internet Explorer 8 met media queries uit de voeten kan.
Omdat dit soort scripts regelmatig wordt bijgewerkt, is het uitermate belangrijk dat je zelf dit script ophaalt van css3-mediaqueries-js en niet gewoon het script uit de download gebruikt.
Touchscreens herkennen met behulp van modernizr
In browservensters breder dan 810 px worden header, menu en footer vastgezet. Alleen de tekst en de foto's kunnen scrollen. Dit gebeurt door de footer, het menu en div#wrapper
(met daarin de tekst en de foto's) absoluut te positioneren. Helaas kan dit in mobiele browsers tot grote problemen leiden, zoals het verdwijnen van een deel van de pagina. Dit speelt vooral in oudere browsers, nieuwere browsers kunnen beter met dit soort constructies uit de voeten. Een volledig overzicht van de problemen kun je vinden bij Bekende problemen.
Het is leuk dat dit probleem over 'n tijdje niet meer speelt, maar op dit moment zijn deze problemen nog zo groot, dat het beter is in mobiele browsers álles te laten scrollen, ook in vensters die breder zijn dan 810 px.
Hier ontstaat echter een probleem. Er is geen betrouwbare methode om te testen welke browser je site bezoekt. Vroeger moest dat noodgedwongen vanwege alle fouten en afwijkingen in browsers voor de desktop, en zelfs met 'n heel beperkt aantal browsers ging dat heel vaak mis. (Als je zoekt op 'browser sniffing' kun je, als je van griezelverhalen houdt, je hart ophalen.)
Voor mobiel bestaan veel meer browsers dan voor de desktop. Bovendien is het aantal resoluties vrijwel onbeperkt. En dan hebben de diverse apparaten ook nog 'ns hun specifieke eigenaardigheden en bugs. Op de desktop is een monitor gewoon een monitor, op mobiele apparaten ligt dat anders. Kortom: het is onbegonnen werk om op een betrouwbare manier te kijken, welk apparaat, welke versie van een besturingssysteem en welke browser iemand gebruikt. Je gaat gegarandeerd goed werkende browsers behandelen alsof ze problemen geven, en - erger - browsers met problemen alsof ze goed werken.
Dat was 'n inleiding om vrolijk van te worden: grote problemen en geen oplossing, want browser sniffing werkt niet betrouwbaar.
Er zijn mogelijkheden om op de server te kijken, of de site wordt bezocht door een mobiele browser of door een desktopbrowser, en afhankelijk daarvan een pagina voor mobiel of voor de desktop te sturen. Maar dan zit je in feite met twee (of nog meer) verschillende pagina's. Op de pagina met links vind je onder Mobiele apparatuur → Validators, snelheid testen, browser sniffing, en dergelijke links naar sites die hier bij kunnen helpen.
In dit voorbeeld wordt van één pagina uitgegaan. Om toch verschil te kunnen maken tussen mobiele browsers en browsers voor de desktop, wordt gekeken of de browser 'touch events' herkent. (Hartelijke verontschuldigingen en zo, maar er bestaan gewoon geen gangbare Nederlandse woorden voor dit soort Engelse termen. Bij 'aanrakings-evenement' denk ik persoonlijk niet direct aan een browser, en bij 'aanrakings-belevenis' ga ik echt aan héle andere dingen denken, die ik liever privé houd.)
Een browser die touch events herkent, zal in de regel een mobiele browser zijn. Een browser die touch events niet herkent, zal in de regel een desktopbrowser zijn. Als een desktopbrowser ten onrechte voor een mobiele browser wordt aangezien, is dat niet zo'n ramp. Alles werkt en ziet er goed uit en zo, alleen scrolt de hele pagina.
Als een mobiele browser voor een desktopbrowser wordt aangezien, kan dat vervelender zijn. Niet als de mobiele browser met deze constructie uit de voeten kan, maar dat is dus niet altijd het geval. Bij de geteste browsers is dat het geval bij Opera Mini op de iPad. In portretstand gaat het goed, want dan is het venster maar 768 px breed en scrolt de hele pagina. Maar in landschapsstand is het venster 1024 px breed. En Opera Mini meldt, ten onrechte, dat het geen touch events herkent, en wordt dus voor een desktopbrowser aangezien. (Wat er precies misgaat staat uitgebreider bij Bekende problemen.)
Een echt waterdichte oplossing is er niet voor dit probleem. Browser sniffing is onbetrouwbaar, en bij detectie op de server zit je met meerdere pagina's. Er wordt wel gewerkt aan dit probleem, en in css4 is het mogelijk opgelost, maar dat is voorlopig nog (verre) toekomstmuziek.
Het testen op het al dan niet herkennen van touch events gebeurt met behulp van een JavaScript: modernizr. Dit is een hele kleine JavaScript-bibliotheek die kan testen of een browser bepaalde mogelijkheden wel of niet heeft. Het gaat dan vooral om css3- en html5-mogelijkheden, maar ook testen op touch events kan.
Op de site van modernizr kun je aangeven, waarop je wilt testen. Er wordt dan een script op maat gemaakt, zodat het zo klein mogelijk is. Dit script test vervolgens of een browser iets wel of niet kan. Afhankelijk daarvan wordt aan de tag <html> een bepaalde class toegevoegd. In het geval van touch events is die class 'touch' of 'no-touch'. Dit geeft de mogelijkheid om, zonder verder JavaScript of zo nodig te hebben, aparte css te schrijven voor touchscreens en voor andere schermen.
css voor touchscreens laat je gewoon voorafgaan door .touch
, en css voor andere schermen door .no-touch
. Omdat in <html> één van deze twee aanwezig is, hoef je de selectors voor touchscreens alleen maar met .touch
te beginnen, en die voor andere schermen met .no-touch.
css die voor alle schermen hetzelfde is, laat je gewoon niet beginnen met .touch
of .no-touch
, zodat het op alle schermen werkt.
Omdat de meest simpele browsers de grootste problemen hebben met deze lay-out, wordt er standaard vanuit gegaan dat het om een mobiele browser gaat. Pas als de browser daadwerkelijk meldt dat touch events niet worden herkend, wordt de css voor een vaste header, menu en footer gebruikt.
De meest simpele browsers zitten in de regel ook op de kleinste apparaten. Daarom wordt ook standaard uitgegaan van een heel klein scherm. Pas als de browser meldt dat het venster breder is, wordt de css voor bredere vensters gebruikt.
In de download zit het gebruikte JavaScript bijgesloten als modernizr-touch-html5shiv.js. Dit script bevat meer dan alleen nodig is om touch events te detecteren. Het zorgt er ook voor dat Internet Explorer 7 en 8 html5-elementen herkennen. Je zou dat ook in een apart script kunnen doen, maar modernizr kan die twee scripts combineren.
Het is belangrijk zelf een nieuw script aan te maken op de site van modernizr, want dit soort scripts wordt voortdurend bijgewerkt. Het script dat is bijgesloten in de download kan inmiddels zijn verouderd.
Het JavaScript kun je aanmaken op modernizr.com/download. Om touch events te kunnen detecteren, heb ik daar onder Misc. 'Touch Events' aangevinkt. Verder moet je, om classes bij <html> aan te laten maken, onder 'Extra' nog aanvinken 'Add CSS Classes'.
Verder is nog aangevinkt 'html5shiv v3.4', zodat Internet Explorer 7 en 8 html5-elementen herkennen. Als je in plaats hiervan 'html5shiv v3.4 w/ printshiv' aanvinkt, kunnen deze elementen ook nog worden geprint door Internet Explorer 7 en 8.
Na het aanvinken van wat je in het JavaScript wilt hebben, klik je op de knop 'GENERATE!' Gelijk onder die knop staat nu het JavaScript. Dat is heel compact, tenzij je gelijk eronder een vinkje zet bij 'Don't Minify Source'. Ik heb daar geen vinkje gezet, want ik ga niets aan dit JavaScript veranderen, dus ik vind het prima als het script zo klein mogelijk is, ook al wordt het daar volstrekt onleesbaar door.
Het gegenereerde JavaScript kopieer je en plak je op de plaats waar het script moet komen te staan. Op mijn site bijvoorbeeld is dat in de folder 'js'.
Dit JavaScript wordt gelijk onder de link naar de style in de <head> gezet:
<script src="pad-en-naam.js"></script>
(In html5 is het type niet meer nodig bij een script, omdat standaard van JavaScript wordt uitgegaan.)
Aan de tag <html> voeg je de classnaam 'no-js' toe:
<html lang="nl" class="no-js">
Aan no-js
worden door modernizr één of meer andere andere classes toegevoegd, afhankelijk van waarop wordt getest. In het geval van testen op touch events wordt er touch
(aanwezig) of no-touch
(niet aanwezig) toegevoegd. En no-js
wordt altijd vervangen door js
.
Altijd? Nee. Niet als JavaScript uitstaat, want dan werkt modernizr niet. Dat is een zwak punt van modernizr: het werkt niet als JavaScript ontbreekt of uitstaat. Maar in de praktijk vallen de beperkingen hiervan erg mee. Bovendien heb je ook nog de mogelijkheid om no-js
in de selector te verwerken. no-js
wordt immers alleen door js
vervangen als JavaScript aanstaat. Dit geeft de mogelijkheid afwijkende css te geven als JavaScript uitstaat.
Zonder JavaScript komt er geen no-touch
bij <html> te staan, dus wordt er dan vanuit gegaan dat het om een mobiele browser gaat. Er kan dus alleen ten onrechte een desktopbrowser worden aangezien voor een mobiele browser, en dat kan alleen als JavaScript uit staat. Dat is geen echt probleem, want ook dan zie je een fatsoenlijke pagina, alleen kan de hele pagina scrollen. Het is al mooi als alles werkt, want heel vaak is dat niet het geval zonder JavaScript. En ik kan het weten, want ik surf al jaren met JavaScript standaard uit.
Als modernizr goed is geïnstalleerd, zou je in de broncode bij <html> het volgende moeten zien:
<html lang="nl" class=" js no-touch">
of
<html lang="nl" class=" js touch">
Maar als je nu spoorslags in de broncode gaat controleren of dit klopt, zul je zien dat dit niet zo is. Als je gewoon de broncode bekijkt, zie je precies wat daar staat: de broncode. En daarin staat <html lang="nl" class="no-js">, dus dat zie je.
Wat je wilt zien, is de door JavaScript gegenereerde code. Die kun je in Firefox zien met behulp van bijvoorbeeld de extensie Firebug. Of met de extensie Web Developer onder View source → View Generated Source. Of met het in Firefox ingebouwde 'Element inspecteren'. Andere browsers hebben soortgelijke mogelijkheden om gegenereerde code te bekijken.
De code aanpassen aan je eigen ontwerp
- Als je dit voorbeeld gaat aanpassen voor je eigen site, houdt het dan in eerste instantie zo eenvoudig mogelijk. Ga vooral geen details invullen.
-
Gebruik vooral geen FrontPage, Publisher of Word (alle drie van Microsoft). Deze programma's maken niet-standaard code, die alleen goed te bekijken is in Internet Explorer. In alle andere browsers zie je grotendeels bagger, áls je al iets ziet.
Publisher en Word zijn niet bedoeld om websites mee te maken. FrontPage is zwaar verouderd en wordt niet meer onderhouden door Microsoft. Als je beslist iets van Microsoft wilt gebruiken, schaf dan (voor honderden euro's) een nieuwer programma aan, dat zich wel aan de standaarden houdt.
Je kunt natuurlijk ook een goed gratis programma gebruiken. Links naar dat soort programma's vind je op de pagina met links onder Gereedschap → wysiwyg-editor.
Maar het allerbeste is om gewoon zelf html, css, enz. te leren, omdat zelfs het allerbeste programma het nog steeds zwaar verliest van 'n op de juiste manier met de hand gemaakte pagina.
-
Ik maak zelf het liefst een site in Firefox. Als je 'n site maakt in Firefox, Opera, Safari, Google Chrome of Edge, is er 'n hele grote kans dat hij in alle browsers werkt. Ik geef de voorkeur aan Firefox, omdat het de enige grote browser is die niet bij een bedrijf hoort dat vooral op je centen of je data uit is.
Google Chrome wordt ook door veel mensen gebruikt, maar ik heb dus wat moeite met hoe Google je hele surfgedrag, je schoenmaat en de kleur van je onderbroek vastlegt. Daarom gebruik ik Google Chrome zelf alleen om in te testen.
-
Het allereerste dat je moet invoeren is het doctype, vóór welke andere code dan ook. Een lay-out met een missend of onvolledig doctype ziet er totaal anders uit dan een lay-out met een geldig doctype. Wát er anders is, verschilt ook nog 'ns tussen de diverse browsers. Als je klaar bent en dan nog 'ns 'n doctype gaat invoeren, weet je vrijwel zeker dat je van voren af aan kunt beginnen met de lay-out.
Geldige doctypes vind je op www.w3.org/QA/2002/04/valid-dtd-list.html.
Gebruik het volledige doctype, inclusief de url, anders werkt het niet goed.
-
Gebruik een 'strict' doctype of het doctype voor html5. Deze zijn bedoeld voor nieuwe sites. Het transitional doctype is bedoeld voor al bestaande sites, niet voor nieuwe. Het transitional doctype staat talloze tags toe, die in html5 zijn verboden. Deze tags worden al zo'n tien jaar afgeraden. Het transitional doctype is echt alleen bedoeld om de puinhoop van vroeger, toen niet volgens standaarden werd gewerkt, enigszins te herstellen.
Het strict doctype staat verouderde tags niet toe. Daardoor kan met 'n strict doctype, of het nu html of xhtml is, probleemloos worden overgestapt naar html5. Met een transitional doctype en het gebruik van afgekeurde tags kun je niet overstappen naar html5. Je moet dan eerst alle verouderde tags verwijderen, wat echt ontzettend veel werk kan zijn.
- Als tweede voer je de charset in. Het beste kun je utf-8 nemen. Als je later van charset verandert, loop je 'n grote kans dat je alle aparte tekens zoals letters met accenten weer opnieuw moet gaan invoeren.
- Test vanaf het allereerste begin in zoveel mogelijk verschillende browsers in 'n aantal resoluties (schermgroottes). Onder het kopje Getest in kun je in deze uitleg vinden, waar ikzelf op test. Ook van Internet Explorer kun je meerdere versies naast elkaar draaien. Je kunt daarvoor zoeken op internet en op de pagina met links staan onder de kopjes Gereedschap → Meerdere versies van Internet Explorer draaien en Gereedschap → Weergave testen 'n aantal links, die daar ook bij kunnen helpen.
- Voor alle voorbeelden geldt: breng veranderingen stapsgewijs aan. Als je bijvoorbeeld foto's wilt laten weergeven, begin dan alleen met het veranderen van de namen van de foto's, zodat je eigen foto's worden weergegeven. Maakt niet uit als de maten niet kloppen en de teksten fout zijn. Als dat werkt, ga dan bijvoorbeeld de maten aanpassen. Dan de teksten. En controleer steeds, of alles nog goed werkt.
- Als het om een lay-out of iets dergelijks gaat: zorg eerst dat header, kolommen, footer, menu, en dergelijke staan en bewegen zoals je wilt, en ga dan pas details binnen die blokken invullen. In eerste instantie gebruik je dus bijvoorbeeld 'n leeg blok op de plaats, waar uiteindelijk het menu komt te staan.
-
Als je begint met allerlei details, is er 'n heel grote kans dat die de werking van de blokken gaan verstoren. Bouw eerst het huis, en ga dan pas de kamers inrichten. Als de blokken eenmaal werken, zoals je wilt, zul je het gelijk merken als 'n toegevoegd detail als tekst of 'n afbeelding iets gaat storen. Daarvoor moet je natuurlijk wel regelmatig controleren in verschillende browsers, of alles nog wel goed werkt.
Je kunt de blokken tijdens het aanpassen opvullen met bijvoorbeeld <br>1<br>2<br>3 enz., tot ze de juiste hoogte hebben. Het is handig om aan het einde even iets toe te voegen als 'laatste', zodat je zeker weet dat er niet drie regels onderaan naar 't virtuele walhalla zijn verhuisd.
Om de breedte te vullen kun je het best 'n kort woord als 'huis' duizend keer of zo herhalen. Ook hier is het handig om aan 't einde (en hier ook aan 't begin) 'n herkenningsteken te maken, zodat je zeker weet dat je de hele tekst ziet.
- Zolang je in grotere dingen zoals 'n lay-out aan 't wijzigen bent, zou ik je aanraden de verschillende delen een achtergrondkleur te geven. Je ziet dan goed, waar 'n deel precies staat.
- Als je instellingen verandert in de style, verander er dan maar één, hooguit twee tegelijk. Als je er zeventien tegelijk verandert, moet je niet verbaasd zijn, als je niet weet, wat er is gebeurd. En als je 't niet meer terug kunt draaien.
- Marges, padding en border worden bij de hoogte en breedte van de inhoud opgeteld. Hier worden vaak fouten mee gemaakt. Als je bijvoorbeeld in een lay-out 'n border toevoegt aan een van de 'hoofdvakken' (header, footer, kolommen), dan wordt deze er dus bij opgeteld. Bij 'n border van 2 px rondom de linkerkolom wordt deze dus plotseling 4 px breder (2 aan beide kanten), en 4 px hoger. Zoiets kan je hele lay-out verstoren, omdat iets net te breed of te hoog wordt. Je moet dan elders iets 4 px kleiner maken. Dat zal vaak zo zijn: als je één maat verandert, zul je vaak ook 'n andere moeten aanpassen.
- In plaats van px kun je ook andere maten gebruiken, met name em. Voordeel van em is dat het door de gebruiker kan worden vergroot en verkleind, ook in Internet Explorer (andere browsers hebben meer mogelijkheden op dit gebied). Nadeel is dat het de lay-out sneller kan verstoren dan bijvoorbeeld px. Dit moet je gewoon van geval tot geval bekijken.
-
Valideren, valideren, valideren en dan voor 't slapen gaan nog 'ns valideren.
Valiwie???
Valideren is het controleren van je html en css op 'n hele serie fouten. Computers zijn daar vaak veel beter in dan mensen. Als je 300 keer <h2> hebt gebruikt en 299 keer </h2>, vindt 'n computer die ene missende </h2> zonder enig probleem. Jij ook wel, maar daarna ben je misschien wel aan vakantie toe.
Je kunt je css en html zowel valideren, als 't online staat, als wanneer 't nog in je computer staat.
html kun je valideren op: validator.w3.org
css kun je valideren op: jigsaw.w3.org/css-validator
Valideren kan helpen om gekmakende fouten te vinden. Valid code garandeert ook dat de weergave in verschillende browsers (vrijwel) hetzelfde is. En valid code is over twintig jaar ook nog te bekijken.
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 spraakbrowser gebruiken, of voor motorisch gehandicapte mensen die moeite hebben met het bedienen van een muis. Een spider van een zoekmachine (dat is het programmaatje wat de site indexeert voor de zoekmachine) is te vergelijken met een blinde. Als je je site goed toegankelijk maakt voor gehandicapten, is dat dus gelijk goed voor een hogere plaats in een zoekmachine. Dus als je 't niet uit sociale motieven wilt doen, kun je 't uit egoïstische motieven doen.
(Op die plaats in de zoekmachine heb je maar beperkt invloed. De toegankelijkheid van je site is maar één van de factoren, maar zeker niet onbelangrijk.)
Als je bij het maken van je site al rekening houdt met toegankelijkheid, is dat nauwelijks extra werk. 't Is ongeveer te vergelijken met inbraakbescherming: doe dat bij 'n nieuw huis en 't is nauwelijks extra werk, doe 't bij 'n bestaand huis en 't is al snel 'n enorme klus.
Enkele tips die helpen bij toegankelijkheid:
- Gebruik altijd een alt-beschrijving bij een afbeelding. De alt-tekst is wat wordt gebruikt, als afbeeldingen niet kunnen worden gezien (dat geldt dus ook voor zoekmachines). Als je iets wilt laten zien, als je over de afbeelding hovert, gebruik daar dan het title-attribuut voor, niet de alt-beschrijving.
- Gebruik bij een link een title, waarin je omschrijft, waar de link naar toe leidt.
-
Accesskeys (sneltoetsen) kun je beter niet gebruiken. Deze gaven te veel problemen, omdat ze vaak dubbelop zijn met sneltoetsen voor de browser of andere al gebruikte sneltoetsen. Bovendien is voor de gebruiker meestal niet duidelijk, welke toetsen het zijn.
In de komende html5 waren ze eerst niet toegestaan, maar inmiddels lijkt het erop dat ze toch worden toegestaan, maar op 'n andere manier dan in html 4.01. Ik ga ze zelf pas weer gebruiken, als duidelijk is, hoe ze gaan werken. En als ze beter zijn uitgedacht dan in html 4.01 het geval was, want bij een goede toepassing is het op zich een heel goed idee.
- Met behulp van de Tab-toets (of op 'n soortgelijke manier) kun je in de meeste browsers door de links lopen. Elke tab brengt je één link verder, Shift+Tab één link terug. Met behulp van tabindex kun je de volgorde aangeven waarin de Tab-toets werkt. Zonder tabindex wordt de volgorde van de code aangehouden, maar soms is een andere volgorde logischer.
-
In het verleden werd vaak aangeraden de volgorde van de code aan te passen. Een menu bijvoorbeeld kon in de html onderaan worden gezet, terwijl het op het scherm met behulp van css bovenaan werd gezet. Inmiddels zijn screenreaders en dergelijke zo verbeterd, dat dit niet meer wordt aangeraden. De volgorde in de html kan tegenwoordig beter hetzelfde zijn als op het scherm, omdat het anders juist verwarrend kan werken.
Een andere mogelijkheid is een zogenaamde skip-link: een link die je buiten het scherm parkeert met behulp van css, zodat hij normaal genomen niet te zien is. Zo'n link is wel zichtbaar te maken in speciale programma's zoals spraakbrowsers. Die link staat boven menu, header, en dergelijke, en linkt naar de inhoud van de pagina, zodat mensen met één klik het hele menu kunnen passeren.
-
Van oorsprong was html een taal om wetenschappelijke documenten weer te geven, pas later is hij gebruikt voor lay-out. Maar daar is hij dus eigenlijk nooit voor bedoeld geweest. Het gebruiken van html voor lay-out leidt tot enorme problemen voor gehandicapten en tot een lage plaats in zoekmachines.
De html hoort alleen inhoud te bevatten, lay-out doe je met behulp van css. Die css moet in een externe stylesheet staan of, als hij alleen voor één bepaalde pagina van toepassing is, in de head van die pagina. Zoekmachines zijn ook niet dol op een oerwoud van inline-stijlen (dat zijn stijlen in de tag zelf:
<div style="...">
.)Breng een logische structuur aan in je document. Gebruik een <h1> voor de belangrijkste kop, een <h2> voor een subkop, enz. Spraakbrowsers en dergelijke kunnen van kopregel naar kopregel springen. En een zoekmachine gaat ervan uit dat een <h1> belangrijke tekst bevat.
Dit geldt voor al dit soort structuurbepalende tags.
Als een <h1> te grote letters geeft, maak daar dan met behulp van je css 'n kleinere letter van, maar blijf die <h1> gewoon gebruiken. Op dezelfde manier kun je al dit soort dingen oplossen.
- Een table is fantastisch, maar alleen als die wordt gebruikt om een echte tabel weer te geven, niet als hij voor opmaak wordt misbruikt. In het verleden is dat op grote schaal gebeurd bij gebrek aan andere mogelijkheden. Een tabel is, als je niet heel erg goed oplet, volstrekt ontoegankelijk voor gehandicapten en zoekmachines. Het lezen van een tabel is ongeveer te vergelijken met het lezen van een krant van links naar rechts: niet per kolom, maar per regel. Dat gaat dus alleen maar goed bij een echte tabel zoals een spreadsheet. In alle andere gevallen garandeert 'n tabel 'n lagere plaats in een zoekmachine.
-
Frames horen bij een volstrekt verouderde techniek, die heel veel nadelen met zich meebrengt. <iframe>'s hebben voor een deel dezelfde nadelen. Eén van die nadelen is dat de verschillende frames voor zoekmachines, schermlezers, en dergelijke als los zand aan elkaar hangen, omdat ze los van elkaar worden weergegeven. Ze staan wel naast elkaar op het scherm, maar er zit intern geen verband tussen.
Als je 'n stuk code vaker wilt gebruiken, zoals 'n menu dat op elke pagina hetzelfde is, voeg dat dan in met PHP of SSI. Dan wordt de pagina niet pas in de browser, maar al op de server samengesteld. Hierdoor zien zoekmachines, schermlezers, en dergelijke één pagina, net zoals wanneer je maar één pagina met html zou hebben geschreven.
(Je kunt beter PHP dan SSI gebruiken, omdat SSI min of meer aan het uitsterven is en PHP veel meer mogelijkheden heeft. Op deze site wordt in enkele voorbeelden nog SSI gebruikt, maar zodra die worden bijgewerkt, gaat dat vervangen worden door PHP.)
- Geef de taal van het document aan, en bij woorden en dergelijke die afwijken van die taal de afwijkende taal met behulp van
lang=".."
. Ik doe dat op mijn eigen site maar af en toe, omdat de tekst (en vooral de code) een mengsel is van Engels, Nederlands en eigengemaakte namen. Dit soort teksten is gewoon niet goed in te delen in een taal. - Gebruik de tag <abbr> bij afkortingen. Doe dat de eerste keer op een pagina samen met de title-eigenschap:
<abbr title="en dergelijke">e.d.</abbr>
. Daarna kun je op dezelfde pagina volstaan met<abbr>e.d.</abbr>
. Doe je dit niet, dan is er 'n grote kans dat 'n spraakbrowser e.d. uit gaat spreken als Ed, en 'n zoekmachine kan er ook geen chocola van maken. -
De spider van 'n zoekmachine, schermlezers, en dergelijke kunnen geen plaatjes 'lezen'. Het is soms verbazingwekkend om te zien hoe veel, of eigenlijk: hoe weinig tekst er overblijft op een pagina, als de plaatjes worden weggehaald.
Op Linux kun je met Lynx kijken, hoe je pagina eruitziet zonder plaatjes en dergelijke, als echt alleen de tekst overblijft. Een installatie-programma voor Lynx op Windows is te vinden op invisible-island.net/lynx.
Ook kun je in Windows het gratis programma WebbIE installeren. WebbIE laat de pagina zien, zoals een tekstbrowser en dergelijke hem ziet. WebbIE is te downloaden vanaf www.webbie.org.uk.
Ten slotte kun je je pagina nog online op toegankelijkheid laten controleren op 'n behoorlijk aantal sites, zoals:
lowvision.support: laat zien hoe een kleurenblinde de site ziet. Engelstalig.
wave.webaim.org: deze laat grafisch zien, hoe de toegankelijkheid is. Engelstalig. Deze tester is ook als extensie in Firefox en Google Chrome te installeren.
Op de pagina met links kun je onder Toegankelijkheid links naar meer tests en dergelijke vinden.
Specifiek voor dit voorbeeld
Zonder css wordt de site in de volgorde van de html op het scherm gezet: header, tekst en foto's, menu, footer. Dit is ook zoals de meeste spraakbrowsers en dergelijke het zullen zien.
Omdat de volgorde wat afwijkt van wat op het scherm wordt getoond (behalve in browservensters smaller dan 600 px), zijn bij dit voorbeeld WAI-ARIA-codes gebruikt om de toegankelijkheid te vergroten. Meer daarover kun je lezen bij Semantische elementen en WAI-ARIA.
Het menu is in een ongeordende lijst <ul> gezet, omdat veel spraakbrowsers en dergelijke een menu daarbinnen herkennen, zodat de gebruiker het in één keer kan passeren en naar de echte inhoud van de pagina kan gaan.
In de toekomst zullen spraakbrowsers en dergelijke een menu in een <nav> ook gaan herkennen, maar dat kan nog jaren duren. Bovendien is een menu in een <ul> heel makkelijk op te maken.
Getest in
Laatst gecontroleerd op 10 juli 2012.
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. Het is belangrijk dat te lezen, want uit een test kan ook prima blijken dat iets totaal niet werkt!
Eventuele opmerkingen over de toegankelijkheid specifiek voor dit voorbeeld staan onderaan Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.
Dit voorbeeld is getest op de volgende systemen:
- Windows XP:
Firefox, Opera, Safari en Google Chrome in een resolutie van 1440x900.
Internet Explorer 8 in de resoluties 800x600, 1024x768, 1280x1024 en 1440x900.
Internet Explorer 7 in de resoluties 800x600, 1024x768 en 1280x1024. - Windows 7:
Firefox, Opera, Safari, Google Chrome en Internet Explorer 9 in de resoluties 800x600, 1024x768 en 1280x1024. - OS X:
Firefox, Opera, Safari en Google Chrome in de resolutie 1024x768. - Linux:
Firefox, Opera en Google Chrome in de resoluties 800x600, 1024x768 en 1280x1024. - iPad met iOS 6.0 in een resolutie van 1024x768 (MC979NF):
Safari (portret en landschap).
Opera Mini (portret en landschap).
Chrome for IOS (portret en landschap). - Android 4.0.3 in een resolutie van 1024x768 (CRESTA CTP888):
Android browser, Opera Mobile, Firefox en Chrome voor mobiel (alles portret en landschap). - Android 2.3.6 in een resolutie van 320x240 (Samsung Galaxy Y GT-S5360):
Android browser (portret en landschap).
Opera Mobile (éénkolomsstand aan/uit, portret en landschap).
Opera Mini (éénkolomsstand aan/uit, portret en landschap). Deze browser is een apart geval. De opgevraagde site wordt gedownload via de servers van Opera, waarbij het in zo'n klein venster normaal is dat (het grootste deel van) de lay-out wordt verwijderd. Daarom wordt bij deze browser alleen gekeken, of er geen content (tekst en dergelijke) verloren gaat.
Er is steeds getest met de laatste versie van de browsers op de hierboven 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.
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 tot 200%.
Er is getest met behulp van muis en toetsenbord, behalve op de iPad en Android, waar een touchscreen is gebruikt.
Naast deze 'gewone' browsers is ook getest in Lynx, WebbIE, NVDA en Fangs Screen Reader Emulator. Lynx is een browser die alleen tekst laat zien en geen css gebruikt. WebbIE is een browser die gericht is op mensen met een handicap. NVDA is een screenreader, zoals die door blinden wordt gebruikt. Fangs Screen Reader Emulator is een extensie bij Firefox, die de pagina laat zien, zoals een screenreader hem ziet.
Als het voorbeeld in deze vier 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 onderaan 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 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
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.
Dit is een ontmoedigend lange lijst, maar de meeste problemen vallen heel erg mee. De lijst is vooral zo lang, omdat ik probeer zo volledig mogelijk te zijn.
Links binnen de pagina (ankers) in vensters breder dan 810 px
Kort samengevat: deze lay-out is minder geschikt voor pagina's die ankers bevatten. Het uitgebreidere verhaal:
Normaal genomen kun je met de Terug- en Vooruit-knop (de precieze naam hangt van de browser af) naar een vorige of (als die er al is) volgende pagina gaan. (Bij gebruik van een toetsenbord werken, afhankelijk van de browser, bepaalde toetscombinaties zoals alt+→ en alt+← precies hetzelfde.) Daarbij maakt het niet uit of die vorige of volgende pagina binnen of buiten de huidige site staat.
Op precies dezelfde manier kun je binnen een pagina terug- en vooruitgaan. Als je bijvoorbeeld bovenaan de pagina op een link klikt naar een plaats verderop in dezelfde pagina ('n anker), kun je normaal genomen met iets als alt+← weer terug, naar waar je geklikt hebt.
Omdat in dit geval alleen de rechterkolom, bij genoeg inhoud, wordt gescrold, zullen dit soort ankers alleen binnen de rechterkolom voorkomen. Helaas werken bij deze constructie de genoemde toetsen niet binnen de pagina zelf: je gaat niet terug of vooruit naar de vorige of volgende positie binnen de pagina, maar naar een compleet andere vorige of volgende pagina.
Als je position: absolute;
weghaalt bij div#wrapper
, of als je height: 100%;
of overflow: auto;
weghaalt bij <article>, werken de toetsen zoals ze normaal genomen werken: je gaat ook binnen de pagina terug of vooruit naar een vorige of volgende positie. Het weghalen van één van deze drie eigenschappen is al voldoende. (Voor zover browsers hier van afwijken, staat dat hieronder per browser aangegeven.) Alleen schiet dat ook niet echt op, omdat je dan deze lay-out niet kunt maken.
Dit is ook de reden dat dit probleem alleen speelt in browservensters breder dan 810 px: in smallere vensters worden deze drie eigenschappen niet gebruikt.
Deze lay-out is dus niet echt geschikt voor teksten, waarbinnen je veel heen en weer moet gaan, bijvoorbeeld om voetnoten onderaan de pagina te bekijken. En ook niet voor pagina's met (veel) ankers.
Om misverstanden te voorkomen: het gaat hier alleen om links binnen div#wrapper
. Links vanuit header, footer of linkerkolom naar div#wrapper
werken volledig normaal. Ook links naar en van andere pagina's werken op de normale manier, inclusief de genoemde toetscombinaties.
Overigens speelt ditzelfde probleem in de linkerkolom en in de footer, maar die zullen normaal genomen niet hoger zijn, dan er ruimte is, en er zullen al helemaal geen ankers in voorkomen.
Aanvullend op bovenstaande zijn er nog verschillen per browser:
Opera Mini: terug- of vooruitgaan binnen de pagina werkt helemaal nooit, je gaat altijd terug of vooruit naar de vorige of volgende pagina.
Safari (overal), Google Chrome (overal), Opera Mobiel (Android 4.0.3) en Android browser (Android 2.3.6): in deze browsers werken werken deze navigatietoetsen op de normale manier, ook binnen div#wrapper
: je gaat terug naar de plaats waar je vandaan kwam, ook binnen de pagina. (Bij Safari en Google Chrome was dit eerst niet zo, dus er is hoop dat ze ooit in alle browsers goed werken.)
Internet Explorer 7: Ook als position: absolute;
bij div#wrapper
wordt weggehaald, of height: 100%
of overflow: auto;
bij <article>, wordt terug- of vooruitgegaan naar een vorige of volgende pagina, niet naar de vorige of volgende positie binnen de pagina.
Alle niet-mobiele browsers in vensters breder dan 810 px
Als het goed is, scrollen in deze browsers header, menu en footer niet mee met de rest van de pagina, maar blijven ze vast op het scherm staan.
Als er een verticale scrollbalk in het venster van de browser staat, kun je scrollen binnen het element waar die scrollbalk bij hoort. Vaak zal dat de hele pagina zijn. In dit voorbeeld is het de rechterkolom. (Hoewel wat hier beschreven staat ook geldt voor de footer en de linkerkolom, als daar zoveel in staat dat er een verticale scrollbalk zou verschijnen.)
Dat scrollen doen de meeste mensen met het wieltje van de muis of door in de scrollbalk te klikken of te slepen. Dit werkt allemaal zoals het normaal werkt.
Scrollen kan echter ook met PgDn of Spatiebalk, PgUp of Shift+Spatiebalk, ↓ of ↑. Met de eerste twee ga je 'n venster omlaag, met de middelste twee 'n venster omhoog, en met de pijltjes één regel omlaag of omhoog.
Omdat de rechterkolom binnen een absoluut gepositioneerde div staat, werken deze toetsen niet zonder meer. Je moet eerst even binnen div#content
klikken. Mensen die deze toetsen gebruiken, zullen dit echter weten, omdat je dit heel vaak tegenkomt. Dus 'n echt groot probleem zal dit niet zijn.
Bij 'n touchscreen speelt dit uiteraard niet, omdat je per definitie het scherm aan moet raken om te kunnen scrollen.
Internet Explorer 7 en 8
- Als het niet lijkt, op wat je op de site ziet, geen achtergrondkleuren heeft, alles zomaar ergens neergesmeten lijkt te zijn, enz., heb je waarschijnlijk geen JavaScript aangebracht voor deze browsers, of JavaScript staat uit. Bij Media queries en Internet Explorer 7 en 8 en Touchscreens herkennen met behulp van modernizr staat hier meer over.
-
Internet Explorer 7 en 8 hebben geen ronde hoeken aan boven- en onderkant van het menu, omdat ze
border-radius
niet kennen. Ik heb enkele scripts en dergelijke geprobeerd die ronde hoeken mogelijk maken in deze browser, maar die werkten niet. Soms werken die script wel, soms niet. Omdat de broncode van deze browsers geheim is, zijn altijd werkende scripts eigenlijk niet te maken.Op de pagina met links onder CSS → Bugs en hacks → Dingen mogelijk maken specifiek voor Internet Explorer vind je links naar JavaScript en zo, waarmee je zelf nog kunt gaan spelen in de hoop ronde hoeken te kunnen maken. Persoonlijk vind ik het de moeite niet waard. Het ziet er goed uit, alleen heeft het menu rechte hoeken.
Internet Explorer 9 herkent (eindelijk) gewoon
border-radius
.(Ik jok 'n beetje. Verschillende scripts werkten te goed: het ene script maakte het menu helemaal zwart, maar met ronde hoeken, dat wel. Een andere script liet alleen de border van het menu staan, zonder links. Maar wel weer met ronde hoeken, eerlijk is eerlijk. Als je van 'n wild en opwindend leven houdt, zou ik zeker proberen ronde hoeken aan te brengen in deze browsers. Goedkoper dan 'n overlevingssafari en minstens even afwisselend.)
Internet Explorer 7
-
In Internet Explorer 7 is de zoomfunctie hopeloos slecht. Bij uitzoomen (verkleinen) vallen er op de wildste plaatsen gaten in de lay-out. Bij inzoomen (vergroten) verschijnt een horizontale scrollbalk. Alles is wel te zien, maar je moet voortdurend horizontaal scrollen, omdat tekst uit de rechterkolom onder het menu links verdwijnt.
Als je alleen de lettergrootte verandert, gaat het wel goed.
- In de rechterkolom werken PgDn, PgUp en de spatiebalk niet (normaal genomen werken Spatiebalk en Shift+Spatiebalk hetzelfde als PgDn en PgUp). Ze werken wel, als je eerst ergens in het roze deel naast de tekst klikt. Pardon? Welkom in de wondere wereld van Internet Explorer. Omdat deze browser inmiddels ook zwaar verouderd is, ga ik hier verder geen tijd aan besteden.
- Dit pareltje van techniek, waarop Microsoft terecht apetrots was, kan de breedte van het browservenster niet vaststellen met behulp van
@media
. Daardoor zouden in brede vensters heel lange regels kunnen ontstaan, wat lastig leest. Om dat te voorkomen heeft deze zielenpiet eenmax-width
gekregen. Dat kan ze nog net begrijpen. Op de pagina met links vind je onder CSS → Bugs en hacks → Dingen mogelijk maken specifiek voor Internet Explorer JavaScript en zo, waarmee je eventueel wel media queries werkend kunt proberen te krijgen. Mij is het niet gelukt in Internet Explorer 7. Maar ik heb het ook niet echt heel fanatiek geprobeerd, want binnenkort stop ik volledig met de ondersteuning voor deze browser. - Omdat de breedte niet met behulp van
@media
kan worden vastgesteld, komt in deze browser ook in vensters smaller dan 810 px een rij foto's naast de tekst te staan. Geen echt probleem, alleen worden de regels met tekst wat kort. Ook scrollen header, menu en footer nooit mee. De combinatie Internet Explorer 7 in een venster smaller dan 810 px zal trouwens niet heel vaak voorkomen. - Een serie kleinere afwijkingen, die mogelijk makkelijk zijn te herstellen, maar dat heb ik niet geprobeerd:
onder de foto's zit een kleine lege ruimte;
in de tekst boven de foto's wordt de padding aan de rechterkant genegeerd;
de foto's naast de tekst staan iets te veel naar rechts;
de <figcaption> onder de afbeeldingen wordt niet breder dan de tekst die erin staat.
Internet Explorer 8
- In browservensters smaller dan 810 px hoort achter de knoppen van het menu een gradiënt te zitten: links en rechts zwart, in het midden iets grijzer. Zo'n gradiënt met drie kleuren is niet te maken in Internet Explorer 8, je zou daar een afbeelding voor moeten gebruiken. Daarom is in deze browser de achtergrond van de knoppen gewoon effen zwart.
-
Bij uitzoomen (verkleinen) springt de pagina steeds weer terug naar boven, als er omlaag wordt gescrold. In vensters breder dan 1400 px vervormen de afbeeldingen bij uitzoomen zo sterk, dat ze volledig onbruikbaar worden. Bij smallere vensters treedt dit ook op, maar pas bij sterk uitzoomen. Als alleen de lettergrootte wordt veranderd, gaat het wel goed.
Dit zijn bijwerkingen van het JavaScript css3-mediaqueries.js. Bij het JavaScript respond.js gebeurde dit niet. (Ik gebruik css3-mediaqueries.js, omdat op de site respond.js niet werkt, en ik probeer het 'n beetje hetzelfde te houden, anders wordt het al snel één grote bende.)
Dit komt trouwens niet, doordat dit script zo slecht is, maar doordat internet Explorer 8 barstensvol bugs en afwijkingen zit. En omdat de broncode ook nog 'ns geheim is, is het vrijwel onmogelijk die fouten te omzeilen.
Opera Mini op Android 2.3.6
- Met de éénkolomsstand aan negeert Opera Mini de minimumhoogte van de links, waardoor het wat lastig is deze met de vingers te bedienen. Met de éénkolomsstand uit wordt de minimumhoogte wel aangehouden.
- In vensters smaller dan 600 px staat het menu onderaan de pagina, gelijk boven de footer. In de header verschijnt een link naar het menu. Deze link is in Opera Mini niet onderstreept, waardoor het iets minder duidelijk is dat dit een link is. Opera Mini schijnt links gewoon nooit te onderstrepen.
Opera Mini op de iPad
Opera Mini op de iPad lijkt ten onrechte niet te melden dat touch events worden herkend. In portretstand is dit geen probleem, omdat de weergave dan altijd zonder gebruik van absolute posities is.
Maar in landschapsstand is dit wel een groot probleem, omdat footer, menu en div#wrapper
met de tekst en foto's nu absoluut zijn gepositioneerd. Als je omlaag wilt scrollen in de tekst en de foto's, werkt dat niet. Tekst en foto's die onder het venster staan, worden niet zichtbaar. De hele pagina scrolt weliswaar, inclusief menu en footer, maar er verschijnt geen nieuwe tekst en geen nieuwe foto's. De hele pagina verdwijnt gewoon aan de bovenkant buiten het venster.
Als de pagina wordt geopend in portretstand, gaat het goed. Als vervolgens wordt gedraaid naar landschapsstand, blijft het goed gaan. De weergave voor mobiele browsers blijft behouden. Pas als na het draaien de pagina wordt ververst, wordt de weergave voor desktopbrowsers gebruikt en gaat het mis.
Als de pagina wordt geopend in landschapsstand, is het net omgekeerd. Ook bij draaien naar portretstand blijft de weergave voor desktopbrowsers gebruikt worden, en scrolt dus de hele pagina van het scherm, zonder dat nieuwe tekst of foto's verschijnen. Pas als de pagina na draaien wordt ververst, wordt de weergave voor mobiele browsers gebruikt.
Vensters breder dan 1800 px (in Opera breder dan 1600 px)
De thumbnails onder de tekst staan niet meer netjes uitgelijnd, omdat de breedte is 'vrijgegeven' en dus onbekend is. Ook naast de tekst staan de thumbs niet meer netjes verdeeld. Ze staan nog wel in kolommen uitgelijnd, maar de kolommen zelf zijn niet meer horizontaal gelijkelijk verdeeld over de lege ruimte naast de tekst.
Je kunt dit eventueel voorkomen door max-width
te gebruiken, maar dat lijkt me eigenlijk de moeite niet waard, want niet veel mensen zullen zo'n breed browservenster hebben. En voor de enkeling die wel zo'n onwijs breed browservenster heeft, is dit waarschijnlijk het kleinste probleem...
In Opera speelt dit al in vensters breder dan 1600 px. Omdat het maar om 'n klein probleem gaat op 'n heel klein aantal schermen, laat ik dit verder zo.
Zoomen
Firefox, Opera, Internet Explorer 8 en 9 in Windows, OSX en Linux: in- en uitzoomen ziet er hetzelfde uit als wanneer de pagina zou worden getoond in een smaller of breder browservenster.
Safari en Google Chrome in Windows en OSX, Google Chrome in Linux: inzoomen (vergroten) werkt prima. Bij uitzoomen (verkleinen) wordt de lay-out nogal veranderd. Alles is goed te zien en zo, maar het ziet er niet meer echt heel netjes uit.
Valideren
linear-gradient
wordt door de css-validator nog niet herkend en dus als fout aangemerkt. Omdat de oorzaak van de fout bekend is, is dat hier geen probleem. De validator wordt vaak veel te fanatiek gebruikt: het is een hulpmiddel om fouten te vinden, geen gereedschap om de Olympische Spelen voor Foutloze Code te winnen.
Mobiele browsers en fixed of absolute positie
Het gaat hier om problemen die zich niet voordoen, omdat geen fixed of absolute positie wordt gebruikt bij mobiele browsers. Maar als dat wel zou worden gebruikt, dan zouden onderstaande problemen zich voordoen. Die problemen zijn precies de reden dat geprobeerd wordt een absolute positie bij mobiele browsers te voorkomen.
Omdat er maar een beperkt aantal browsers is getest, zullen er waarschijnlijk nog (veel) meer problemen zijn die hier niet worden beschreven, omdat er niet op is getest.
Opera Mobiel op Android 4.0.3 in landschapsstand (1024x768): omdat in portretstand de hele pagina scrolt, spelen in portretstand onderstaande problemen niet.
Als de footer een absolute positie krijgt, staat de footer netjes onderaan het browservenster. Helaas scrolt de footer mee met de rest van de pagina. Daardoor is een deel van de tekst onleesbaar, omdat deze onder de meescrollende footer staat.
Dit is op te lossen door de footer een fixed positie te geven. (Dat is alleen nodig voor Opera Mobiel. Bij alle andere geteste browsers gaat het ook goed, als de footer een absolute positie heeft.) Als de footer een fixed positie krijgt, scrolt hij nog steeds mee. Maar als je stopt met scrollen, springt hij weer terug naar de onderkant van het venster. Het ziet er niet echt geweldig uit, maar in ieder geval is alles nu te zien.
Behalve helemaal onderaan de pagina, daar staat de footer weer over het onderste deel. Daardoor kun je van de onderste foto's 'n deel van de onderkant niet zien. Door onderaan <article> een extra marge te geven, wordt dat opgelost. Andere browsers hebben er geen last van, en voor Opera Mobiel geeft het ruimte om de footer neer te zetten, zonder dat die over de onderste foto's komt te staan.

In Opera Mobiel op Android 4.0.3 scrolt het menu in de linkerkolom mee met de rest van de pagina. Je zou dat ook 'n fixed positie kunnen geven, zodat het net als de footer elke keer na het scrollen terugspringt. Maar dat begint meer op 'n vlooiencircus met 'n mislukte vlooientemmer aan het hoofd te lijken dan op een fatsoenlijke pagina.
Om een of andere reden geeft Opera Mobiel een grotere letter dan de andere browsers op dit systeem. Daardoor is het menu niet volledig zichtbaar: de onderste knop valt weg, zoals op de afbeelding hiernaast is te zien. Rechts van het menu staat echter wel een scrollbalk, waarmee die onderste knop toch valt te bereiken. Als je met je vinger scrolt, beweegt de hele pagina mee, dus je moet echt precies de scrollbalk aanraken met je vinger. Op de afbeelding is dat het minuscule donkergrijze stukje onderaan de scrollbalk. Een fantastische oefening voor een revalidatiecentrum.
Vanwege al deze problemen is het beter gewoon de hele pagina te laten scrollen. Dan hoeven menu en footer ook niet fixed gepositioneerd te worden, absoluut volstaat.
Opera Mini op de iPad in landschapsstand (1024x768): in portretstand speelt dit probleem niet, want daar scrolt de hele pagina mee.
Bij openen van de pagina ziet alles eruit zoals het hoort: header bovenaan, footer onderaan, menu links, tekst en 1 kolom foto's rechts. Maar bij scrollen blijkt álles mee te scrollen, alsof de pagina 'n afbeelding is. Bovendien verschijnen er ook geen nieuwe tekst of foto's: je ziet alleen wat er bij opening al zichtbaar was. De footer scrolt ook mee naar boven, en daaronder verschijnt gewoon een lege ruimte. Anders dan bij Opera Mobiel op Android is dit niet op te lossen door een fixed positie voor de footer te gebruiken.
Safari en Google Chrome op de iPad, Google Chrome, Android browser, Firefox en Opera Mobiel op Android 4.0.3, allemaal in landschapsstand (1024x768): niet echt een probleem, maar ik moest het ergens kwijt. Bij inzoomen (vergroten) verdwijnen header en footer buiten het venster. Als door scrollen de header of footer weer terugkomt op het venster, blijft die weer staan. In Android browser blijft de footer altijd staan. In Opera Mobiel verdwijnt de footer bij scrollen, maar springt gelijk terug zodra het scrollen stopt.
Het werkt allemaal wel, maar om nou te zeggen dat het 'n rustig beeld geeft...
Android browser in landschapsstand op Android 4.0.3: in landschapsstand werkt er geen enkele link naar een anker binnen de pagina, ook niet vanuit de header, menu of footer. Links naar andere pagina's werken wel normaal. Ook zonder position: absolute;
bij div#wrapper
werken de ankers niet, wel als je height: 100%;
of overflow: auto;
bij <article> weghaalt. Probleem is dat de ankers gewoon helemaal niet worden herkend: de id wordt niet opgepikt. Vandaar dat een link naar een andere site wel gewoon werkt. Dit is ook de reden dat het in portretstand wel werkt: daar worden deze eigenschappen niet gebruikt.
Dit is een ernstig probleem. Samen met het gelijk hieronder staande probleem in Firefox op Android 4.0.3, maakt dit het gebruik van ankers feitelijk onmogelijk, als de pagina ook geschikt moet zijn voor mobiel.
Firefox in landschapsstand op Android 4.0.3: (Vlak voordat deze tekst af was, verscheen Firefox 14 voor mobiel. In deze versie is onderstaand probleem opgelost.)
Links vanuit header, menu en footer naar 'n anker binnen div#wrapper
werken gewoon.
In portretstand werkt alles zoals het hoort. In landschapsstand gebeurt er het volgende: als er binnen div#wrapper
een link staat naar 'n anker dat ook binnen div#wrapper
staat, werkt ook die link de eerste keer normaal. Maar bij elke volgende aanraking van div#wrapper
(het oranje deel van de pagina), waar dan ook, verschuift de pagina naar een ogenschijnlijk willekeurige plaats. Dat gebeurt ook, als je 'n link naar 'n anker aanraakt. Bij een volgende aanraking werkt alles weer normaal, bij de aanraking daarna wordt weer verplaatst naar 'n ogenschijnlijk willekeurige positie, enz. Dus afwisselend goed en fout.
Dit is vervelender dan het mogelijk lijkt. Op het moment dat je voor de tweede keer op een link klikt en naar een ogenschijnlijk willekeurige plaats wordt gescrold, is de link waar je op klikte ook verdwenen. En er is geen simpele manier om naar die link terug te gaan, dus dat wordt zoeken.
Dit is een ernstig probleem. Samen met het gelijk hierboven staande probleem in Android browser op Android 4.0.3, maakt dit het gebruik van ankers feitelijk onmogelijk, als de pagina ook geschikt moet zijn voor mobiel.
(Vlak voordat deze tekst af was, verscheen Firefox 14 voor mobiel. In deze versie is onderstaand probleem opgelost.)
Wijzigingen
Alleen grotere wijzigingen worden hier vermeld, geen dingen als een link die is geüpdatet.
:
Nieuw opgenomen.
4 april 2013:
Hele stuk over de nieuwe html5-outline verwijderd, omdat dit toch niet in de uiteindelijke specificatie komt te staan.