Uitleg flexibele lay-out met header, menu en één, twee of drie kolommen. Past zich aan breedte van venster aan

Skip links en inhoudsopgave

Laatst aangepast: .

Afbeelding 1: de lay-out in vensters van verschillende grootte

Korte omschrijving

Een‑, twee of driekoloms lay-out met (vaste) header en (vast) menu. 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 aan de onderkant van het venster ruimte leeg blijven.

In bredere vensters staan meerdere kolommen naast elkaar. Als er genoeg tekst en dergelijke in deze kolommen staat, kunnen deze kolommen worden gescrold.

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 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 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 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 (oranje)

Vensters smaller dan 700 px: de kolom wordt even breed als het venster van de browser.

Vensters breder dan 700 px: rechts van deze kolom staat een tweede kolom.

Vensters breder dan 810 px: links van deze kolom staat een menu, rechts van deze kolom staat een tweede kolom.

Vensters breder dan 1500 px: links van deze kolom staat een menu, rechts van deze kolom staan nog twee kolommen.

Tweede kolom (roze)

Vensters smaller dan 700 px: de kolom wordt even breed als het venster van de browser en staat onder de oranje kolom.

Vensters breder dan 700 px: deze kolom staat rechts van de oranje kolom en is ongeveer half zo breed als de oranje kolom.

Onderste rij of derde kolom (donkergroen)

Vensters smaller dan 700 px: de kolom wordt even breed als het venster en staat onder de roze kolom.

Vensters breder dan 700 px: de kolom wordt even breed als het venster en staat onder de oranje en roze kolom.

Vensters breder dan 810 px, behalve touchscreens: de kolom staat links van het menu en onder de oranje en roze kolom.

Vensters breder dan 1500 px: de kolom staat rechts van de roze kolom en is ongeveer half zo breed als de oranje kolom.

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

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

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

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

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

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 en een vast menu: header en menu 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 en menu 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 en menu 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.)

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 en menu. Die kunnen er nu met behulp van de class "no-touch" uitgefilterd worden, waardoor andere browsers deze css niet krijgen.

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. Alles werkt, het ziet er alleen anders uit, dan wanneer JavaScript aan staat.

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 en kolommen. In werkelijkheid gaat het om een aantal min of meer 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 soms weinig met elkaar te maken. Zonder enig probleem zou je de header links kunnen neerzetten, of het menu rechts. Wat voor het oog een samenhangend geheel is, bestaat in werkelijkheid uit een aantal min of meer losse blokken.

Omdat de pagina in werkelijkheid uit min of meer 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 (div#wrapper) 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, over tekst en dergelijke die onder de header staat. Om dat te voorkomen, wordt overflow op auto gezet: als de inhoud niet in <header> past, verschijnt rechts van de header een verticale scrollbalk.

Dan houden we het deel onder de header nog over: het menu en de kolommen.

<header> kan relatief simpel een breedte krijgen, omdat <header> gewoon altijd even breed als het venster moet zijn. Voor het deel met menu en kolommen ligt het iets ingewikkelder, omdat de plaatsing van menu en kolommen afhankelijk is van de breedte van het venster en van het al dan niet herkennen van touch events door de browser. 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.

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. 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. De knoppen in het menu zijn zo simpel mogelijk gehouden: rechthoekige grijze vlakken. Maar niets belemmert je, om ze op te leuken met allerlei toeters en bellen.

Afbeelding 2
Afbeelding 2: extra link naar menu aan onderkant van pagina in een venster smaller dan 600 px.
Afbeelding 3
Afbeelding 3: menu staat onderaan pagina in een venster smaller dan 600 px.

Bovenaan de pagina verschijnt linksboven in 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 kolommen staat, helemaal onderaan in div#wrapper: 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 elke kolom de volle breedte van het venster van de browser. De drie kolommen staan onder elkaar.

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.

Afbeelding 4: in vensters breder dan 600 px staat het menu bovenaan en is er één kolom

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 en menu. Zelfs de rijke, subtiele, gevoelige, kunstzinnige schakering van de achtergrondkleuren in het voorbeeld verhelpt daar niets aan.

De kleine stukjes groen die je achter het menu ziet, zijn de achtergrond­kleur van het menu. De knoppen in het menu zijn hier iets verfraaid met een achtergrond-gradiënt en ronde hoeken. Ik zal trouwens de eerste zijn om toe te geven, dat het nog steeds geen pareltjes van schoonheid zijn. Maar het gaat er hier niet om het mooiste menu te maken.

De kolommen vullen de volle breedte van het venster van de browser en staan onder elkaar.

In vensters breder dan 700 px is weer wat meer ruimte. Hier worden de eerste en tweede kolom niet meer onder elkaar, maar naast elkaar gezet. De eerste kolom vult ongeveer twee derde van de breedte, de tweede kolom een derde.

Afbeelding 5: in vensters breder dan 700 px staat het menu bovenaan en zijn er twee kolommen

Dit naast elkaar plaatsen gebeurt door bij beide kolommen display: table-cell; op te geven. Hierdoor worden beide kolommen als een cel in een tabel weergegeven, alsof je in de html <td> hebt gebruikt. Opgeven van een rij (<tr>) of tabel (<table>) is niet nodig: de browser maakt de benodigde <gt; en <table> automatisch aan, waardoor een normale tabel ontstaat. Maar omdat de browser dat automatisch afhandelt, merk je daar verder niets van.

De derde kolom is hier eigenlijk nog geen kolom, maar staat onder de eerste twee kolommen.

Een aantal mensen is nu vermoedelijk aan het bijkomen van een hartverzakking. Tabellen voor lay-out? Stond daar niet een levenslange verbanning naar Redmond op?

Nee, niet op déze tabel. Een tabel in de html hoort alleen gebruikt te worden voor tabulaire gegevens, omdat de html anders slecht toegankelijk is voor screenreaders, zoekmachines, en dergelijke. Html-tabellen zijn ook ongelooflijk moeilijk te onderhouden, zeker als ze genest zijn.

Dit is echter geen html-tabel, maar een css-tabel. En dat is heel wat anders. Deze tabel heeft geen enkele invloed op de toegankelijkheid: je verandert geen komma aan de html. De structuur van de html blijft precies hetzelfde, alleen de plaats van de onderdelen op het scherm verandert. Precies waar css voor is bedoeld.

Uiteraard moet je ook hier niet al te wild mee omgaan. Als je css-tabellen 37 niveaus diep gaat nesten, leidt dat tot dezelfde overspannenheid als bij html-tabellen.

Het grote voordeel van het gebruik van een css-tabel is hier de automatische hoogte. Normaal genomen moet je nogal wat moeite doen om de twee kolommen even hoog te maken. Door ze beide te veranderen in de cel van een tabel, krijgen ze automatisch dezelfde hoogte. Net zoals in een 'echte' tabel het geval is. Waardoor ook de achtergrondkleur van beide kolommen even ver naar beneden doorloopt, ongeacht welke kolom het langst is.

In vensters breder dan 810 px is nog wat meer ruimte. Het menu komt nu links van de kolommen te staan.

Afbeelding 6: in vensters breder dan 810 px staat het menu links en zijn er twee kolommen. Op touchscreens staat het menu bovenaan de pagina.

De drie kolommen staan in een gezamenlijke <article>, het menu staat daarbuiten. Dit geeft de mogelijkheid aan de linkerkant van <article> ruimte vrij te maken voor het menu.

Het is hier eigenlijk de bedoeling dat header en menu blijven staan en alleen de kolommen scrollen. Maar omdat dat in mobiele browsers tot (grote) problemen kan leiden, is daarvoor een aanvul­lende 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 en menu niet mee. Als de browser touch events herkent en dus vermoedelijk een mobiele browser is, blijft het menu gewoon bovenin staan als een rij naast elkaar staande knoppen.

Bij een heel grote lettergrootte zou er inhoud van het menu onder het venster van de browser kunnen komen te staan. Omdat het menu met position: fixed; is vastgezet, zou dat op geen enkele manier meer te zien zijn. Daarom wordt voor het menu overflow op auto gezet. Als het menu nu niet binnen het browservenster past, verschijnt aan de rechterkant een verticale scrollbalk.

De derde kolom is hier eigenlijk nog geen kolom, maar staat rechts van het menu en onder de eerste twee kolommen. Omdat deze derde kolom wat breed kan worden, wordt de inhoud ervan vanaf een vensterbreedte van 810 px in twee kolommen weergegeven.

Bij een vensterbreedte van meer dan 1200 px wordt, om te lange regels te voorkomen, de tekst in de eerste (oranje) kolom zelf ook weer in twee kolommen weergegeven. Om dezelfde reden wordt de tekst in de derde kolom nu in drie kolommen weergegeven.

Afbeelding 7: in vensters breder dan 1500 px staat het menu links en zijn er drie kolommen. Op touchscreens staat het menu bovenaan de pagina.

Bij een breedte van meer dan 1500 px, wordt ook de derde kolom naast de andere twee gezet. Omdat deze derde kolom nu smaller is, wordt de inhoud ervan weer in één kolom weer­gegeven.

De derde kolom wordt ook weer met behulp van display: table-cell; naast de andere twee gezet, zoals beschreven bij Dit naast elkaar...

Hierdoor wordt ook deze derde kolom automatisch even hoog als de eerste twee.

Bij deze breedte is in alle drie de kolommen een achtergrond-afbeelding aangebracht. Dat heeft verder niet echt nut, maar het laat zien dat zoiets mogelijk is zonder veel extra werk.

Voor Internet Explorer 8 en 9 is vanzelfsprekend aparte css nodig. Dat is een van de twee 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 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. (Hoewel, o wonder, in Internet Explorer 10 kan dit eindelijk!)

(En die tweede zekerheid? Kom op, 'n beetje zelf nadenken! Dat is de PvdA die steevast vóór de verkiezingen links is, en na de verkiezingen rechts. Vóór de verkiezingen helpen ze opa de straat over te steken, na de verkiezingen helpen ze opa van z'n centen af. Vóór de verkiezingen misbruiken ze 'n gehandicapt kind om aan zetels te komen, na de verkiezingen slopen ze zo'n beetje alle hulp voor dat soort kinderen. Maar ik dwaal mogelijk 'n heel klein beetje af.)

Voor Internet Explorer 8 is extra JavaScript nodig om de nieuwe html5-elementen en @media-regels te herkennen.

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.

Op webkit gebaseerde browsers, zoals Google Chrome en Safari: -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 worden linear-gradient, column-count, column-rule en column-span gebruikt.

Zodra de experimentele fase voorbij is, wordt het voorvoegsel weggelaten. Omdat dat moment niet bij alle browsers hetzelfde is, zet je nu ook al de officiële naam erbij. Deze wordt als laatste opgegeven. Bijvoorbeeld 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.

linear-gradient

Op dit moment moet je nog het volgende schrijven:

{-moz-linear-gradient: ...; -o-linear-gradient: ...; -webkit-linear-gradient: ...; linear-gradient: ...;}

In de toekomst kun je volstaan met:

{linear-gradient: ...;}

Internet Explorer 8 en 9 kennen linear-gradient helemaal niet, die krijgen eigen css. Internet Explorer 10 herkent het zonder het voorvoegsel -ms-.

column-count, column-rule en column-span

Op dit moment moet je nog het volgende schrijven:

{-moz-column-count: ...; -webkit-column-count: ...; column-count: ...;}

In de toekomst kun je volstaan met:

column-count: ...;

(Voor column-rule en column-span geldt hetzelfde.)

Internet Explorer 8 en 9 kennen deze eigenschappen helemaal niet. Internet Explorer 10 en Opera herkennen ze zonder de voorvoegsels -ms- of -o-.

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> en <section> gebruikt. Alle vier 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 kolommen <article>.

<section>: deel van een tekst. In dit voorbeeld is de eerste kolom onderverdeeld in een aantal <section>'s. De tweede en derde kolom, waarin veel minder tekst staat, zijn elk een eigen <section>.

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

<header> mag vaker op één pagina worden gebruikt. Een <article> zou bijvoorbeeld een eigen <header> kunnen hebben, naast de <header> 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> per pagina het beste is.

(In dit voorbeeld wordt <footer> niet gebruikt. Voor <footer> geldt hetzelfde als voor <header>, maar zoals de naam al zegt: het is een footer.)

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 soms 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 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">

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.

:hover, :focus en :active voor muis, toetsenbord, touchpad en touchscreen

:hover

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

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

In dit voorbeeld wordt :hover gebruikt in browservensters breder dan 810 px, waarin het menu links van de eerste kolom staat. Zodra de cursor boven een van de knoppen in het menu komt, verandert de knop van kleur. Op touchscreens werkt dit niet.

:focus

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

De meeste mensen gaan met een muis naar een link, invoerveld, en dergelijke. Waarna ze vervolgens klikken om de link te volgen, tekst in te voeren, of wat ze ook maar willen doen.

Er is echter 'n tweede manier om naar links, invoervelden, en dergelijke te gaan: met behulp van de Tab-toets (sommige browsers gebruiken andere toetsen, maar het principe is hetzelfde). Met behulp van de Tab-toets kun je naar links, invoervelden, en dergelijke 'springen'. Waar je staat, wordt door alle browsers aangegeven met een of ander kadertje. De link en dergelijke met het kadertje eromheen heeft focus. Dat wil zeggen dat je die link volgt, als je op de Enter-toets drukt, of dat je in dat veld tekst kunt gaan invoeren, enz.

Als iemand geen muis wil of kan gebruiken, bijvoorbeeld door 'n handicap, is deze manier om de cursor te sturen erg handig. Als de volgorde van de links, invoervelden, en dergelijke in de code niet logisch is, kun je eventueel met behulp van tabindex 'n afwijkende volgorde opgeven. De Tab-toets volgt dan die afwijkende volgorde.

Links, invoervelden, en dergelijke worden automatisch bezocht bij gebruik van de Tab-toets. Maar door aan andere elementen een tabindex te geven, kunnen ook andere elementen focus krijgen.

In dit voorbeeld wordt :focus gebruikt in het menu. Bij gebruik van de Tab-toets worden één voor één alle knoppen in het menu afgelopen. :focus werkt dus alleen bij gebruik van een toetsenbord.

Zodra één van de knoppen in het menu focus krijgt, verandert deze knop van kleur.

:active

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

Een element is actief, zolang je de muis boven dat element ingedrukt houdt, of – op sommige touchscreens – het element aanraakt.

In Internet Explorer ouder dan versie 8 werkte dit foutief, zoals :focus hoort te werken, en :focus werkte gewoon helemaal niet. Omdat Internet Explorer 8 de oudste versie is die ik (en het merendeel van de sitebouwers) nog ondersteun, speelt dit niet meer.

:active wordt hier niet gebruikt, dus is hier verder niet van belang. Het zou hier ook redelijk zinloos zijn. Op touchscreens heeft het geen enkel nut hier, en als je met de muis op een knop drukt, moet je per definitie ook over die knop hoveren, dus dan werkt :hover al.

Beschrijving van code en css

De code die te maken heeft met de basis van dit voorbeeld is blauw gekleurd. 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 witte vlakken met de links. Ook in de kopregels zit vaak wat verschil. Daarnaast kunnen er nog andere (meestal kleine) verschillen zijn.

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

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

<!DOCTYPE html>

<html lang="nl" class="no-js">

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.

De toevoeging class="no-js" is bedoeld voor modernizr. Als JavaScript aanstaat, wordt dit veranderd in class="js". Meer daarover kun je vinden bij Touchscreens herkennen met behulp van modernizr.

<meta charset="utf-8">

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

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

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

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

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

Mobiele apparaten variëren enorm in breedte. En dat is een probleem. Sites waren, in ieder geval tot voor kort, gemaakt voor desktopbrowsers. En die hebben, in vergelijking met bijvoorbeeld een smartphone, heel brede 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 in een hogere resolutie veel fijner dan in een lagere resolutie. 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 werken, 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. Met ingang van versie 10 van Internet Explorer werken conditional comments niet meer.

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.

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

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

margin: 0; padding: 0;

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

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

text-align: center;

Tekst horizontaal centreren.

#top

Het element met id="top". Dit is de link bovenin de header naar het menu onderin de pagina. Hij is alleen zichtbaar in browservensters 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 boven- en zijkant van het browservenster 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, h2

Alle <h1>'s en <h2>'s.

De <h1> is de belangrijkste kop van de pagina, dat is er maar eentje.

De <h2>'s zijn iets minder belangrijke kopjes dan de <h1>. Ze worden hier gebruikt om de verschillende onderdelen zoals header, menu en beschrijving aan te geven.

font-size: 1.2em;

Iets kleinere letter dan een <h1> of <h2> standaard krijgen. 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 (belangrijke) kopregels gaat.

Dit is een vrij kleine letter voor een <h1>. Voor grotere browservensters wordt de lettergrootte van de <h1> 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 h2

Alle <h2>'s binnen een <header>. Er is maar één <header>, waarbinnen maar een <h2> staat: het kopje 'Header'.

border-top: solid #aaa 1px;

Randje aan de bovenkant als afscheiding tussen de titel van dit voorbeeld en het voorbeeld zelf.

Een <h> is een blok-element. Normaal genomen wordt een blok-element automatisch even breed als zijn ouder. Dat is hier <header>. <header> is ook een blok-element, dus ook dat wordt normaal genomen even breed als z'n ouder.

De ouder van <header> is <body>. <header> wordt daardoor even breed als het venster van de browser. Dus ook <h2> wordt even breed als het venster. Waardoor ook de border aan de bovenkant de volle breedte van het venster vult.

header p

Alle paragrafen binnen een <header>. Er is hier maar één <header>, waarbinnen maar één <p> staat.

margin: 0 1%;

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

Een paragraaf heeft standaard een marge aan boven- en onderkant. Die wil ik hier niet hebben. Links en rechts wil ik wel een kleine marge, zodat de tekst nooit helemaal tegen de zijkant van het venster van de browser kan komen te staan.

Een marge in procenten wordt gemeten ten opzichte van de ouder. Dat is hier <header>, die altijd de volle breedte van het venster van de browser vult. In een smaller venster is de marge hierdoor smaller dan in een breder venster.

Afbeelding 8: de normaal genomen onzichtbare marge van de paragraaf in de header even zichtbaar gemaakt

Overigens zul je deze marge alleen maar zien, als de tekst exact de volle breedte van <header> vult en tegen de zijkant daarvan aan staat. Bij header wordt alle tekst binnen <header> horizontaal gecentreerd. Tenzij de tekst de volle breedte vult, zal er hierdoor altijd al wat ruimte links en rechts van de tekst aanwezig zijn, waardoor je de marge niet ziet.

Op de afbeelding is de achtergrond van <header> geel. De achtergrond van de <p> is even rood gemaakt. De strook geel links van de rode achtergrond is de marge. Zonder die rode achtergrond, zou je in dit geval helemaal niet weten dat de <p> ook een marge heeft.

#een

Het element met id="een". Dit is de eerste kolom. De achtergrond hiervan is oranje.

background: orange;

Oranje achtergrondkleur.

color: black;

Voorgrondkleur zwart. Dit is onder andere de kleur van de tekst.

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hierboven heb ik een achtergrondkleur opgegeven. Sommige mensen hebben zelf de 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, is er nog niets aan de hand, want dan veranderen achtergrond- en voorgrondkleur geen van beide.

padding: 3em 1% 1%;

Omdat voor links geen waarde is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 3em 1% 1% 1% in de volgorde boven – rechts – onder – links.

Rechts, onder en links een padding van 1%, zodat er wat afstand is tussen de buitenkant van de kolom en de tekst.

Een padding in procenten wordt gemeten ten opzichte van de breedte van de ouder. Dit geldt ook voor de padding aan boven- en onderkant: ook die wordt gemeten ten opzichte van de breedte van de ouder, niet ten opzichte van de hoogte.

Die ouder is hier <article>, een blok-element. Een blok-element wordt normaal genomen even breed als de ouder van dat blok-element. De ouder van <article> is div#wrapper. Ook een blok-element, dus ook dat wordt normaal genomen weer even groot als de ouder daarvan. De ouder van div#wrapper is <body>. div#wrapper wordt daardoor even breed als het venster van de browser.

Hierdoor is de padding bij een breed browservenster groter dan bij een smaller venster.

Afbeelding 9: zonder extra css staat er onder de bovenste kop een witte kier

Aan de bovenkant is de padding een stuk groter: 3 em. Dat is om de witte kier op de afbeelding hiernaast te voorkomen.

De kopregel 'Eigenlijke inhoud van de pagina' staat buiten #een. De oranje achtergrond van #een is dan ook niet zonder meer zichtbaar achter deze kopregel, wat een lelijke witte kier oplevert.

Afbeelding 10: alles onder de bovenste kop een eindje omlaag zetten met behulp van padding

Door aan de bovenkant van #een een padding van 3 em op te geven, komt de inhoud van #een lager te staan. Het eerste kind van #een is de <h3> met 'Beschrijving van de onderdelen'. Deze komt dus 3 em lager te staan, net als alles daaronder. Hierdoor ontstaat aan de bovenkant van #een een lege ruimte met een oranje achtergrondkleur, zoals op de afbeelding is te zien.

Afbeelding 11: met een negatieve marge alles onder de bovenste kop een eind omhoog trekken. Nu is er geen witte kier meer onder de bovenste kop.

Hieronder bij article h2:first-child krijgt de eerste <h2> binnen <article>, dat is de kopregel met 'Eigenlijke inhoud van de pagina', een negatieve marge aan de onderkant. Hierdoor wordt alles wat beneden deze <h2> staat omhoog getrokken. Dat is #een, inclusief de oranje achtergrondkleur. Die hierdoor ook achter 'Eigenlijke inhoud van de pagina' komt te staan.

Als eenheid is em genomen, zodat de padding mee verandert met de lettergrootte.

article h2:first-child

De <h2> die het eerste kind is van <article>. Dit is de <h2> met 'Eigenlijke inhoud van de pagina'.

margin: 0 0 -1.2em;

Omdat voor links geen waarde is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 0 0 -1.2em 0 in de volgorde boven – rechts – onder – links.

Links en rechts geen marge.

Een <h> heeft van zichzelf een marge aan boven- en onderkant. De marge aan de bovenkant is hier niet welkom, omdat je vrij weinig ruimte hebt in kleine browservensters (voor grotere vensters wordt verderop een marge aan de bovenkant aangebracht.)

De negatieve marge van 1,2 em aan de onderkant is bedoeld om alles onder deze <h2> iets omhoog te trekken. De uitleg daarvan staat hierboven bij padding: 3em 1% 1%;.

padding-left: 1%;

Voor het oog staat deze <h2> binnen kolom #een met de oranje achtergrond. Maar in de html staat hij daarboven. #een heeft bij #een aan de linkerkant een padding van 1% gekregen. Daarom wordt hier dezelfde padding aan de linkerkant aangebracht.

Een padding in procenten wordt gemeten ten opzichte van de ouder. Dat is hier <article>, dezelfde ouder als #een heeft. Hierdoor is de padding aan de linkerkant van deze <h2> even groot als de padding aan de linkerkant van #een, want 1% van <article> is even groot bij #een als bij deze <h2>.

article p

Alle paragrafen binnen <article>.

text-indent: 1em;

Elke eerste regel 1 em laten inspringen. Door als eenheid em te nemen, springt de regel meer of minder in bij een grotere of kleinere lettergrootte.

margin: 0;

Een <p> heeft standaard een marge aan boven- en onderkant. Die is hier niet welkom.

h3

Alle <h3>'s. Dit zijn de kopjes die bovenaan elk van de drie kolommen staan.

font-size: 1.15em;

Normaal genomen heeft een <h3> een iets grotere letter. Hier verander ik de lettergrootte naar iets kleiner dan de standaardgrootte. 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: 0;

Een <h> heeft standaard een marge aan boven- en onderkant. Die marges zijn hier niet welkom.

h4

Alle <h4>'s. Dit zijn de subkopjes binnen de oranje kolom.

margin: 0;

Een <h> heeft standaard een marge aan boven- en onderkant. Die marges zijn hier niet welkom.

#twee

Het element met id="twee". Dit is de tweede kolom. De achtergrond hiervan is roze.

background: #fcc;

Achtergrondkleurtje.

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

padding: 1%;

Aan alle kanten een kleine padding, zodat er wat afstand is tussen de tekst en de buitenkant van de kolom.

Een padding in procenten wordt gemeten ten opzichte van de breedte van de ouder. Dit geldt ook voor de padding aan boven- en onderkant: ook die wordt gemeten ten opzichte van de breedte van de ouder, niet ten opzichte van de hoogte.

Die ouder is hier <article>, een blok-element. Een blok-element wordt normaal genomen even breed als de ouder van dat blok-element. De ouder van <article> is div#wrapper. Ook een blok-element, dus ook dat wordt normaal genomen weer even groot als de ouder daarvan. De ouder van div#wrapper is <body>. div#wrapper wordt daardoor even breed als het venster van de browser.

Hierdoor is de padding bij een breed browservenster groter dan bij een smaller venster.

#drie

Het element met id="drie". Dit is de derde kolom. In smallere browservensters is dit niet de derde kolom, maar staat dit element onder de eerste kolommen. De achtergrond hiervan is donkergroen.

background: #8fbc8f;

Achtergrondkleurtje.

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

padding: 1%;

Aan alle kanten een kleine padding, zodat er wat afstand is tussen de tekst en de buitenkant van de kolom.

Een padding in procenten wordt gemeten ten opzichte van de breedte van de ouder. Dit geldt ook voor de padding aan boven- en onderkant: ook die wordt gemeten ten opzichte van de breedte van de ouder, niet ten opzichte van de hoogte.

Die ouder is hier <article>, een blok-element. Een blok-element wordt normaal genomen even breed als de ouder van dat blok-element. De ouder van <article> is div#wrapper. Ook een blok-element, dus ook dat wordt normaal genomen weer even groot als de ouder daarvan. De ouder van div#wrapper is <body>. div#wrapper wordt daardoor even breed als het venster van de browser.

Hierdoor is de padding bij een breed browservenster groter dan bij een smaller venster.

nav

Alle <nav>'s. Dat is er hier maar eentje: de <nav> waarbinnen het menu staat. De achtergrond hiervan is lichtgroen.

background: #0f0;

Achtergrondkleurtje.

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

font-size: 0.7em;

Iets kleinere letter. Als eenheid neem ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

nav h2

Alle <h2>'s die binnen een <nav> staan. Er is hier maar één <nav>, en die heeft maar één <h2>, waarin 'Menu' staat.

display: none;

Verberg deze kopregel. Dit kopje heeft alleen zin in bredere browservensters, als het menu aan de linkerkant staat. Daar wordt dit kopje weer zichtbaar gemaakt.

text-align: center;

Tekst horizontaal centreren.

margin-bottom: 5px;

Een <h> heeft van zichzelf een marge aan boven- en onderkant. De marge aan de onderkant wordt hier iets verkleind.

nav ul

Alle ongeordende lijsten binnen een <nav>. Er is hier maar één <nav>, waarbinnen maar een <ul> staat. Binnen die <ul> staat het menu.

Een menu kan normaal genomen het beste binnen een <ul> worden gezet. Spraakbrowsers en dergelijke kunnen een <ul> in één keer passeren, waardoor blinden niet het hele menu voorgelezen krijgen. In de toekomst zal dat waarschijnlijk ook het geval zijn met <nav>, maar het duurt nog jaren voor elke spraakbrowser en dergelijke dat kan.

Los hiervan is een menu binnen een <ul> het makkelijkst op te maken.

list-style-type: none;

De gebruikelijk balletjes en dergelijke van een <ul> zijn hier niet welkom.

margin: 0; padding: 0;

Verschillende browsers hebben verschillende standaardinstellingen voor marge en padding bij een <ul>. Door beide op 0 te zetten, zijn ze overal hetzelfde.

nav li

De <li>'s binnen een <nav>. Er is hier maar één <nav>, waarbinnen het menu staat. Binnen de <li>'s staan de links van het menu.

width: 50%;

Een <li> is een blok-element en wordt normaal genomen even breed als zijn ouder, de <ul>. De <ul> is ook een blok-element en wordt normaal genomen ook even breed als z'n ouder, de <nav>. Ook de <nav> is een blok-element en wordt dus ook weer even breed als z'n ouder: div#wrapper. Ik kan het ook niet helpen, het wordt eentonig: die wordt ook weer even breed als zijn ouder: <body>. Even breed als de pagina dus. Via die hele ketting zou de <li> ook even breed als de pagina worden.

Afbeelding 12: als geen breedte wordt opgegeven, worden de knoppen in het menu veel te smal

In dit geval is dat niet zo, omdat de <li>'s hieronder gefloat worden. En een gefloat blok-element krijgt niet meer ruimte dan nodig is, om de inhoud ervan weer te kunnen geven. De knoppen worden daardoor heel smal, want een knop met de tekst 'Top' wordt maar drie letters breed, zoals op de afbeelding is te zien. Niet echt ideaal om met je vingers te bedienen.

Daarom geef ik zelf een breedte op: 50%. Een breedte in procenten is altijd ten opzichte van de ouder. Via die hele ketting die hierboven staat opgesomd, kom je uiteindelijk bij de pagina uit. Elke <li>, en dus elke link in het menu, wordt half zo breed als de pagina. Nu zijn ze makkelijk met de vinger te bedienen.

float: left;

Een <li> is een blok-element. Normaal genomen komen die op een nieuwe regel te staan. Door ze naar links te floaten, komen er zoveel op één regel te staan, als er naast elkaar passen. Omdat elke <li> hierboven half zo breed als de pagina is gemaakt, staan er twee <li>'s en dus twee knoppen uit het menu naast elkaar.

nav a

De links binnen een <nav>. Hier is maar één <nav>: de <nav> met het menu. In elke <a> staat één link van dat menu.

background: #ccc;

Achtergrond grijs.

color: black;

Tekst binnen een <a> krijgt normaal genomen een kleurtje. Het is hier al duidelijk genoeg dat het om een link gaat, en ik vind een kleurtje hier niet mooi.

display: block;

Een <a> is van zichzelf een inline-element. Door er een blok-element van te maken, kun je eigenschappen als hoogte gebruiken.

height: 1.2cm;

Eigenlijk zou dit niet nodig horen te zijn, omdat de regelhoogte hieronder ook al op 1,2 cm wordt gezet. Maar Opera Mini op Android 2.3.6 negeert die regelhoogte, waardoor je veel te kleine knoppen voor je vingers krijgt.

Als eenheid neem ik de absolute maat cm, zodat de knop altijd groot genoeg is, los van zoomen.

line-height: 1.2cm;

Tekst wordt automatisch halverwege de regelhoogte gezet. Door de regelhoogte even hoog te maken als de hoogte, komt de tekst automatisch halverwege de hoogte van de <a> te staan, en is dus verticaal gecentreerd.

Omdat de hoogte in cm is, is de regelhoogte ook in cm opgegeven.

text-align: center;

Tekst horizontaal centreren.

text-decoration: none;

Tekst binnen een <a> wordt normaal genomen onderstreept. Het is hier al duidelijk genoeg dat het om een link gaat, en ik vind een onderstreping hier niet mooi.

border: black solid;

Randje rondom de links. De breedte geef ik gelijk hieronder op.

border-width: 1px 1px 0 0;

De kleur en stijl heb ik gelijk hierboven al opgegeven. Het apart opgeven van de breedte is in dit geval iets simpeler dan het opgeven van twee volledige regels voor border-top en border-right.

Boven en rechts een border, onder en links niet.

De links komen naast en onder elkaar te staan. Als je aan alle vier de kanten een border zou opgeven, zouden op de grens tussen twee links twee borders tegen elkaar komen te staan, waardoor je daar een dikte van 2 px zou krijgen. Door de border aan onder‑ en linkerkant weg te laten, voorkom je dat.

Er zit nu wel een opening in de border aan de onderkant van de onderste knoppen, dat wordt later gecorrigeerd. Ook aan de linkerkant zit een opening: de border aan de linkerkant van de linkerknoppen mist. Alleen wordt die niet gecorrigeerd, omdat het nauwelijks opvalt dat daar een border mist.

nav li:nth-last-child(2) a

De <a>'s binnen een <li> binnen een <nav>. Hier is maar één <nav>. Maar dit geldt niet voor elke <li> binnen die <nav>, het gaat om één bepaalde <li>: de <li> binnen <nav> die het tweede kind van <nav> is, 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.)

Zoals bij alle <li>'s zit ook binnen dit lijst-item maar één <a>. Uiteindelijk geldt dit dus alleen voor de tweede link van het menu, van achteraf geteld.

Bij nav a is aan de links binnen het menu een border aan de bovenkant en aan de rechterkant gegeven. Aan de onderkant is geen border gegeven. Bij de laatste link 'Top' is dat geen probleem, omdat die tegen de onderkant van het venster van de browser staat, dus dat zie je nauwelijks.

Bij de een-na-laatste link, 'Link acht', kan de border aan de onderkant wel zichtbaar ontbreken.

Als er een oneven aantal links is, staat deze link namelijk in de rechterkolom, terwijl er in de linkerkolom nog een lagere link staat. Dat is op de afbeelding hieronder ook het geval. En dan zou je zien dat rechts een border aan de onderkant mist. Daarom wordt hier bij 'Link acht' een border aan de onderkant toegevoegd.

In dit geval is het beter om de links vanaf de achterkant te tellen. Het gaat namelijk altijd om de een-na-laatste link, die mogelijk een border aan de onderkant moet krijgen. 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 af zouden gaan.

margin-bottom: -1px; Afbeelding 13: zonder negatieve marge bij een-na-laatste knop komt laatste knop iets te hoog te staan

Dit zijn de laatste knoppen uit het menu, zoals ze in een smal browservenster worden weergegeven. 'Link acht' krijgt gelijk hieronder een border aan de onderkant.

'Link zeven' heeft geen border aan de onderkant. De border die je daar ziet, is de border aan de bovenkant van link 'Top'. Hierdoor komt 'Link acht' 1 px lager uit dan 'Link zeven'.

Omdat de <li>'s waar de links in staan naar links worden gefloat, komt hierdoor ook 'Top' 1 px te laag te staan. Dit is de reden van de verspringende lijn onder 'Link zeven' en 'Link acht' op de afbeelding.

Om dat te corrigeren wordt aan 'Link acht' aan de onderkant een negatieve marge van 1 px gegeven. Deze trekt alles onder 'Link acht', dus ook 'Top', 1 px omhoog, waardoor alles weer op de juiste hoogte staat.

border-bottom: black solid 1px;

Border aan de onderkant.

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 menu en kolommen staan. Alleen de header staat niet binnen deze div.

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, die alleen zichtbaar moet zijn in browservensters smaller dan 600 px.

display: none;

In browservensters 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.4em;

Hierboven is de lettergrootte verkleind tot 1,2 em. Dat is veel kleiner dan de standaardlettergrootte van een <h1>. In browservensters breder dan 600 px is er meer ruimte, daarom wordt de lettergrootte hier weer verhoogd. 1,4 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.

article

Alle <article>'s. Dat is er hier maar eentje. De kolommen staan erin.

padding-top: 55px;

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.

article h2:first-child

De <h2> die het eerste kind is van <article>. Dat is de <h2> met 'Eigenlijke inhoud van de pagina'.

margin: 0 0 -2em;

Omdat voor links geen waarde is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 0 0 -2em 0 in de volgorde boven – rechts – onder – links.

Alleen aan de onderkant een negatieve marge. Die is bedoeld om een kier in de oranje achtergrondkleur te voorkomen. Deze negatieve marge is ook al opgegeven bij article h2:first-child, waar ook de uitleg is te vinden. Hier wordt alleen de grootte van de marge aangepast.

nav

Alle <nav>'s. Dat is er hier maar eentje, het menu staat erin. De achtergrond hiervan is lichtgroen, hoewel je hier maar weinig van die achtergrondkleur ziet.

width: 100%;

Het menu moet over de volle breedte van de pagina komen te staan, gelijk onder <header>.

Een <nav> is een blok-element. Normaal genomen krijgt een blok-element automatisch dezelfde breedte als z'n ouder. Dat is hier div#wrapper. Ook div#wrapper is een blok-element en wordt daarom weer even breed als z'n ouder. Dat is <body>. div#wrapper en daardoor <nav> worden dus normaal genomen even breed als de pagina.

Maar hier niet. In <nav> zit een <h2> met 'Menu'. Die is bij nav h2 verborgen met display: none; en telt daarom hier niet mee.

Afbeelding 14: als geen breedte wordt opgegeven bij het menu, wordt dit veel te smal
Afbeelding 14: het tot grote droefenis stemmende resultaat als je niet zelf een breedte aan <nav> geeft. De bezuinigingen van Rutte zijn er niets bij.

Verder zit er een <ul> in de <nav>. De <li>'s in die <ul> worden naar links gefloat. Meer zit er niet in de <nav>. En als de inhoud van een blok-element wordt gefloat, krijgt het blok-element niet meer automatisch de volle breedte van z'n ouder, maar wordt niet breder dan nodig is om de inhoud weer te geven.

Door de <nav> een breedte van 100% te geven, wordt hij toch even breed als z'n ouder <article>, en omdat <article> even breed is als <body>, wordt de <nav> ook even breed als de pagina.

position: absolute;

Om de <nav> en dus het daarin zittende menu op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste voorouder die zelf een absolute, relatieve of fixed positie heeft. Dat is hier div#wrapper.

top: 0;

Helemaal bovenaan div#wrapper neerzetten. Omdat div#wrapper gelijk onder <header> begint, staat het menu tegen <header> aan.

#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 8. Daarom is een class gebruikt.

display: none;

De link naar boven is alleen nodig in browservensters smaller dan 600 px, waar het menu onderaan komt te staan. In bredere vensters is hij overbodig en kan dus worden verborgen.

nav li

Alle <li>'s binnen <nav>. Er is hier maar één <nav>, waarbinnen het menu staat. Binnen elke <li> staat één link van dat menu.

width: 12%;

Een breedte in procenten wordt altijd gemeten ten opzichte van de ouder. Dat is hier <nav>, die bij nav even breed als de pagina is gemaakt.

Er zijn acht lijst-items. Om de volle breedte van <nav> te vullen, zou je elk lijst-item 12,5% breed moeten maken. Dat gaat grandioos mis. Die procenten moeten naar pixels worden vertaald, en daarbij worden enorme afrondingsfouten gemaakt door Google Chrome, Safari en Opera, wat soms wel 'n volle centimeter lege ruimte aan de rechterkant oplevert.

Daarom gebruik ik hele getallen, dat gaat wel goed.

Samen met de verplaatsing van 1 px naar links die gelijk hieronder wordt opgegeven, en met de marge links van de eerste <li>, die bij nav li:first-child wordt opgegeven, staat het menu horizontaal in het midden van de pagina.

margin-left: -1px;

Bij nav a wordt een witte border van 2 px aan de <a>'s in de <li>'s gegeven. Waar twee knoppen tegen elkaar aan staan, wordt die border 4 px breed. Dat is breder dan mooi is. Door elke <li> 1 px naar links te schuiven, worden de twee borders samen 3 px breed, omdat 1 px van de linkerborder van elke knop over de rechterborder van z'n buurvrouw komt te staan. Dat past beter bij de dikte van de rest van de border.

nav li:first-child

De <li> die het eerste kind is van <nav>. Er is hier maar één <nav>, waarbinnen het menu zit. Dit is het lijst-item, waarbinnen 'Link een' zit.

margin-left: 2.5%;

Een marge in procenten wordt altijd gemeten ten opzichte van de ouder. Dat is hier <nav>.

Het complete menu is 100% breed. Maar elk van de acht <li>'s heeft bij nav li maar een breedte van 12% gekregen, samen 96%. Om de acht <li>'s horizontaal gecentreerd te krijgen, moet ik dus links een marge van 2% aanbrengen. Rechts van de laatste <li> blijft dan automatisch ook een marge van 2% over.

Maar bij nav li worden de <li>'s ook nog 1 px naar links geschoven, dus de totale breedte van de <li>'s is geen 96%, maar 96% min 8 px. Uitproberen levert op dat een marge van 2,5% links van de eerste <li> precies goed is: de acht knoppen staan nu horizontaal gecentreerd.

(Ja, inderdaad. Als je er 'n schuifmaat bij pakt, zie je dat ze niet in het midden staan. Als je dat met het blote oog kunt zien, zou ik je aanraden te solliciteren bij de koopvaardij. Er ligt daar ongetwijfeld 'n mooie carrière als verrekijker-zonder-verrekijker voor je in het verschiet.)

nav a

De links binnen <nav>. Er is hier maar één <nav>, waarbinnen het menu zit. Dit zijn de links die bij dat menu horen.

background: black;

Hieronder wordt als achtergrond voor de knoppen van het menu een gradiënt, een verlopende kleur, gegeven. Die kleur verloopt van zwart via grijs naar donkergrijs. In Internet Explorer 8 kan dit alleen met een aparte afbeelding worden weergegeven. Daarom krijgt die browser gewoon een zwarte achtergrondkleur. De hier gelijk onderstaande linear-gradient kent Internet Explorer 8 niet, daarom negeert hij die hele tweede background gewoon. Browsers die linear-gradient wel kennen, gebruiken de background hieronder, omdat die latere background deze background overrulet.

(Internet Explorer 9 kent ook geen gradiënten, maar daarvoor wordt het verderop opgelost met behulp van SVG)

background: -moz-linear-gradient(left, #000 0%, #595959 50%, #131313 100%); background: -o-linear-gradient(left, #000 0%, #595959 50%, #131313 100%); background: -webkit-linear-gradient(left, #000 0%, #595959 50%, #131313 100%); background: linear-gradient(to right, #000 0%, #595959 50%, #131313 100%);

Als je goed kijkt, zie je dat hier in feite vier keer vrijwel hetzelfde staat: background: linear-gradient (left, #000 0%, #595959 50%, #131313 100%). Alleen staat bij de vierde keer geen left, maar to right. Waarom dit vier keer wordt herhaald, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-. Waarom er de vijfde keer to right staat, wordt hieronder verklaard.

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.

linear-gradient valt in een aantal delen uiteen.

left: de kant waar de gradiënt begint. Standaard is dat de bovenkant. Omdat de gradiënt hier van links naar rechts loopt, moet ik het opgeven.

Als vierde en laatste staat hier de uiteindelijke vorm van linear-gradient, zonder voorvoegsel. Hier staat geen left, maar to right. De notatie voor de richting is nogal wat keren veranderd. Op 'n gegeven moment leek het erop dat het aangeven van de beginrichting (hier left) goed werkte. Waarop het in alle browsers is geïmplementeerd. Met een voorvoegsel, want het is nog experimenteel.

Vervolgens bleek in de praktijk dat dit niet goed werkte. In plaats van het vertrekpunt left bleek het beter het eindpunt van de gradiënt aan te geven: to right. Dat is de, zoals het er nu uitziet, definitieve syntax.

Zolang de variant met voorvoegsels wordt herkend door de browser, wordt de oude syntax gebruikt, inclusief de verouderde richtingsaanduiding. Zodra een browser de uiteindelijke syntax zonder voorvoegsel herkent, overrulet deze de oude syntax, omdat hij als vierde en laatste in de css staat. Een aardige illustratie van het nut van voorvoegsels tijdens de experimentele fase: beide vormen van de syntax kunnen naast elkaar worden gebruikt.

Na de richting staan drie keer twee waardes, gescheiden door een komma. De eerste waarde is steeds de kleur, de tweede de plaats waar die kleur staat.

#000 0%: de kleur #000 (zwart) op 0% vanaf de linkerkant neerzetten (dat is helemaal links).

#595959 50%: de kleur #595959 (grijs) op 50% vanaf links neerzetten (dat is precies in het midden).

#131313 100%: de kleur #131313 (donkergrijs) op 100% vanaf links neerzetten (dat is helemaal rechts).

Er zijn drie plaatsen opgegeven die een bepaalde kleur moeten krijgen: links, midden en rechts. De overgang tussen die kleuren verloopt geleidelijk, dat regelt de browser verder. Dit is een hele simpele gradiënt, maar je kunt ook tig kleuren op tig plaatsen aangeven. En ook nog in allerlei richtingen.

color: white;

Voorgrondkleur wit, waardoor ook de tekst wit wordt. De achtergrond is vrijwel zwart, dus de normale zwarte tekst is hier wat minder handig.

border: white solid;

Witte rand rondom de links. De breedte geef ik gelijk hieronder op.

border-width: 2px 2px 0;

Kleur en stijl van de rand is gelijk hierboven al opgegeven.

Omdat voor links geen waarde is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 2px 2px 0 2px in de volgorde boven – rechts – onder – links. Aan alle kanten, behalve onder, een witte rand.

Deze manier van het opgeven van een border kost minder css, dan wanneer je drie aparte borders zou opgeven voor boven, rechts en links.

(Tussen twee knoppen in, waar 2 borders elkaar raken, is de border geen 4 px maar slechts 3 px breed, omdat bij nav li de <li>'s 1 px naar links worden gezet, zodat de borders iets over elkaar heen staan. Dat ziet er beter uit.)

border-radius: 25px 25px 0 0;

Links‑ en rechtsboven ronde hoeken, rechts- en linksonder gewoon rechte hoeken. Omdat er voor de ronde hoeken maar één maat is opgegeven, worden ze 25 px hoog en 25 px breed. Je kunt ook twee maten opgeven, dan krijg je ellipsvormige hoeken.

Anders dan de naam van deze eigenschap suggereert, krijgt ook de achtergrondkleur (en ook een eventuele achtergrond-afbeelding) ronde hoeken.

nav li:nth-last-child(2) a

De <a>'s binnen een <li> binnen een <nav>. Hier is maar één <nav>. Maar dit geldt niet voor alle <li>'s, het gaat om één bepaalde <li>: de <li> binnen <nav> die het tweede kind van <nav> is, 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.)

Zoals bij alle <li>'s, zit ook binnen deze lijst-items maar één <a>. Uiteindelijk geldt dit dus voor de tweede link van het menu, van achteraf geteld.

In dit geval is het belangrijk om exact deze selector te gebruiken. Bij nav li:nth-last-child(2) a heeft deze <a> een border aan de onderkant gekregen. Die moet hier worden weggehaald. Door exact dezelfde selector te gebruiken, weet je zeker dat het altijd om exact diezelfde <a> gaat, en niet om z'n buurmeisje omdat er 'n <a> is tussengevoegd of weggehaald.

border-bottom: none;

De bij nav li:nth-last-child(2) a aan de onderkant gegeven zwarte border moet weg, want die steekt hier aan de onderkant uit.

Bij nav a hierboven is de border al bij alle <a>'s aan de onderkant weggehaald, maar dat werkt niet bij deze <a>. De border bij deze <a> is aangebracht met een selector waarin drie elementen staan: nav, li en a. Bovendien staat er nog de pseudo-class nth-last-child(2) in.

Om de border weg te halen, moet de selector minstens evenveel gewicht, evenveel specificiteit hebben. Alleen nav a heeft dat niet, want daar zitten alleen maar twee elementen in. Eén te weinig en de pseudo-class mist ook.

Daarom moet voor deze <a> de border aan de onderkant apart worden weggehaald met een selector die evenveel specificiteit (of meer) heeft, als waar de border mee is aangebracht. Deze selector heeft precies evenveel specificiteit, en omdat hij later in de css staat, overrulet hij de eerdere selector.

css voor vensters breder dan 700 px

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

De css die hier tot nu toe staat, geldt ook voor browservensters breder dan 700 px. Elk venster dat minimaal 600 px breed is, is immers ook 700 px breed. De css die hieronder staat, geldt alleen voor browservensters breder dan 700 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 700 px gaat.

#een

Het element met id="een". Dit is de eerste kolom. De achtergrond hiervan is oranje.

display: table-cell;

Weergeven alsof het een cel in een tabel is. Bij #twee wordt ook de tweede kolom op deze manier weergegeven. Hierdoor gedragen #een en #twee zich precies zoals twee cellen in een normale html-tabel zich zouden gedragen. Het grootste voordeel daarvan is dat ze beide automatisch even hoog worden. Daardoor loopt de achtergrondkleur bij beide kolommen even ver door, zonder dat hier allerlei kunstgrepen voor nodig zijn.

Ook borders tussen de kolommen worden even lang als de langste kolom, zonder dat allerlei extra grappen en grollen nodig zijn, zoals achtergrond-afbeeldingen.

Als je op deze manier met behulp van css cellen in een tabel maakt, zet de browser er automatisch een <td> en een <table> omheen. Daar merk je verder niets van.

Tabellen voor lay-out worden sterk afgeraden, en terecht. Het is een manier van coderen die nog stamt uit de tijd dat er geen css bestond. Tabellen voor lay-out zijn slecht toegankelijk voor screenreaders en dergelijke (en dus ook voor zoekmachines), zijn een nachtmerrie om te onderhouden, kosten veel meer code dan nodig is en er is ook nog 'n statistisch verband tussen tabellen en zweetvoeten aangetoond.

Kortom: een en al kommer en kwel.

En toch gebruik ik ze. Die nadelen gelden voor een html-tabel. Die is bedoeld voor tabulaire gegevens, zoals een kalender. Maar hier gaat het om css-tabellen. Er wordt niets aan de structuur van de html veranderd. Daardoor hebben deze tabellen geen enkel nadeel, wat betreft de toegankelijkheid. Ook kosten ze nauwelijks extra code.

Alleen moet je ook niet al te enthousiast css-tabellen gaan gebruiken, want een 37 niveaus diep geneste css-tabel leidt ook tot overspannenheid en zweetvoeten.

width: 63%;

Breedte. Deze css-tabel bestaat uit twee cellen. Net als in een gewone html-tabel, wordt de overblijvende breedte van 37% opgevuld door de tweede cel.

border-right: black solid 1px;

Lijntje rechts.

#een h3

Alle <h3>'s binnen het element met id="een". Dat is er hier maar eentje: de bovenste kopregel in de eerste kolom met 'Beschrijving van de onderdelen'.

margin-top: 10px;

Kleine ruimte aan de bovenkant.

Over het gebruik van display: table-cell; is vrij weinig informatie te vinden, en al helemaal niet over de marge boven het eerste element in zo'n tabelcel.

Dat dit een marge van 10 px aan de bovenkant van de <h3> oplevert, is vrij logisch.

Maar het blijkt ook een marge aan de bovenkant van de <h3> in de tweede kolom (en in een breder browservenster ook de <h3> in de derde kolom) op te leveren.

In een echte html-tabel word de inhoud van een cel verticaal gecentreerd, tenzij je dat verandert met vertical-align. In deze css-tabelcellen wordt de inhoud niet verticaal gecentreerd, tenzij je dat expliciet opgeeft met vertical-align.

Er zit dus verschil tussen de weergave van html-tabelcellen en css-tabelcellen.

Kennelijk wordt bij gebruik van display: table-cell; de grootste marge aan de bovenkant van het eerste element toegepast in élke kolom. Want als de marge aan de bovenkant van de <h3> in de tweede of derde kolom het grootst wordt gemaakt, wordt die marge boven álle <h3>'s gezet.

#twee

Het element met id="twee". Dit is de tweede kolom. De achtergrond hiervan is roze.

display: table-cell;

Dit zorgt ervoor dat de tweede kolom niet onder, maar naast de eerste kolom komt te staan. De uitleg staat bij #een.

#twee h3

Alle <h3>'s binnen het element met id="twee". Dat is er hier maar eentje: de kopregel in de tweede kolom met 'Tweede kolom'.

margin-bottom: 20px;

Kleine afstand tussen kopregel en tekst eronder.

#drie

Het element met id="drie". Dit is de derde kolom. De achtergrond hiervan is donkergroen.

In feite is dit hier nog geen kolom. Pas in nog bredere browservensters komt dit element naast de andere twee kolommen te staan. Hier staat het nog onder de eerste en tweede kolom.

border-top: black solid 1px;

Randje aan de bovenkant. Omdat #drie onder de eerste en tweede kolom staat, staat dit randje tussen deze kolommen en #drie.

css voor vensters breder dan 810 px

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

De css die hier tot nu toe staat, geldt ook voor browservensters breder dan 810 px. Elk venster dat minimaal 600 of 700 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.

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.

font-size: 110%;

Iets groter dan standaard. 't Zal de leeftijd zijn, maar ik vind de standaardgrootte wat te klein. Nu de browservensters wat breder worden, is er ruimte voor een iets grotere letter.

.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 de drie kolommen met tekst 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 menu en kolommen staan. Alleen de header staat niet binnen deze div.

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 de drie kolommen met tekst binnen die div. Daardoor blijft de header, ook bij scrollen, 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.

position: absolute;

Om div#wrapper op een bepaalde plaats neer te kunnen zetten. Er wordt altijd gepositioneerd ten opzichte van de eerste voorouder die zelf een fixed, absolute of relatieve positie heeft. Als die er niet is, zoals hier het geval is, wordt gepositioneerd ten opzichte van het venster van de browser.

Aan de bovenkant wordt div#wrapper gelijk onder de header gezet, aan de onderkant gelijk met de onderkant van het venster van de browser. div#wrapper staat dus als het ware klem tussen header en onderkant van het venster.

Binnen div#wrapper staat een <article>, waarbinnen de drie kolommen met tekst staan. <article> met de daarin zittende kolommen met tekst past niet binnen div#wrapper, het is te hoog. (<article> is eigenlijk 'n gewone div, maar dan eentje met 'n semantische betekenis.)

Door overflow op auto te zetten bij div#wrapper, ontstaat een verticale scrollbalk aan de rechterkant van div#wrapper. <article> met de daarin zittende kolommen met tekst kan nu worden gescrold, waarbij div#wrapper op z'n plaats blijft staan: gelijk onder de header. Omdat het scrollen binnen div#wrapper plaatsvindt, blijft ook de header gewoon op z'n plaats staan.

(Ook het menu scrolt niet mee, maar dat wordt bij .no-touch nav met behulp van position: fixed; vastgezet.)

top: 7em;

<header>, dat gelijk boven div#wrapper staat, is 7 em hoog. Daarom moet div#wrapper op 7 em vanaf de bovenkant van het venster van de browser staan, om goed op <header> aan te sluiten.

bottom: 0;

Onderkant van div#wrapper aan de onderkant van het browservenster zetten.

overflow: auto;

Als de inhoud van div#wrapper meer is dan erbinnen past, verschijnt een verticale scrollbalk.

Er verschijnt geen horizontale scrollbalk, omdat de inhoud van div#wrapper automatisch aan de breedte van div#wrapper wordt aangepast. Alleen de hoogte kan dus te groot zijn.

.no-touch article

De <article>'s binnen een element met class="no-touch". Er is hier maar één <article>. De kolommen met tekst en het menu 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 de kolommen met tekst te scrollen, terwijl header en menu 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.

margin-left: 20%;

Een marge in procenten wordt altijd genomen ten opzichte van de ouder. Dat is hier div#wrapper.

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 onder <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 55 px gegeven om ruimte te maken voor het menu, dat in smallere browservensters bovenaan komt te staan. Hier wordt het menu links neergezet en is die padding dus niet nodig.

article h2:first-child

De <h2> die het eerste kind is van <article>. Dat is de <h2> met 'Eigenlijke inhoud van de pagina'.

margin: 10px 0 -2em;

Bij article h2:first-child is aan de bovenkant de marge weggehaald. In deze grotere browservensters is wat meer ruimte, daarom wordt hier weer een kleine afstand tussen deze kop en de header aangebracht.

.no-touch article h2:first-child

De <h2> die het eerste kind is van <article> binnen een element met class="no-touch". Dat is de <h2> met 'Eigenlijke inhoud van de pagina'.

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 de kolommen met tekst te scrollen, terwijl header en menu 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.

padding-left: 1.3%;

Bij article h2:first-child heeft deze <h2> aan de linkerkant een padding van 1% gekregen. Hier wordt dat verandert in 1,3%.

Deze <h2> staat boven de eerste kolom. Voor het oog lijkt hij daar deel van uit te maken. In werkelijkheid staat hij daarbuiten: zijn ouder is niet de eerste kolom #een, maar <article>. Ook de ouder van #een is <article>.

Omdat gelijk hieronder de padding aan de linkerkant van #een wordt veranderd, moet ook de padding links van deze <h2> worden aangepast, anders staat de inhoud van #een niet meer netjes uitgelijnd met deze <h2>.

Waarom #een een padding van 1,3% krijgt, en waarom dus deze <h2> die ook moet krijgen, staat gelijk hieronder.

.no-touch #een

Het element met id="een" binnen een element met class="no-touch". Dit is de eerste kolom. De achtergrond hiervan is oranje.

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 de kolommen met tekst te scrollen, terwijl header en menu 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.

padding: 3em 1% 1% 1.3%; Afbeelding 15: de eerste kolom staat iets onder het menu, daarom moet de padding links iets groter worden

Bij #een is een padding gegeven aan #een. De padding aan de linkerkant is daar 1%, net als aan de rechterkant. Hier wordt de padding links iets vergroot. #een staat in werkelijkheid iets onder het menu, omdat je anders door afrondingsverschillen in sommige browsers een kier krijgt tussen menu en eerste kolom.

Op de afbeelding is de achtergrondkleur van het menu even doorzichtig gemaakt, zodat te zien is dat #een onder het menu doorloopt. Als de padding links op 1% was blijven staan, was de padding daardoor te klein geweest. De padding links wordt gewoon vanaf de linkerkant van #een gemeten, of je die linkerkant nu ziet of niet. Een kleine verhoging met 0,3% zorgt ervoor dat de padding links weer groot genoeg is.

Een padding in procenten wordt altijd gemeten ten opzichte van de breedte van de ouder. Ook een marge aan boven- en onderkant wordt gemeten ten opzichte van de breedte van de ouder. Die ouder is hier <article>. Omdat <article> een blok-element is, wordt <article> even breed als z'n ouder. Dat is hier div#wrapper, ook een blok-element. Dat dus ook weer even breed wordt als z'n ouder <body>, oftewel: even breed als het venster van de browser.

Omdat de breedte van div#wrapper mee verandert met de breedte van het browservenster, verandert via deze hele keten ook deze padding in procenten mee met de breedte van het venster. Bij een breder venster is de padding dus groter dan bij een smaller venster.

#drie

Het element met id="drie". Dit is de derde kolom. In smallere browservensters is dit niet de derde kolom, maar staat dit element onder de eerste kolommen. De achtergrond hiervan is donkergroen.

-moz-column-count: 2; -webkit-column-count: 2; column-count: 2;

Als je goed kijkt, zie je dat hier in feite drie keer vrijwel hetzelfde staat: column-count: 2;. Waarom dit drie keer wordt herhaald, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-.

In browservensters met deze breedte is de derde kolom eigenlijk nog geen kolom: hij staat nog onder de eerste twee kolommen. Daardoor wordt hij wat breed. Lange regels zijn lastig te lezen. Door de inhoud van #drie in twee kolommen te splitsen, blijven de regels redelijk kort.

Hierbij moet je voorkomen dat deze kolommen te hoog worden. Het is uitermate onhandig, als je van de onderkant van de eerste kolom terug omhoog moet scrollen naar de bovenkant van de tweede kolom. In dit voorbeeld gaat het overal om korte teksten, waarbij dit probleem niet speelt.

.no-touch nav

De <nav>'s binnen een element met class="no-touch". Er is hier maar één <nav>, waarin het menu staat.

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 de kolommen met tekst te scrollen, terwijl header en menu 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, hoeft ook <nav> niet links in het browservenster te worden gezet.

width: 18%;

Een breedte in procenten wordt altijd genomen ten opzichte van de ouder. Dat is hier div#wrapper.

18% breed maken. <nav> met het menu komt links van <article> te staan. Bij .no-touch article is hiervoor aan de linkerkant van <article> 20% ruimte vrijgemaakt. Dat is 2% meer dan <nav> breed is, maar bij die 18% komen nog de padding en de border, die hieronder worden opgegeven.

De totale breedte van <nav> is dan ongeveer 20%. <article> staat in werkelijkheid 'n heel klein stukje onder <nav>, maar daar zie je niets van.

overflow: auto;

<nav> wordt hieronder fixed gepositioneerd. De bovenkant wordt iets hieronder met top: 7em gelijk onder de header gezet. Nog iets verder wordt de onderkant met bottom: 0; gelijk gezet met de onderkant van venster van de browser.

Hierdoor heeft <nav> feitelijk een hoogte gekregen, ook al is die niet expliciet opgegeven, omdat boven- en onderkant op een vaste plaats staan.

Als de lettergrootte heel groot wordt, zou de tekst mogelijk niet meer in <nav> passen. Normaal genomen zou die dan toch zichtbaar worden, omdat overflow standaard op visible staat. Hier is dat niet zo, omdat het menu fixed is gepositioneerd. Wat niet binnen <nav> past, verdwijnt aan de onderkant van het venster van de browser en is op geen enkele manier nog te zien.

Door overflow op auto te zetten ontstaat een verticale scrollbalk naast <nav>, maar alleen als dat nodig is, als de inhoud niet meer in <nav> past. Hierdoor blijft de volledige inhoud ook bij een heel grote letter nog steeds zichtbaar.

font-size: 1em;

Bij nav is de lettergrootte 0,7 em gemaakt. Dat is vrij klein en leuk voor kleine browservensters, maar hier is meer ruimte, dus kan de lettergrootte weer worden verhoogd.

Als eenheid neem ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

border-right: black solid 1px;

Lijntje aan de rechterkant.

padding: 0 1%;

Een padding in procenten wordt altijd genomen ten opzichte van de breedte van de ouder. Dat is hier div#wrapper.

Omdat voor onder en links geen waarde is ingevuld, krijgen deze automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 1% 0 1% in de volgorde boven – rechts – onder – links.

Links en rechts wat ruimte tussen het menu in <nav> en de buitenkant van <nav>.

Omdat de achtergrondkleur doorloopt achter een padding, blijft toch de volledige ruimte van het menu lichtgroen. Bij een marge loopt de achtergrondkleur niet door en zou er links en rechts een kier ontstaan.

position: fixed;

Vastzetten ten opzichte van het venster van de browser, zodat het menu ook bij scrollen op dezelfde plaats blijft staan.

top: 7em;

<header> is 7 em hoog. De bovenkant van <nav> komt hier gelijk tegenaan te staan.

bottom: 0;

Onderkant van <nav> helemaal aan de onderkant van het venster van de browser zetten.

.no-touch nav h2

De <h2>'s binnen een <nav>, die weer binnen een element met class="no-touch" zit. Er is hier maar één <nav>, waarin maar één <h2> zit: het kopje met 'Menu'.

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 de kolommen met tekst te scrollen, terwijl header en menu 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 het menu niet links wordt gepositioneerd, is deze <h2> ook niet nodig.

display: block;

Bij nav h2 is dit kopje verborgen. Als <nav> met het menu links wordt gepositioneerd, is het kopje weer welkom.

De rest van de opmaak is al opgegeven bij nav h2.

margin-top: 2.7em;

Met deze marge aan de bovenkant komt het kopje 'Menu' even hoog te staan als de kopjes 'Beschrijving van de onderdelen' en 'Tweede kolom' in de eerste en tweede kolom.

Bij zoomen blijven alle drie de kopjes op dezelfde hoogte staan. Als de lettergrootte wordt veranderd in browsers waarin dat kan, komt deze <h2> iets hoger of lager dan de andere twee kopjes te staan. Maar het gaat niet om 'n enorme afwijking.

.no-touch nav li

De <li>'s binnen een <nav>, die weer binnen een element met class="no-touch" zit. Er is hier maar één <nav>, waarin de <li>'s met de links van het menu zitten.

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 de kolommen met tekst te scrollen, terwijl header en menu 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. Deze regel zorgt ervoor dat de links in het menu onder elkaar komen te staan, wat alleen nodig is als <nav> links wordt gepositioneerd.

width: 100%; Afbeelding 16: als geen breedte wordt opgegeven bij de lijst-items in het menu, worden de knoppen veel te smal

Een <li> is een blok-element. Normaal genomen wordt dat automatisch even breed als z'n ouder, hier <nav> (te herkennen aan de groene achtergrond). Maar bij nav li is een breedte van 12% opgegeven, Een breedte wordt altijd genomen ten opzichte van de ouder, hier <nav>. Dat levert het resultaat op dat op de afbeelding hiernaast is te zien. Niet helemaal wat de bedoeling is.

De tekst van de links wordt wel weergegeven, omdat overflow standaard op visible staat. Maar achtergrond en dergelijke worden niet breder dan die 12%.

Daarom wordt hier handmatig opgegeven dat het blok-element de volle breedte moet krijgen. Ook hier wordt die breedte weer ten opzichte van de ouder <nav> genomen. Ik had ook auto, de standaardinstelling voor breedte, kunnen gebruiken hier. Dat heeft in dit geval hetzelfde effect, omdat blok-elementen normaal genomen even breed worden als hun ouder.

De <li>'s, en dus de grijze achtergrond, worden nog steeds iets smaller dan de groene <nav>, omdat de <nav> bij .no-touch #wrapper links en rechts een padding heeft gekregen. Omdat die padding links en rechts even groot is en de <li>'s de volle ruimte ertussen vullen, worden de <li>'s gelijk horizontaal gecentreerd.

float: none;

Een <li> is een blok-element. Normaal genomen komt dat op een nieuwe regel te staan. Daardoor zouden de links onder elkaar en niet naast elkaar komen te staan.

Bij nav li is float: left; opgegeven, zodat de <li>'s en de links daarin naast elkaar komen te staan. Door dat hier op te heffen, komen de <li>'s weer gewoon onder elkaar te staan, zoals welopgevoede blok-elementen betaamt.

margin: 0;

Bij nav li en nav li:first-child hebben de <li>'s een marge aan de linkerkant gekregen. Hier moet die weer weg, omdat ze anders niet netjes uitgelijnd onder elkaar en niet goed horizontaal gecentreerd staan.

.no-touch nav a

De <a>'s binnen een <nav>, die weer binnen een element met class="no-touch" zit. Er is hier maar één <nav>, waarbinnen de links van het menu zitten.

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 de kolommen met tekst te scrollen, terwijl header en menu 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 css in deze regel is alleen bedoeld voor een menu, waarin de links niet naast elkaar, maar onder elkaar staan.

background: #ccc;

Grijze achtergrondkleur.

color: black;

Voorgrondkleur zwart, waardoor ook de tekst zwart wordt. Bij nav a is de voorgrondkleur wit gemaakt, maar op een grijze achtergrond is dat veel te onduidelijk.

height: 2.2em;

Hoogte. Door de hoogte aan de <a> te geven en niet aan de <li>, wordt de hele <a> gevoelig voor hoveren en klikken, en niet alleen de tekst binnen de <a>.

Een <a> is een inline-element, en hoogte en dergelijke kan alleen aan een blok-element worden gegeven. Bij nav a is de <a> veranderd in een blok-element, dus dat is al geregeld.

Op diezelfde plaats is ook een hoogte van 1,2 cm opgegeven. Die wordt hier veranderd in een iets lagere relatieve maat. Iets kleiner kan, omdat dit menu niet met de vinger wordt bediend. Door de relatieve eenheid em te gebruiken, wordt de hoogte van de knoppen gekoppeld aan de lettergrootte.

line-height: 2.2em;

Tekst wordt automatisch halverwege de regelhoogte neergezet. Door de regelhoogte even hoog als de gewone hoogte te maken, wordt de tekst verticaal gecentreerd.

Door de relatieve eenheid em te gebruiken, wordt de grootte van de letters gekoppeld aan de hoogte van de knoppen. Bovendien verandert door het gebruik van em ook in Internet Explorer de regelhoogte mee met de lettergrootte.

border: black solid;

Zwart randje. De breedte geef ik gelijk hieronder op.

border-width: 0 1px 1px;

Gelijk hierboven zijn kleur en stijl al opgegeven.

Omdat voor links geen waarde is opgegeven, krijgt dat automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk 0 1px 1px 1px in de volgorde boven – rechts – onder – links. Aan alle kanten een lijntje, behalve aan de bovenkant.

Afbeelding 17: als ook aan de bovenkant een border wordt gegeven, krijg je tussen twee knoppen een te dikke border

Als ook aan de bovenkant een border zou komen, zou er tussen twee knoppen een dubbele lijn komen te staan, omdat de lijnen aan boven- en onderkant tegen elkaar aan komen te staan. Dit is op de afbeelding hiernaast te zien. Door de lijn aan de bovenkant weg te laten, voorkom je dat. Nu mist wel een lijn aan de bovenkant van de bovenste knop, maar dat wordt later opgelost.

border-radius: 0;

Bij nav a hebben de <a>'s ronde hoeken gekregen. Dat moet hier ook gebeuren, maar de daar opgegeven hoeken horen bij een horizontale menubalk met de knoppen naast elkaar. Daar kregen álle knoppen ronde hoeken, hier moeten alleen de bovenste en de onderste knop ronde hoeken krijgen.

Om te beginnen alle ronde hoeken weghalen. Dan zijn de binnenste knoppen al klaar, want die blijven gewoon rechthoekig. Voor de bovenste en onderste breng ik later de ronde hoeken weer aan, maar dan de juiste.

.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 de kolommen met tekst te scrollen, terwijl header en menu 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: 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.

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.

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

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.

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 de kolommen met tekst te scrollen, terwijl header en menu 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 bij .no-touch nav a 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.

.no-touch nav a:focus, .no-touch nav a:hover

De <a>'s binnen een <nav>, die weer binnen een element met class="no-touch" zit. Maar alleen als de <a>'s focus hebben of als erover wordt gehoverd. Er is hier maar één <nav>, waarbinnen de links van het menu zitten.

Waarom :focus en :hover beide zijn gebruikt, is te vinden bij :hover, :focus en :active voor muis, toetsenbord, touchpad en touchscreen.

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 de kolommen met tekst te scrollen, terwijl headerheader en menu 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. :focus en :hover werken in vrijwel geen enkele mobiele browser goed, dus hoeven ze deze css niet te krijgen.

Het wordt hier gebruikt om de knoppen te laten verkleuren. Bij veel mobiele browsers zorgt het verkleuren van de knoppen alleen maar voor verwarring, omdat ze in die browsers alleen verkleurd zijn, als je met de back-knop van de browser teruggaat.

background: black;

Achtergrond zwart maken.

color: white;

Voorgrondkleur wit maken, waardoor ook de tekst wit wordt.

outline: none;

Een link die focus heeft, krijgt normaal genomen een outline. Daardoor weten mensen die de Tab-toets gebruiken om van link naar link te gaan, welke link focus heeft en gevolgd wordt als op Enter wordt gedrukt. Dat is hier niet nodig, omdat een link die focus heeft al verkleurt. Een outline is in dit geval foeilelijk.

css voor vensters breder dan 1200 px

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

De css die hier tot nu toe staat, geldt ook voor browservensters breder dan 1200 px. Elk venster dat minimaal 600, 700 of 810 px breed is, is immers ook 1200 px breed. De css die hieronder staat, geldt alleen voor browservensters breder dan 1200 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 1200 px gaat.

#een section

Alle <section>'s binnen het element met id="een". Dit zijn alle <section>'s binnen de eerste kolom. Elk hoofdstukje binnen de eerste kolom staat in een eigen <section>.

-moz-column-count: 2; -webkit-column-count: 2; column-count: 2;

Als je goed kijkt, zie je dat hier in feite drie keer vrijwel hetzelfde staat: column-count: 2;. Waarom dit drie keer wordt herhaald, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-.

In deze bredere browservensters worden de regels binnen de eerste kolom wat lang. Daarom wordt ook de inhoud van de eerste kolom zelf in twee kolommen neergezet.

Hierbij moet je voorkomen dat deze kolommen hoger dan het venster van de browser worden. Het is uitermate onhandig, als je van de onderkant van de eerste kolom terug omhoog moet scrollen naar de bovenkant van de tweede kolom.

Hier is niet in één keer de volledige tekst binnen de eerste kolom in twee kolommen gesplitst, want dan zou dit probleem zich voordoen. De tekst binnen elke <section> wordt in twee kolommen gesplitst, dus na elke <section> beginnen de kolommen opnieuw.

Hierdoor gaat het om vrij korte stukken tekst en wordt dit heen-en-weer scrollen voorkomen.

-moz-column-rule: rgba(0, 0, 0, 0.3) solid 1px; -webkit-column-rule: rgba(0, 0, 0, 0.3) solid 1px; column-rule: rgba(0, 0, 0, 0.3) solid 1px;

Als je goed kijkt, zie je dat hier in feite drie keer vrijwel hetzelfde staat: column-rule: rgba(0, 0, 0, 0.3) solid 1px;. Waarom dit drie keer wordt herhaald, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-.

Met column-rule wordt een lijntje aangebracht tussen de kolommen die met column-count zijn gemaakt. Hierbij hoeven alleen maar kleur, stijl en breedte van de lijn opgegeven te worden, precies hetzelfde als bij border. In dit geval wordt de kleur met behulp van rgba() opgegeven.

Het gebruik van rgba() kan bij iets oudere browsers grote problemen geven, tot en met het volledig onleesbaar worden van tekst. Deze browsers kennen wel css en veranderen dus bijvoorbeeld wel de voorgrondkleur als die gewoon met color is opgegeven, maar niet de achtergrondkleur als die met rgba() is opgegeven. Met 'n beetje pech levert dat 'n tekstkleur op, die niet of nauwelijks is te onderscheiden van de achtergrond.

In dit geval is er geen risico op zo'n ramp, omdat het hier alleen maar om een lijntje tussen kolommen gaat. Ik vermeld het risico hier toch even, omdat rgba() in oudere browsers echt tot het volledig onzichtbaar worden van tekst kan leiden.

Meestal wordt voor 'n kleur de hexadecimale notatie gebruikt, iets als color: #33ab01;. Daarbij worden niet alleen cijfers, maar ook letters gebruikt. 0 tot en met 9 werken precies hetzelfde als altijd, maar na de 9 komen nog A, B, C, D, E en F.

Als je telt, is 't dus: 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12, enz. Daarbij is A gelijk aan het tientallige 10, B aan 11, enz. Op deze manier kun je met twee cijfers en/of letters 256 mogelijkheden aangeven: van 00 tot en met FF.

De eerste drie getallen bij rgba() geven de kleur aan. Deze lopen van 0 tot en met 255, dus ook hiermee kun je 256 mogelijkheden aangeven. En omdat er drie getallen zijn levert dat 256 x 256 x 256 = 16.777.216 mogelijke kleuren op, net iets meer dan het aantal kleurpotloden in de gemiddelde kleurdoos van 'n kind.

De notatie bij rgba() geeft dus precies evenveel mogelijkheden als de hexadecimale.

Het eerste getal staat voor rood, het tweede voor groen en het derde voor blauw (feitelijk de Engelse namen, maar de eerste letter is toevallig in het Nederlands hetzelfde). Uit deze drie kleuren zijn alle kleuren op een monitor opgebouwd.

255 wil zeggen volledig aanwezig, 0 wil zeggen helemaal ontbrekend.

255, 255, 255 levert wit op, 0 , 0 , 0 zwart.

In plaats van getallen mag je ook percentages gebruiken, bijvoorbeeld: rgba(10%, 20%, 100%, 0.3).

Omdat in dit voorbeeld drie keer 0 is opgegeven, levert dit een zwarte kleur op.

Het vierde getal staat voor het alfa-kanaal. Hiermee wordt de doorzichtigheid aangegeven. Dit getal loopt van 0 naar 1. Volledig doorzichtig is 0, volledig ondoorzichtig is 1.

Het getal voor het alfa-kanaal wordt als decimale breuk aangegeven, dus bijvoorbeeld 0.5 wil zeggen halfdoorzichtig. Let erop dat je 'n punt gebruikt, de Amerikaanse manier om breuken aan te geven. Als je 'n komma gebruikt, denkt de browser dat er twee verschillende getallen staan.

In dit voorbeeld is deze achtergrondkleur behoorlijk ondoorzichtig: 0.3. Hierdoor zie je de lijntjes tussen de kolommen redelijk vaag. Dat is hier mooier dan volledig zwarte lijnen. Vind ik.

border-top: rgba(0, 0, 0, 0.3) solid 1px;

Aan de bovenkant van elke <section> ook een lijntje aanbrengen. Kleur en dergelijke zijn hetzelfde als het lijntje tussen de kolommen, dat gelijk hierboven bij column-rule wordt opgegeven.

padding: 10px 0;
Afbeelding 18: de kopjes staan te dicht op de tekst
Afbeelding 18: zonder padding aan boven- en onderkant.

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

Afbeelding 19: de kopjes staan op voldoende afstand van tekst
Afbeelding 19: met padding aan boven- en onderkant.

Aan de boven- en onderkant van elke <section> een kleine padding, zodat er boven en onder de gelijk hierboven opgegeven border wat ruimte ontstaat.

#een h4

De <h4>'s binnen het element met id="een". Dit zijn de kleine tussenkopjes in de eerste kolom.

-moz-column-span: all; -webkit-column-span: all; column-span: all;

Als je goed kijkt, zie je dat hier in feite drie keer vrijwel hetzelfde staat: column-span: all;. Waarom dit drie keer wordt herhaald, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-.

Bij #een section is de inhoud van de eerste kolom met behulp van column-count: 2; zelf ook weer in twee kolommen neergezet. Ook deze <h4>'s staan binnen #een section, dus die twee kolommen gelden ook voor deze kopjes.

Deze regel geeft opdracht om de <h4>'s niet binnen één kolom, maar over de volle breedte van álle (all) kolommen te zetten. Dat zijn er hier maar 2, maar deze eigenschap kent als waarden nou eenmaal alleen maar none en all. Als ik Wilders css zou willen leren, zou ik met deze eigenschap beginnen, want zelfs iemand met zo'n star zwart-wit wereldbeeld zou dit nog moeten kunnen begrijpen. (Ik moet er trouwens niet aan denken zo iemand uit te moeten leggen dat er meer kleuren zijn dan zwart en wit... Maar ik dwaal weer 'ns af, vrees ik.)

Internet Explorer 8 en 9 kennen geen kolommen, dus die negeren dit. Firefox kent wel kolommen, maar heeft column-span nog niet geïmplementeerd. In Firefox worden deze kopjes dan ook gewoon binnen de kolom gezet. Ooit zal dit ook in Firefox worden geïmplementeerd, mogen we aannemen. Omdat onbekend is of dit met of zonder -moz- zal gebeuren, zet ik hier voor de zekerheid ook de vorm met -moz- neer.

text-align: center;

Tekst horizontaal centreren.

margin: -5px 0 5px;

Omdat voor links geen waarde is opgegeven, krijgt links automatisch dezelfde waarde als rechts. Hier staat dus eigenlijk -5px 0 5px 0 in de volgorde boven – rechts – onder – links.

Aan de onderkant een kleine marge tussen de kopjes en de daaronder staande tekst.

Aan de bovenkant wordt het kopje met behulp van een negatieve marge iets naar boven geplaatst. Enig experimenteren leerde dat dit, samen met de bij #een section opgegeven padding aan boven- en onderkant, het mooiste resultaat opleverde.

#drie

Het element met id="drie". Dit is de derde kolom. In smallere browservensters is dit niet de derde kolom, maar staat dit element onder de eerste kolommen. De achtergrond hiervan is donkergroen.

-moz-column-count: 3; -webkit-column-count: 3; column-count: 3;

Als je goed kijkt, zie je dat hier in feite drie keer vrijwel hetzelfde staat: column-count: 3;. Waarom dit drie keer wordt herhaald, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-.

In deze bredere browservensters worden de regels binnen de derde kolom behoorlijk lang. Bij de css voor vensters breder dan 810 px is de inhoud van deze kolom bij #drie al in twee kolommen gesplitst. Hier is deze kolom zo breed geworden, dat de regels toch weer wat aan de lange kant worden. Daarom wordt de inhoud van de derde kolom nu in drie kolommen gesplitst.

Hierbij moet je voorkomen dat deze kolommen hoger dan het venster van de browser worden. Het is uitermate onhandig, als je van de onderkant van de eerste kolom terug omhoog moet scrollen naar de bovenkant van de tweede kolom. Omdat het in deze kolom om vrij weinig tekst gaat, speelt dat probleem hier niet.

css voor vensters breder dan 1500 px

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

De css die hier tot nu toe staat, geldt ook voor browservensters breder dan 1500 px. Elk venster dat minimaal 600, 700, 810 of 1200 px breed is, is immers ook 1500 px breed. De css die hieronder staat, geldt alleen voor browservensters breder dan 1500 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 1500 px gaat.

#een

Het element met id="een". Dit is de eerste kolom. De achtergrond hiervan is oranje.

background: url(101-pics/links.png) orange;

Bij #een heb ik met behulp van background een achtergrondkleur opgegeven. Hier gebruik ik weer background om een achtergrond-afbeelding toe te voegen. Omdat ik in beide gevallen background gebruik, moet ik hier ook de achtergrondkleur weer opnieuw opgeven.

Als je de zogenaamde 'shorthand' background gebruikt, worden waarden die je niet invult teruggezet naar de standaardwaarde. Daardoor zou de achtergrondkleur verdwijnen, als ik die niet opnieuw opgeef.

Als ik de eerste keer background-color had gebruikt en nu background-image zou gebruiken, zou de achtergrondkleur wel oranje blijven, omdat bij gebruik van background-image alleen de afbeelding wordt gewijzigd. De andere eigenschappen voor de achtergrond worden alleen bij gebruik van background naar de standaardwaarden teruggezet.

width: 48%;

Bij #een heeft de eerste kolom een breedte van 63% gekregen, zodat er ruimte kwam voor een tweede kolom. Hier wordt er nog een derde kolom naast gezet, daarom wordt de breedte verkleind.

#twee

Het element met id="twee". Dit is de tweede kolom. De achtergrond hiervan is roze.

background: url(101-pics/midden.png) 0 1px #fcc;

Bij #twee heb ik met behulp van background een achtergrondkleur #fcc opgegeven. Hier gebruik ik weer background om een achtergrond-afbeelding toe te voegen. Omdat ik in beide gevallen background gebruik, moet ik hier ook de achtergrondkleur weer opnieuw opgeven.

Als je de zogenaamde 'shorthand' background gebruikt, worden waarden die je niet invult teruggezet naar de standaardwaarde. Daardoor zou de achtergrondkleur verdwijnen, als ik die niet opnieuw opgeef.

Als ik de eerste keer background-color had gebruikt en nu background-image zou gebruiken, zou de achtergrondkleur wel #fcc blijven, omdat bij gebruik van background-image alleen de afbeelding wordt gewijzigd. De andere eigenschappen voor de achtergrond worden alleen bij gebruik van background naar de standaardwaarden teruggezet.

Verder wordt hier nog de positie van de achtergrond-afbeelding aangepast met 0 1px. Het eerste getal bepaalt de aanpassing in horizontale richting, het tweede in verticale. Horizontaal is er dus geen aanpassing, verticaal wordt de eerste achtergrond-afbeelding 1 px omlaag gezet.

De reden hiervan is de aandoening acedia. Niet van de browser of zo, maar van mij. Acedia is de Latijnse naam voor luiheid, maar ik noem mezelf liever niet lui. Als je zegt dat je acedia hebt, reageren mensen heel meelevend. Als je zegt dat je lui bent, ligt dat toch wat anders.

Bij het maken van de achtergrond-afbeeldingen ben ik wat slordig geweest. De tekst op de afbeelding met 'twee' staat 1 px hoger dan die op 'een'. Dat kan ik in 'n grafisch programma corrigeren, maar het is veel simpeler om de tweede afbeelding gewoon 1 px lager te laten beginnen. Nu staan de achtergrond-afbeeldingen toch netjes op gelijke hoogte.

width: 23%;

Tot nu toe stonden er maar twee kolommen naast elkaar. De eerste kolom had een breedte, en de tweede kolom mocht gewoon de rest van de ruimte opvullen.

Nu komt er een derde kolom naast de eerste twee te staan, dus de tweede kolom moet nu ook een breedte krijgen.

#drie

Het element met id="drie". Dit is de derde kolom. In smallere browservensters is dit niet de derde kolom, maar staat dit element onder de eerste kolommen. In vensters breder dan 1500 px, waar deze css voor is bedoeld, is dit echt een derde kolom. De achtergrond hiervan is donkergroen.

background: url(101-pics/rechts.png) 0 -1px #8fbc8f;

Bij #drie heb ik met behulp van background een achtergrondkleur #8fbc8f opgegeven. Hier gebruik ik weer background om een achtergrond-afbeelding toe te voegen. Omdat ik in beide gevallen background gebruik, moet ik hier ook de achtergrondkleur weer opnieuw opgeven.

Als je de zogenaamde 'shorthand' background gebruikt, worden waarden die je niet invult teruggezet naar de standaardwaarde. Daardoor zou de achtergrondkleur verdwijnen, als ik die niet opnieuw opgeef.

Als ik de eerste keer background-color had gebruikt en nu background-image zou gebruiken, zou de achtergrondkleur wel #8fbc8f blijven, omdat bij gebruik van background-image alleen de afbeelding wordt gewijzigd. De andere eigenschappen voor de achtergrond worden alleen bij gebruik van background naar de standaardwaarden teruggezet.

Verder wordt hier nog de positie van de achtergrond-afbeelding aangepast met 0 -1px. Het eerste getal bepaalt de aanpassing in horizontale richting, het tweede in verticale. Horizontaal is er dus geen aanpassing, verticaal wordt de eerste achtergrond-afbeelding 1 px omhoog gezet.

Bij het maken van de achtergrond-afbeeldingen ben ik wat slordig geweest. De tekst op de afbeelding met 'drie' staat 1 px lager dan die op 'een'. Dat kan ik in 'n grafisch programma corrigeren, maar het is veel simpeler om de derde afbeelding gewoon 1 px hoger te laten beginnen. Nu staan de achtergrond-afbeeldingen toch netjes op gelijke hoogte.

-moz-column-count: auto; -webkit-column-count: auto; column-count: auto;

Als je goed kijkt, zie je dat hier in feite drie keer vrijwel hetzelfde staat: column-count: auto;. Waarom dit drie keer wordt herhaald, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-.

Tot nu toe stond deze derde kolom onder de eerste twee kolommen. Omdat hij daardoor nogal breed werd, is de inhoud met behulp van column-count zelf ook weer in kolommen gesplitst. Nu wordt deze kolom naast de andere twee gezet, waardoor hij 'n stuk smaller wordt.

Bij deze eigenschap betekent auto dat er geen kolommen meer worden gemaakt. (Dat is alleen zo als je column-width niet hebt gebruikt, maar dat is hier het geval. Als je column-width wel gebruikt, bepaalt deze eigenschap het aantal kolommen.)

display: table-cell;

Dit zorgt ervoor dat de derde kolom niet onder, maar naast de eerste en tweede kolom komt te staan. De uitleg staat bij #een.

width: 23%;

Even breed maken als de tweede kolom.

Bij de eerste en tweede kolom is al een breedte opgegeven van 48% en 23% opgegeven. Samen met de padding is de breedte van eerste en tweede kolom77%. Je zou denken dat deze derde kolom dan automatisch de resterende 23% krijgt, maar daar denken sommige browsers heel anders over. Door de breedte zelf op te geven, wordt de kolom in alle browsers 23% breed.

border-left: black solid 1px;

Zwart randje aan de rechterkant.

#drie h3

Alle <h3>'s binnen het element met id="drie". Dat is er hier maar eentje: het kopje met 'Onderste rij of derde kolom'.

margin-bottom: 20px;

Wat ruimte tussen dit kopje en de tekst eronder.

Speciaal voor Internet Explorer 8

<!--[if IE 8]> <style> .no-touch body #wrapper {width: 100%; overflow-x: hidden;} .no-touch body #een, .no-touch body #twee, .no-touch body #drie {padding-right: 15px;} </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 8, maar je kunt het ook voor andere versies aangeven. Met ingang van versie 10 van Internet Explorer werken conditional comments niet meer.

In plaats van de style kun je ook 'n normale link naar 'n extern css-bestand aanbrengen:

<!--[if IE 8]> <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 8 in. De css voor Internet Explorer 8 komt dan apart in die stylesheet te staan, zodat het de andere browsers niet stoort.

Het is belangrijk dat de spaties in <!--[if IE 8]> 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.

.no-touch body #wrapper

Omdat de ondersteuning voor dit door sadisten ontworpen onding gelukkig een aflopende zaak is, ga ik maar heel beknopt op de css voor Internet Explorer 8 in. Ik heb er trouwens vaak ook geen idee van, waarom iets wel of niet werkt in dit vlooiencircus van fouten, afwijkingen en bugs. Ik begin al spontaan overal te krabben, als ik alleen maar kíjk naar wat deze browser met de code doet. (Ja, sorry, ik vind de Partij voor de Dieren een hele sympathieke partij, maar ik houd toch niet echt van vlooien.)

Je kunt vrijwel altijd uiteindelijk wel uitvinden, waarom iets wel of niet werkt, maar dat kost zeeën van tijd en, zoals gezegd: dit kreng loopt gelukkig naar z'n einde. Dus ik kan m'n tijd beter en vooral aangenamer gebruiken.

body in de selector wordt alleen gebruikt, om genoeg specificiteit ('gewicht') te geven aan deze selector. Bij te weinig specificiteit zal deze css eerdere css niet overrulen.

width: 100%; overflow-x: hidden;

div#wrapper even breed als de browser maken en alles wat er horizontaal niet in past gewoon helemaal niet laten zien. Dit voorkomt een volkomen overbodige horizontale scrollbalk onder de eerste twee kolommen. Vraag me niet uit welk duister krocht die scrollbalk omhoog kruipt: geen flauw idee waar 't ding vandaan komt.

.no-touch body #een, .no-touch body #twee, .no-touch body #drie {padding-right: 15px;}

body in de selector wordt alleen gebruikt, om genoeg specificiteit ('gewicht') te geven aan deze selector. Bij te weinig specificiteit zal deze css eerdere css niet overrulen.

Om het helemaal dolletjes gezellig te maken, plaatst Internet Explorer 8 de tekst in deze drie kolommen aan de rechterkant gewoon buiten de kolom. Een padding rechts voorkomt dat om een of andere wonderbaarlijke reden. Mogelijk had het bij volle maan over de rechterschouder werpen van wat zout ook geholpen, maar dat heb ik niet geprobeerd.

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

@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+);

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. In dit geval wordt gebruik gemaakt van een zogenaamde 'data-url'.

In deze op hogere wiskunde lijkende formule wordt een afbeelding weergegeven. Deze hoef je gelukkig niet zelf uit te vogelen. Als je op bijvoorbeeld colorzilla.com een gradiënt maakt, krijg je desgewenst gelijk met de normale linear-gradient 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.

In browservensters breder dan 810 px is deze achtergrond niet nodig. Daar zorgt de algemene css voor hetzelfde grijze menu aan de linkerkant als in alle andere browsers. Als deze browser op een touchscreen wordt gebruikt, werkt het hetzelfde als in andere mobiele browsers: bovenaan staat een horizontale rij met knoppen. In dat geval blijft de hier opgegeven achtergrond gewoon gebruikt worden.

Html5-elementen en Internet Explorer 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 8 onbekende html5-elementen <header>, <section>, <nav> en <article> gebruikt. De css voor deze elementen zou dus niet werken in Internet Explorer 8.

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 IE 8]> <script> document.createElement("header"); document.createElement("section"); document.createElement("nav"); document.createElement("article"); </script> <![endif]-->

Deze code geldt alleen voor Internet Explorer 8. Uitleg zie bij Speciaal voor Internet Explorer 8.

<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");

Door het toevoegen van zo'n regel voor een onbekend element, kan dat element nu gewoon worden gebruikt in Internet Explorer 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 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 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 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 8 (of ouder) 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 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 IE 8]> <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 of Opera. </div> </noscript> <![endif]-->

Los van dat deze browser bij <noscript> alleen css binnen 'n inline-style kan verwerken, moet ook nog 'n extra <div> worden gebruikt. Als je de style met <noscript style="..."> zou aangeven, wordt een deel van de inhoud van <noscript> altijd getoond in Internet Explorer 8, ook al staat JavaScript aan.

media queries en Internet Explorer 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 kan Internet Explorer 8 (en ouder) 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 kan ook deze browser gebruik maken van media queries.

Helemaal probleemloos werkt dit bepaald niet. Omdat de code van deze browser 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 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 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.

Hieruit blijkt weer dat je de roestbakken die Microsoft abusievelijk browser noemt, uiterst goed moet testen. En waarom deze scripts soms 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="101-files-dl/css3-mediaqueries.js"></script> <![endif]-->

Deze code geldt alleen voor Internet Explorer versie 8. Uitleg zie bij Speciaal voor Internet Explorer 8.

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 en menu vastgezet. Alleen de kolommen kunnen scrollen. Dit gebeurt door het menu fixed en div#wrapper 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, inclusief header en menu.

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 en menu gebruikt.

De meest simpele browsers zitten in de regel ook op de kleinste apparaten. Daarom wordt ook standaard uitgegaan van een heel klein browservenster. 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 8 (en ouder) 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 verouderd zijn.

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 8 html5-elementen herkent. Als je in plaats hiervan 'html5shiv v3.4 w/ printshiv' aanvinkt, kunnen deze elementen ook nog worden geprint door Internet Explorer 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 wílt 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

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:

Specifiek voor dit voorbeeld

Getest in

Laatst gecontroleerd op 4 april 2013.

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:

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. Op Windows 8 is zowel met een touchscreen als met een combinatie van toetsenbord en touchpad getest.

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.

In eerste instantie lijkt dit een ontmoedigend lange lijst met problemen. De meeste problemen zijn echter kleine afwijkingen van de lay-out, of kunnen simpel worden ontlopen. De lijst is voornamelijk 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 de oranje kolom verreweg het hoogste is, zullen dit soort ankers (vrijwel) alleen binnen de oranje kolom voorkomen.

Helaas werken bij deze constructie de genoemde toetsen niet in alle browsers binnen de pagina zelf: je gaat niet altijd 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; of overflow: auto; weghaalt bij div#wrapper, 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 twee eigenschappen is al voldoende. 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: behalve in Opera Mini gaat het hier alleen om links binnen div#wrapper. Links vanuit header, menu, en dergelijke naar div#wrapper werken volledig normaal. Ook links naar en van andere pagina's werken op de normale manier, inclusief de genoemde toetscombinaties.

Alleen in Opera Mini (Android en iOS) leiden álle links naar een anker binnen div#wrapper naar ogenschijnlijk volledig willekeurige plaatsen. Overigens werkt terug‑ of vooruitgaan binnen dezelfde pagina helemaal nooit in deze browser: je gaat altijd terug of vooruit naar de vorige of volgende pagina.

Ditzelfde probleem speelt in de roze en donkergroene kolom, maar daarin zullen normaal genomen geen ankers voorkomen.

In een toenemend aantal browsers werken deze toetsen inmiddels wel, zoals ze horen te werken: Safari (overal), Google Chrome (overal), Opera Mobile (Android 4.0.3), Android Browser (Android 2.3.6 en 4.0.3), Firefox (Windows 8 en Android 4.0.3). Je gaat terug naar de plaats waar je vandaan kwam, ook binnen de pagina. (Bij Safari, Google Chrome en Firefox was dit eerst niet zo, dus er is hoop dat ze ooit in alle browsers goed werken.)

Alle niet-mobiele browsers in vensters breder dan 810 px

Als het goed is, scrollen in deze browsers header en menu 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 div#wrapper, waarbinnen een aantal kolommen staat.

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 kolommen binnen een absoluut gepositioneerde div staan, werken deze toetsen niet zonder meer. Je moet eerst even binnen div#wrapper 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 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 8 en Touchscreens herkennen met behulp van modernizr staat hier meer over.
  • Internet Explorer 8 heeft geen ronde hoeken aan boven- en onderkant van het menu, omdat het border-radius niet kent. Ik heb enkele scripts en dergelijke geprobeerd die ronde hoeken mogelijk maken in deze browser, maar die werkten niet. Bovendien gaven ze soms problemen, zoals het verdwijnen van álle lay-out in het menu. Omdat de broncode van deze browser 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.

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

    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.

Internet Explorer 8 en 9

In de eerste (oranje) en derde (donkergroene) kolom staat in een breder browservenster de inhoud van deze kolommen zelf soms ook weer in kolommen. Omdat Internet Explorer 8 en 9 css-kolommen (column-...) niet kennen, staat in deze browsers alles altijd in één kolom. Internet Explorer 10 kent wel css-kolommen.

Als je kolommen echt belangrijk vindt, kun je op de pagina met links mogelijk een oplossing vinden onder CSS → Bugs en hacks → Dingen mogelijk maken specifiek voor Internet Explorer of onder CSS → Bugs en hacks → Niet-ondersteunde elementen, eigenschappen, enz. mogelijk maken.

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 browservensters smaller dan 600 px staat het menu onderaan de pagina. In de header verschijnt een link naar het menu. Omdat Opera Mini links niet onderstreept, is het iets minder duidelijk dat dit een link is. Opera Mini onderstreept links nooit, dit geldt dus ook voor eventuele andere links.

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 div#wrapper nu absoluut is gepositioneerd. Als je omlaag wilt scrollen, werkt dat niet. Tekst die onder het browservenster staat, wordt niet zichtbaar. De hele pagina scrolt weliswaar, maar er verschijnt geen nieuwe tekst. 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 verschijnt. Pas als de pagina na draaien wordt ververst, wordt de weergave voor mobiele browsers gebruikt.

  • De knoppen in het menu hebben geen ronde hoeken en de achtergrond is effen zwart. Om ronde hoeken en een gradiënt te krijgen, zou je gebruik moeten maken van afbeeldingen. Daar vind ik het niet belangrijk genoeg voor.
  • In browservensters smaller dan 600 px staat het menu onderaan de pagina. In de header verschijnt een link naar het menu. Omdat Opera Mini links niet onderstreept, is het iets minder duidelijk dat dit een link is. Opera Mini onderstreept links nooit, dit geldt dus ook voor eventuele andere links.

Opera Mobile op Android 2.3.6 en 4.0.3

In browservensters smaller dan 600 px staat het menu onderaan de pagina. In de header verschijnt een link naar het menu. Omdat Opera Mobile links niet onderstreept, is het iets minder duidelijk dat dit een link is. Opera Mobile onderstreept links nooit, dit geldt dus ook voor eventuele andere links.

Firefox (alle versies)

Firefox kent column-span niet. Hierdoor staan de kopregels in Firefox niet midden boven de tekst, maar links.

Afbeelding 20
Afbeelding 20: zoals Firefox het kopje laat zien.
Afbeelding 21
Afbeelding 21: zoals het wordt getoond in browsers die column-span kennen.

Zoomen

Op touchscreens werken in- en uitzoomen altijd hetzelfde, onderstaande geldt daarom alleen voor de desktop.

Firefox, Opera, Internet Explorer 8, 9 en 10 (bureaublad-versie) 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.

Internet Explorer 10 (startscherm-versie) in Windows 8: uitzoomen (verkleinen) werkt niet. Bij uitzoomen blijft de lay-out hetzelfde, alles wordt alleen breder en zo.

Safari en Google Chrome in OSX, Google Chrome in Windows en Linux: bij in- en uitzoomen blijft de lay-out hetzelfde, alleen de breedte en zo verandert.

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 of fixed 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 Mobile op Android 4.0.3 in landschapsstand (1024x768): omdat in portretstand de hele pagina scrolt, speelt in portretstand onderstaande probleem niet.

Bij opening van de pagina staat alles goed. Ook scrollen levert geen problemen op: de hele inhoud van de pagina is zichtbaar. Bij het menu gaat het echter mis. Als het menu fixed is gepositioneerd, zou het in principe niet moeten scrollen, maar altijd zichtbaar moeten zijn. Soms is dat zo, maar soms verdwijnt het menu gewoon helemaal, of verdwijnt een aantal knoppen.

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, menu links en daarnaast twee kolommen. Maar bij scrollen blijkt álles mee te scrollen, alsof de pagina 'n afbeelding is. Bovendien verschijnt er geen nieuwe tekst: je ziet alleen, wat bij opening al zichtbaar was.

Safari en Google Chrome op de iPad, Google Chrome, Android browser, Firefox en Opera Mobiel op Android 4.0.3, allemaal in landschapsstand (1024x768): bij inzoomen (vergroten) verdwijnen header en menu buiten het venster. Als door scrollen de header of menu weer terugkomen op het venster, blijven die soms weer staan, soms niet. Soms wordt het menu over de tekst in de eerste (oranje) kolom gezet. Met scrollen is alles wel zichtbaar te krijgen, maar beter is om gewoon niet fixed of absoluut te positioneren.

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 of het menu. Links naar andere pagina's werken wel normaal. Zonder position: absolute; bij div#wrapper werken de ankers wel, maar dan is de lay-out niet meer goed. Dit is een ernstig probleem, dat het gebruik van ankers feitelijk onmogelijk maakt. Door geen absolute of fixed positie te gebruiken in deze browser, wordt dit probleem voorkomen.

Wijzigingen

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

:

Nieuw opgenomen.