Skip links en inhoudsopgave

Laatst aangepast: .

Scrollbare en schaalbare tabel met vaste header

Korte omschrijving

Bij scrollen van de tabel blijven de kopjes boven de kolommen (de <th>'s) op dezelfde plaats staan.

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 Quanta Plus, 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

Als een tabel wat lang is, past hij niet meer in z'n geheel in het venster van de browser. Het kan dan handig zijn om de kopjes boven de kolommen op hun plaats te laten staan, terwijl de tabel zelf gescrold kan worden.

Dit is een vraag die met enige regelmaat terugkomt op forums, maar tot mijn verbazing kon ik geen enkele goede constructie met alleen html en css vinden. De constructies die ik vond, werken alleen met (sterk) verouderde browsers, en dan nog vaak heel gebrekkig. Er zijn wel mogelijkheden met JavaScript te vinden, maar het kan ook prima met alleen css en html.

De hele constructie wordt in een div gezet, die relatief wordt gepositioneerd. De vaste kopjes worden gepositioneerd ten opzichte van deze div. De div krijgt een bepaalde hoogte. Hierdoor past de tabel er niet volledig in: hij is te hoog.

Binnen deze div komt een tweede div te staan, die even hoog wordt als de buitenste div en overflow op auto heeft staan. Binnen deze div komt de tabel te staan. Omdat de tabel te hoog is voor deze div en overflow op auto staat, krijgt de div een verticale scrollbalk.

Boven de tabel staan binnen een <thead> vier kopjes <th>. Normaal genomen zou ik de breedte hiervan in procenten of em opgeven, maar dat werkt hier niet. Ik moet px gebruiken voor de breedte (op het waarom daarvan kom ik verderop nog terug). Nadeel is dat de breedte van de kolommen nu niet mee verandert met een andere lettergrootte, maar dat is niet echt 'n heel groot probleem.

Binnen elke <th> staat een span, en binnen die span staat de tekst van het kopje boven de bijbehorende kolom. De spans worden absoluut gepositioneerd ten opzichte van de buitenste div. Hierdoor blijft de span, en dus de tekst binnen de <th>, stilstaan bij scrollen van de tabel. Tegelijkertijd is de tabel nog steeds een volstrekt normale standaardtabel, alles wordt geregeld via css.

De spans worden ook horizontaal gepositioneerd, zodat ze op precies de juiste afstand van elkaar staan. De tweede, derde en vierde span krijgen links een border, die precies boven de verticale border tussen de cellen komt te staan.

De meest rechtse span wordt links én rechts gepositioneerd en mag zelf z'n breedte bepalen. Hierdoor vult deze bij in- of uitzoomen altijd de resterende ruimte boven de tabel.

Ongelijke verticale streepjes

In de praktijk was het wel iets lastiger dan hier staat. Door het absoluut positioneren van de spans bleek het weergeven van de breedte van de <th>'s in procenten niet meer te werken. Om wat voor reden dan ook gaven Opera, Safari/Google Chrome en Firefox/Internet Explorer verschillende breedtes van de <th> en de <td>'s in de tabel zelf. Normaal genomen krijgen de <td>'s automatisch de bij de <th>'s opgegeven breedtes. Op bovenstaande afbeelding is de afwijking in Firefox en Internet Explorer te zien. Let op de verticale streepjes in de grijze en in de witte balk, die zouden boven elkaar moeten staan.

In principe is die afwijking prima te corrigeren. Maar als ik de afwijking voor Firefox/Internet Explorer had gecorrigeerd, zag de afwijking van Safari/Google Chrome er nog erger uit, en van Opera raakte je acuut aan de alcohol. En vice versa.

Door de <th> een breedte in px te geven, kon dit worden opgelost. De <th> en de <td> worden dan wel even breed, precies zoals het hoort te werken. De in de <th>'s zittende spans krijgen zelf ook een breedte, zodat de kopjes gecentreerd kunnen worden en zo.

Deze afwijkingen bij het gebruik van procenten doen zich alleen maar voor, als de spans absoluut worden gepositioneerd.

Waardoor deze afwijkingen tussen de diverse browsers worden veroorzaakt, weet ik niet. Het gebruik van border-collapse levert dezelfde soort verschillen op, dus dit is ook onbruikbaar. Waardoor het gebruik van kadertjes 'n stuk ingewikkelder wordt, omdat je nu handmatig dubbele kadertjes tussen de cellen moet voorkomen.

Je kunt ook bij border-collapse de afwijkingen corrigeren, maar niet voor álle browsers: zodra je de ene corrigeert, wordt de afwijking in 'n andere juist groter.

Alleen - grote schrik - Internet Explorer 7 blijkt goed uit de voeten te kunnen met border-collapse. Deze browser zet, ook bij gebruik van border-collapse, alles op de juiste plaats neer. Wel moet je ook in deze browser px en geen procenten gebruiken voor de breedte.

(Voor de zekerheid heb ik even een drugtest laten doen, want als alleen Internet Explorer 7 iets goed blijkt te doen... En wie weet wat ze in het café allemaal in je drankje stoppen. Maar het is echt zo: Internet Explorer 7 doet als enige iets goed!)

Ook table-layout: fixed; kan niet worden gebruikt. Dit zou ervoor moeten zorgen, dat de tabel al wordt weergegeven, als de eerste regel van de tabel is bekeken. Dat is de regel met de kopjes. Om wat voor reden dan ook levert dit in Safari en Google Chrome een andere breedte bij de kopjes op dan in de tabel zelf.

De bovenste grijze balk en de roze balk boven de tabel hebben helemaal niets met de tabel te maken. Het zijn een gewone kop en paragraaf, die alleen tegen de tabel aan zijn geparkeerd.

Je kunt je afvragen waarom ik dan ook niet op dezelfde manier de kopjes boven de kolommen heb neergezet. Dat zou kunnen. Maar het gebruik van <th> boven een kolom maakt een tabel toegankelijker voor spraakbrowsers en dergelijke. En ook een zoekmachine weet dan beter waar de tabel over gaat. Als ik gewone normale tekst boven 'n tabel zet, is die koppeling aan de tabel veel minder duidelijk.

Voor de rest is de tabel alleen nog wat opgeleukt met randjes, tekst centreren, dat soort dingen, maar dat is verder allemaal niet zo bijzonder.

De voorvoegsels -moz-, -ms-, -o- en -webkit-

Voordat een nieuwe css-eigenschap wordt ingevoerd, is er in de regel een experimentele fase. Browsers passen het dan al toe, maar met een aangepaste naam. Tijdens deze fase kunnen problemen worden opgelost en worden veldslagen uitgevochten over hoe de standaard precies moet worden toegepast.

Als iedereen het overal over eens is en alle problemen zijn opgelost, wordt de officiële naam uit de standaard gebruikt.

De belangrijkste browsers hebben elk een eigen voorvoegsel:

Firefox: -moz-, naar de maker: Mozilla.

Google Chrome en Safari: -webkit-, naar de gebruikte weergave-machine: webkit.

Opera: -o-, je mag zelf bedenken waar de letter o vandaan komt (hint: Opera wordt door Opera Software gemaakt).

Internet Explorer: -ms-, naar de maker: Microsoft. Traditiegetrouw heeft Microsoft zich hier jarenlang niets van aangetrokken, pas bij Internet Explorer 8 is Microsoft -ms- gaan gebruiken. Omdat het ook zonder -ms- werkt en de speciale css voor Internet Explorer toch in een aparte stylesheet staat, gebruik ik -ms- nooit voor oudere versies dan Internet Explorer 9.

Hoewel deze voorvoegsels door w3c zelf genoemd worden, rekent de validator ze vreemd genoeg toch fout. Althans: dat denken veel mensen, waaronder ikzelf tot voor kort. De validator blijkt een instelling te hebben, waarmee je deze foutmelding uit kunt zetten.

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 transform erbij. Deze wordt als laatste opgegeven. Bijvoorbeeld Firefox herkent -moz-transform. Zodra Firefox transform gaat herkennen, zal dit -moz-transform overrulen, omdat het er later in staat. Dat ze er beide in staan, is dus geen enkel probleem.

In dit voorbeeld wordt box-sizing gebruikt. In Internet Explorer 8 en 9 werkt dit al zonder voorvoegsel. Internet Explorer 7 kent het niet.

Firefox herkent -moz-box-sizing. Safari en Google Chrome herkennen -webkit-box-sizing. Opera herkent -o-box-sizing.

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 box-sizing erbij. Deze wordt als laatste opgegeven. Bijvoorbeeld Firefox herkent -moz-box-sizing. Zodra Firefox box-sizing gaat herkennen, zal dit -moz-box-sizing overrulen, omdat het er later in staat. Dat ze er beide in staan, is dus geen enkel probleem.

Op dit moment moet je nog het volgende schrijven:

{-moz-box-sizing: ...; -o-box-sizing: ...; -webkit-box-sizing: ...; box-sizing: ...;}

In de toekomst kun je volstaan met:

{box-sizing: ...;}

Dit zal nog wel 'n behoorlijke tijd duren. Firefox, Safari, Opera en Google Chrome hebben een goed update-mechanisme. Maar Internet Explorer blijft altijd jaren en jaren in omloop, en tijdens die omloop worden alleen bugs gerepareerd, er worden nooit veranderingen aangebracht. Dus pas als Internet Explorer 9 is uitgestorven is de laatste schrijfwijze eindelijk mogelijk.

Beschrijving van code en css

De code die te maken heeft met de basis van dit voorbeeld is rood 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">

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

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

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

Het hier gebruikte doctype is dat van html5. Dit kan al veilig worden gebruikt.

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

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

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 wat in dit voorbeeld tussen <style> en </style> staat (zonder deze begin- en eindregel).

De bovenste regel is voor de algemene stylesheet, geldig voor alle browsers. Dit is gewoon 'n link die naar 'n bestand elders verwijst, waar de css in staat. Op de plaats van "../../css/naam-van-stylesheet.css" moet je pad naar en naam van jouw stylesheet invullen.

Het eigenaardige stukje code daaronder heet een 'conditional comment' en wordt door alle browsers gezien als commentaar, omdat het tussen <!-- en --> staat. Maar Internet Explorer herkent het, door de extra toevoegingen, als speciaal voor Internet Explorer bedoeld en zal het dus uitvoeren. Het is veiliger dan een zogenaamde 'hack', waarbij vaak gebruik wordt gemaakt van 'n fout (bug) in de browser. Dit is opzettelijk aangebracht door Microsoft en zal dus blijven bestaan, terwijl 'n bug gerepareerd kan worden. Op deze manier kun je 'n stylesheet alleen voor Internet Explorer opnemen.

Dit stukje geldt voor alle versies van Internet Explorer, maar je kunt het ook per versie aangeven.

De link verwijst naar een aparte stylesheet voor Internet Explorer, waarin je css speciaal voor die browser zet. Op de plaats van "../../css/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>

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

margin: 0; padding: 0;

Slim om te doen, is soms wat afwijkend in verschillende browsers.

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

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

font-size: 110%;

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

Ik gebruik hier % als eenheid, en voor alle andere lettergroottes gebruik ik em. Dat komt door Internet Explorer. Als ik als maateenheid iets als px neem, kunnen gebruikers van Internet Explorer de lettergrootte niet veranderen.

Maar als ik overal em neem als maateenheid, wat dan voor de hand zou liggen, kom ik in de problemen met versies van Internet Explorer ouder dan versie 8. De stappen van de verkleining of vergroting zijn in die browsers zo groot, dat 't gelijk onleesbaar klein of absurd groot is.

Als je nou echter bij body geen em gebruikt (font-size: 1.1em; zou hetzelfde moeten zijn als font-size: 110%;), dan is de lettergrootte in Internet Explorer te veranderen, en in oudere versies dan versie 8 zijn de tussenstappen teruggebracht tot normale grootte.

Dit werkt ook als je als lettergrootte 100% invult. Dat heeft geen enkele invloed op de lettergrootte, behalve dus dat de tussenstappen in oudere versies nu normaal werken.

In Internet Explorer 8 is deze bug eindelijk gerepareerd. Aangezien we waarschijnlijk nog vele jaren met oudere versies dan Internet Explorer 8 zitten opgescheept, zal deze truc ook nog jaren moeten worden toegepast.

color: black;

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

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. 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.

background: #ff9;

Achtergrondkleurtje.

h1

De belangrijkste kop op de pagina: de tekst in de bovenste grijze balk. Hoewel deze deel lijkt uit te maken van de tabel, staat hij er in werkelijkheid volkomen los van.

Deze <h1> is niet direct aan het uiterlijk te herkennen. Zo is de letter bijvoorbeeld veel kleiner dan 'n <h1> van zichzelf automatisch heeft. Vaak wordt, om een andere uiterlijk van een <h1> te krijgen, een andere <h> gebruikt. Dat is geen goed idee. Spraakbrowsers en dergelijke weten door het gebruik van een <h1> wat de belangrijkste kop op de pagina is. En hetzelfde geldt voor een zoekmachine.

Je gebruikt dus gewoon de juiste <h> om het gewicht van de kop aan te geven, en het uiterlijk pas je desgewenst met behulp van css aan.

(In html5 kun je meerdere keren 'n <h1> gebruiken, maar de discussie daarover is nog lang niet afgerond. Voorlopig ben ik in ieder geval nog lang niet van plan die mogelijkheid te gaan gebruiken.)

width: 770px;

Breedte. Alles op deze pagina dat met de tabel te maken heeft, heeft deze zelfde breedte.

max-width: 99%;

Maximumbreedte. Een breedte in procenten geldt altijd ten opzichte van de ouder van het element. In dit geval is er geen ouder, en dan geldt de 99% ten opzichte van het venster van de browser. Oftewel: de kop mag nooit breder zijn dan het venster van de browser.

Als de pagina sterk wordt vergroot, of in een heel smal browservenster, blijft de kop hierdoor altijd zichtbaar, zonder dat een horizontale scrollbalk verschijnt. In een breder venster of bij een normale grootte heeft dit verder geen enkel effect.

Er is 99% genomen en geen 100%, omdat bij de breedte nog een border links en rechts van 1 px breed komt. Als je 100% neemt, zou de maximale breedte daardoor 100% + 2 px worden, en dat zou toch nog 'n horizontale scrollbalk opleveren.

Alles op deze pagina dat met de tabel te maken heeft, heeft deze zelfde maximumbreedte.

margin: 10px auto 0;

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

Boven een marge van 10 px voor wat afstand tussen de bovenkant van het venster van de browser en de kop. Onderaan geen marge.

Links en rechts auto, dat betekent hier: evenveel. Oftewel: de kop staat altijd horizontaal gecentreerd, ongeacht de breedte van het venster van de browser. Deze manier van horizontaal centreren van een blok-element werkt alleen maar, als het blok-element een breedte heeft.

Omdat alles op deze pagina dat met de tabel te maken heeft op dezelfde manier wordt gecentreerd, staat alles netjes uitgelijnd boven elkaar.

border: black solid 1px;

Randje rondom de kop.

color: black;

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

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. 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.

Ik heb dit ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.

background: #ddd;

Grijze achtergrondkleur.

text-align: center;

Tekst horizontaal centreren. Omdat de kop zelf ook al horizontaal is gecentreerd, staat de tekst hierdoor horizontaal gecentreerd in het venster van de browser.

font-size: 1.5em;

Van zichzelf heeft een <h1> een behoorlijk grote letter. Die maak ik hier iets kleiner. Als eenheid gebruik ik em, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen.

font-weight: normal;

Van zichzelf heeft een <h> vette tekst. Dat is hier 'n beetje teveel van het goede.

#voorbeeld

Het element met id="voorbeeld". Dat is hier de paragraaf met tekst op roze achtergrond boven de tabel. Deze paragraaf staat helemaal los van de eigenlijke tabel, hij is er alleen maar tegenaan gezet.

-moz-box-sizing: border-box; -o-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;

Als je goed kijkt, zie je dat hier eigenlijk vier keer hetzelfde staat in 'n verschillende vorm: box-sizing: border-box;. Waarom dat zo is, staat bij De voorvoegsels -moz-, -ms-, -o- en -webkit-.

Als iemand je ooit vertelt dat vroeger alles beter was, dan is die iemand beslist geen sitebouwer. Tot niet zo lang geleden waren er twee manieren om de breedte van een element te berekenen. De standaardmanier was om border, padding en margin bij de breedte op te tellen. Een breedte van 100 px met een border, padding en margin van elk 10 px leverde dus een totale breedte van 10 + 10 + 10 + 100 + 10 + 10 + 10 = 160 px.

Microsoft had, in een poging Internet volledig in handen te krijgen en iedereen te dwingen Internet Explorer en dus Windows te gebruiken, een eigen manier om de breedte te berekenen. Border, padding en marge kwamen binnen de breedte te staan. Dezelfde constructie als hierboven 160 px oplevert, leverde bij Internet Explorer een breedte van 100 px op. En daarbinnen kwamen de border, padding en margin te staan. De breedte voor tekst en dergelijke was dus maar 60 px.

(Er waren nog veel meer verschillen tussen Internet Explorer en de rest, maar dit was een van de belangrijkste. Door dit soort geëikel was je vaak feitelijk verplicht om twee keer of zelfs nog vaker dezelfde site te maken, aangepast voor elke (versie van) een browser. Overigens waren andere browsermakers ook niet vies van smerige trucs, maar Microsoft was met stip de smerigste.)

Voornamelijk dankzij het succes van Firefox werd Microsoft gedwongen zich ook aan de standaarden te gaan houden. Normaal genomen berekenen alle browsers tegenwoordig de breedte op dezelfde manier: margin, padding en border worden bij de breedte opgeteld.

css3 heeft een nieuwe eigenschap: box-sizing. Deze eigenschap gebruikt de oude, foutieve manier om de breedte te berekenen. Maar in dit geval kun je er bewust voor kiezen, het is niet de browser die opzettelijk van de standaard afwijkt. En soms kan de oude manier van berekenen handig zijn, zoals hier.

div#content, de div waar de tabel in staat, en de <h1> hebben dezelfde breedte: een breedte van 770 px en links en rechts een border van 1 px, dus in totaal 772 px. Tussen deze twee in staat #voorbeeld. Deze kan ik dezelfde breedte geven, alleen moet ik rekening houden met een padding van 3 px links en rechts: 1 + 3 + 764 + 3 + 1 maakt samen ook 772 px. Bij een normale grootte gaat dit prima: de kop, deze paragraaf en de tabel zijn allemaal even breed.

Als ik echter ga inzoomen (vergroten), gaat de maximumbreedte een rol spelen. Die is bij de kop en de tabel 99%. Kop en tabel worden dus niet breder dan 99%, waar nog 'n border links en rechts bijkomt van 1 px (vandaar die 99% en geen 100%: anders krijg je 'n horizontale scrollbalk omdat het net iets te breed wordt.)

#voorbeeld heeft een breedte van 764 px. Als ik dat de maximumbreedte van 99% geef, komen daar echter nog in totaal 8 px border en padding bij. Het totaal wordt nu 99% + 8 px: veel breder dan kop en tabel. Als ik het bijvoorbeeld maximaal 98% maak, krijg ik het nooit in alle browsers precies goed: de roze balk wordt altijd iets breder of smaller dan de rest, en soms zelfs 'n fors stuk. Bovendien zit er ook nog 'ns verschil tussen de verschillende browsers.

Daarom kies ik hier voor de 'foute' manier van het berekenen van de breedte. Ik maak #voorbeeld 772 px breed en plaats de padding en border binnen die breedte. Nu kan ik gewoon een maximumbreedte van 772 px opgeven. Die levert vrijwel hetzelfde resultaat als de maximumbreedte van 770 bij de kop en de tabel, want daar komt nog 'n border van 2 x 1 px bij.

width: 772px;

Breedte.

max-width: 99.3%;

Maximumbreedte. Een breedte in procenten geldt altijd ten opzichte van de ouder van het element. In dit geval is er geen ouder, en dan geldt de 99,3% ten opzichte van het venster van de browser. Oftewel: deze paragraaf mag nooit breder zijn dan het venster van de browser.

Als de pagina sterk wordt vergroot, of in een heel smal browservenster, blijft de paragraaf, en dus de erin zittende tekst, altijd zichtbaar zonder dat een horizontale scrollbalk verschijnt. In een breder venster of bij een normale grootte heeft dit verder geen enkel effect.

Het vreemde getal 99,3 komt door de overige onderdelen. Deze zijn 99% breed, waar nog links en rechts 'n border van 1 px bij komt. Als ik ze 100% breed zou maken, zou de totale breedte door die borders net te veel worden bij vergroten, en zou je 'n overbodige horizontale scrollbalk krijgen.

De andere onderdelen worden dus 99% plus 2 px. Maar bij deze paragraaf is box-sizing gebruikt, en dan komt de border binnen de paragraaf te liggen. Dus bij deze paragraaf missen de 2 extra px. Door de maximumbreedte 0,3% groter te nemen, wordt de uiteindelijke maximumbreedte ongeveer even groot als die van de andere onderdelen.

margin: 0 auto;

Omdat voor onder en links geen waarde is opgegeven, krijgen deze automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 auto 0 auto in de volgorde boven - rechts - onder - links.

Boven en onder geen marge.

Links en rechts auto, dat betekent hier: evenveel. Oftewel: de kop staat altijd horizontaal gecentreerd, ongeacht de breedte van het venster van de browser. Deze manier van horizontaal centreren van een blok-element werkt alleen maar, als het blok-element een breedte heeft.

Omdat alles op deze pagina dat met de tabel te maken heeft op dezelfde manier wordt gecentreerd, staat alles netjes uitgelijnd boven elkaar.

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

border: black solid;

Zwart randje. De breedte geef ik gelijk hieronder op.

border-width: 0 1px;

De kleur en vorm van de border heb ik gelijk hierboven al opgegeven.

Omdat voor onder en links geen waarde is opgegeven, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 1px 0 1px in de volgorde boven - rechts - onder - links. Boven en onder geen border, links en rechts een border van 1 px breed.

Boven en onder is geen border nodig, omdat de boven- en onderbuur al 'n border aan onder- en bovenkant hebben.

padding: 3px;

Aan alle kanten een kleine afstand tussen de rand van de paragraaf en de tekst erin.

color: black;

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

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. 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.

Ik heb dit ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.

background: #fdd;

Roze achtergrond.

text-align: center;

Tekst horizontaal centreren.

code

Alle <code>'s. Dat is er hier maar eentje: &#x3a56; in het roze kopje.

font-size: 1.2em;

Iets grotere letter. Elke browser geeft tekst binnen <code> op een afwijkende manier weer. Maar sommige browsers maken de tekst wel heel erg klein. Daarom maak ik hem iets groter, dan is het eindresultaat (ongeveer) tekst van normale grootte.

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

(Je kunt een eigen font opgeven om te gebruiken binnen 'n tag als <code>, maar omdat het hier maar om één klein stukje gaat, laat ik het simpelweg aan de browser over. Mag die ook 'ns doen, waar hij zelf zin in heeft.)

#content

Het element met id="content". Dit is een div, waarbinnen nog 'n andere div staat, en daarbinnen staat weer de tabel. De combinatie van twee divs zorgt ervoor dat de tabel gescrold kan worden, terwijl de kopjes boven de kolommen stil blijven staan.

position: relative;

Om kinderen te kunnen positioneren ten opzichte van 'n ouder, moet die ouder een relatieve, fixed of absolute positie hebben. Omdat ik hier verder niets bij opgeef, heeft dit geen enkele invloed op #content zelf. Het maakt alleen positioneren ten opzichte van deze div mogelijk.

width: 770px;

Breedte. Alles op deze pagina dat met de tabel te maken heeft, heeft deze zelfde breedte.

max-width: 99%;

Maximumbreedte. Een breedte in procenten geldt altijd ten opzichte van de ouder van het element. In dit geval is er geen ouder, en dan geldt de 99% ten opzichte van het venster van de browser. Oftewel: de div, en dus ook de erin zittende tabel, mag nooit breder zijn dan het venster van de browser.

Als de pagina sterk wordt vergroot, of in een heel smal browservenster, blijft de tabel hierdoor altijd zichtbaar, zonder dat een horizontale scrollbalk verschijnt. In een breder venster of bij een normale grootte heeft dit verder geen enkel effect.

Er is 99% genomen en geen 100%, omdat bij de breedte nog een border links en rechts van 1 px breed komt. Als je 100% neemt, zou de maximale breedte daardoor 100% + 2 px worden, en dat zou toch nog 'n horizontale scrollbalk opleveren.

Alles op deze pagina dat met de tabel te maken heeft, heeft deze zelfde maximumbreedte.

height: 400px;

Hoogte. Door de hoogte van deze div te beperken, kan ik later een scrollbalk laten verschijnen, waardoor de tabel gescrold kan worden. Deze div zelf scrolt niet mee, en omdat de spans in de <th>'s boven de tabel absoluut gepositioneerd zijn ten opzichte van deze div, scrollen die ook niet mee.

margin: 0 auto;

Omdat voor onder en links geen waarden zijn ingevuld, krijgen deze automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 0 auto 0 auto in de volgorde boven - rechts - onder - links. Boven en onder geen marge. Links en rechts auto, wat hier betekent: evenveel. Oftewel: deze div, en dus de inhoud ervan ook, staat altijd horizontaal gecentreerd, ongeacht de breedte van het venster van de browser.

Omdat alles op deze pagina dat met de tabel te maken heeft op dezelfde manier wordt gecentreerd, staat alles netjes uitgelijnd boven elkaar.

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

border: black solid 1px; Border bij juiste element plaatsen

Ik kan beter 'n border aan deze div geven dan aan de tabel. De hele tabel staat binnen deze div, maar ook de scrollbalk. Als ik dus een border aan deze div geef, komt ook de scrollbalk binnen het randje te staan, zoals op de linkerafbeelding is te zien.

Als ik de border aan de tabel geef, is het resultaat op de rechterafbeelding te zien: de scrollbalk staat buiten de border.

Bovendien krijgt de header van de tabel, de grijze balk er gelijk boven, ook een border als ik de div en niet de tabel een border geef. De header bestaat uit vier <th>'s. Binnen elke <th> zit een absoluut gepositioneerde span met de tekst van de kopjes, verder niets. Omdat de spans absoluut gepositioneerd zijn, hebben de <th>'s geen hoogte en kunnen dus ook geen border krijgen, zoals te zien is op de rechterafbeelding.

Maar de hele handel staat wel binnen deze div, dus als ik gewoon de border aan de div geef, heeft ook de header een border. (In werkelijkheid heeft de header dus helemaal geen border, alleen deze div, maar voor het oog maakt dat helemaal niets uit.)

padding-top: 1.5em; Zonder padding aan de bovenkant

De roze balk boven de tabel heeft helemaal niets met de tabel te maken, hij is alleen tegen de tabel aan gezet. Als je in 'n volle tram tegen iemand aan staat, ben je ook niet gelijk getrouwd, zoiets.

Het bovenste deel van de tabel bestaat uit vier <th>'s, waarbinnen de spans met de tekst van de kopjes zitten. Die spans zijn met behulp van een absolute positie boven de tabel geplaatst. Op de afbeelding vormen ze de grijze balk.

Omdat de spans absoluut zijn gepositioneerd, hebben de vier <th>'s geen hoogte. Dat betekent dat de volledige bovenste rij van de tabel geen hoogte heeft, want daarin staan alleen de <th>'s. Daardoor schuift de tweede rij van de tabel, dat is het eerste blauwe kopje met 'Alfanumerieke symbolen', naar boven. En komt ónder de absoluut gepositioneerde spans met de kopjes van de kolommen te staan, zoals op de afbeelding is te zien.

Daarom geef ik met behulp van deze padding wat afstand tussen de bovenkant van de div en het begin van de tabel. Die afstand vervangt als het ware de in elkaar gefloepte <th>'s zonder hoogte.

1,5 em blijkt de juiste hoogte te zijn. Door als eenheid em te nemen, verandert de padding mee met een andere lettergrootte: bij een grotere letter schuift de tabel iets omlaag. Anders zouden de kopjes bij een grotere letter boven de tabel komen te staan, en bij een kleinere letter zou er een kier ontstaan tussen tabel en kopjes.

#wrapper-tabel

Het element met id="wrapper-tabel". Dit is een extra div, die tussen de tabel en de buitenste div#content staat. Het gebruik van deze extra div maakt het mogelijk de tabel te scrollen, terwijl de kopjes boven de kolommen stil blijven staan.

Op de afbeelding hiernaast heeft div#content een blauwe lijn. div#wrapper-tabel heeft een rode lijn. Omdat div#content aan de bovenkant een padding heeft, staat div#wrapper-tabel aan de bovenkant op enige afstand van div#content.

Binnen div#wrapper-tabel staat de tabel. In de grijze balk staan de kopjes boven de kolommen. Elk kopje staat in een span. Deze spans staan absoluut gepositioneerd ten opzichte van div#content.

Als ik div#wrapper-tabel weglaat, scrollen de kopjes boven de kolommen gewoon mee met de tabel. Maar als ik deze div tussen div#content en de tabel zet, blijven de kopjes op hun plaats staan, terwijl de tabel gescrold kan worden.

De <th>'s waar de spans in staan, scrollen vrolijk mee met de tabel, alleen de spans (en dus de daarin zittende tekst) blijven staan. Dat is te zien aan de borders aan de onderkant van <th>'s en spans.

De structuur van de tabel blijft volledig intact, het hele mechanisme wordt volledig aangestuurd door css. Daardoor ontstaan geen extra problemen voor spraakbrowsers, zoekmachines, enz. Dit zou mogelijk wel het geval zijn, als de kopjes net zoals de roze balk volledig los van de tabel erboven waren gezet, als aparte paragraaf of zo.

(Ik moet eerlijk zeggen dat ik niet begrijp, hoe dit werkt. Ik heb er ook nergens iets over kunnen vinden. Niet in de specificatie, geen vergelijkbare constructies op internet, niets. Je zou zeggen dat de kopjes óf altijd, óf nooit met de tabel mee horen te scrollen, maar dat is dus niet zo. Maar het werkt in alle geteste browsers op exact dezelfde manier en het valideert, dus kennelijk is het volledig in orde.)

height: 100%;

Een hoogte in procenten wordt altijd genomen ten opzichte van de ouder. In dit geval is dat div#content, die zelf 400 px hoog is.

overflow: auto;

De tabel is veel te hoog voor de div. Door de waarde van overflow op auto te zetten verschijnt een scrollbalk, waarmee de tabel naar boven kan worden gescrold en dus zichtbaar wordt.

De tabel wordt even breed als de div, dus een horizontale scrollbalk is niet nodig. (Alleen in Internet Explorer 7 verschijnt die, maar dat is een apart geval waarvoor later aparte css komt.)

table

Alle tabellen. Dat is er hier maar eentje.

width: 100%;

Zonder deze breedte ontstaat er bij in- en uitzoomen in bepaalde standen een kleine kier tussen de verticale scrollbalk rechts van de tabel en de tabel.

border-spacing: 0;

Alle cellen enz. hebben een border. Normaal genomen zou ik border-collapse: collapse; gebruiken om de borders samen te laten vallen, zodat je geen dubbele lijntjes krijgt. In dit geval werkt dat niet, omdat Firefox/Opera/Internet Explorer andere resultaten geven dan Safari/Google Chrome, waardoor de verticale lijntjes in de header niet meer precies boven de verticale lijntjes tussen de cellen staan. Je kunt dat wel corrigeren voor de ene groep browsers, maar dan is de andere groep weer niet goed.

Hierdoor moet ik overal zelf de borders opgeven, en ook zelf zorgen dat er geen dubbele borders en marges en zo verschijnen. Dit is één van de eigenschappen die daarbij helpt.

color: black;

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

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. 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.

Ik heb dit ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.

background: white;

Witte achtergrond.

text-align: center;

Vrijwel alle tekst in de tabel wil ik gecentreerd hebben. Op de plaatsen waar dat toch niet moet, corrigeer ik dat later met wat extra css voor die plaatsen.

th

De kopjes van de tabel. Dat zijn er vier, eentje boven elke kolom.

Een aantal instellingen is voor alle <th>'s hetzelfde, die geef ik hier op.

width: 90px;

Breedte. De andere kolommen krijgen andere breedtes, dat geef ik hieronder op.

Ik zou liever procenten of em gebruiken, omdat de breedte van de kolommen dan mee verandert met de breedte van de tabel.

Dit kan echter niet, omdat de breedte van de <th>'s anders blijkt te worden dan de breedte van de cellen in de tabel. Hierdoor komen de verticale streepjes tussen de koppen niet netjes boven de verticale strepen tussen de cellen te staan, en ook staan de kopjes niet goed in het midden van de kolom. Wat hiervan de reden is, is mij niet helemaal duidelijk. Ik heb er ook niets over kunnen vinden. Het doet zich alleen voor als de spans in de <th>'s absoluut gepositioneerd worden, zoals hier het geval is.

Deze afwijking zou op zich nog wel te corrigeren zijn, maar helaas geven Opera, Safari/Google Chrome en Firefox/Internet Explorer drie verschillende afwijkingen. Als je de ene corrigeert, wordt de afwijking in de andere groter.

Als ik px gebruik voor de breedte, gaat het wel in alle browsers goed.

In theorie kan het gebruik van px problemen opleveren als je de letters gaat vergroten, omdat de breedte van de kolommen niet mee verandert. Maar pas bij vergrotingen ruim boven de 200% komt de tekst buiten de kolommen te staan, dus dat probleem bestaan alleen voor laagwaterspijkerzoekers.

border-bottom: black solid 1px;

Zwart randje aan de onderkant van de <th>'s.

De afdelingskopjes in de tabel hebben aan de bovenkant een zwarte border van 5 px hoog. De cellen in de tabel hebben aan de onderkant een zwarte border van 1 px. Dat maakt samen 6 px.

Het bovenste kopje in de tabel, dat met 'Alfanumerieke symbolen', heeft geen cel boven zich, en dus ook niet de border aan de onderkant daarvan. Hierdoor is de border aan de bovenkant van het bovenste kopje maar 5 px hoog: 1 px te weinig. Dit randje van 1 px hoog aan de onderkant van de <th>'s vult dat gemis aan.

th + th

Elke <th> die gelijk op een andere <th> volgt. Dit is elke tweede en volgende <th>, maar omdat voor de derde en vierde <th> later andere css volgt, geldt de css hier feitelijk alleen voor de tweede <th>.

Hiervoor gelden ook de bij th opgegeven instellingen.

width: 80px;

Breedte. Waarom ik px gebruik staat bij th.

th + th + th

Elke <th> die gelijk op een andere <th> volgt, die ook weer op een andere <th> volgt. Dit is elke derde en volgende <th>, maar omdat voor de vierde <th> later andere css volgt, geldt de css hier feitelijk alleen voor de derde <th>.

Hiervoor gelden ook de bij th opgegeven instellingen.

width: 130px;

Breedte. Waarom ik px gebruik staat bij th.

th + th + th + th

Elke <th> die gelijk op drie andere opeenvolgende <th>'s volgt. Dat is hier alleen de vierde en laatste <th>.

Hiervoor gelden ook de bij th opgegeven instellingen.

width: auto;

Breedte. Voor de eerste drie kolommen heb ik een breedte in px opgegeven. Door hier auto op te geven, wordt voor deze kolom gewoon alle nog overblijvende ruimte gebruikt.

.kopje

De elementen met class="kopje". Binnen elke <th> staat een span met deze class. Binnen deze spans staan de kopjes die boven de kolommen staan.

Een aantal instellingen zijn voor alle vier de spans hetzelfde, die kan ik hier in één keer voor alle vier opgeven.

position: absolute;

Door de kopjes absoluut te positioneren, scrollen ze niet mee met de tabel. Waardoor ze altijd zichtbaar blijven.

Er wordt gepositioneerd ten opzichte van de eerste ouder die zelf een fixed, absolute of relatieve positie heeft. Dat is hier div#content.

Hoe het komt dat de kopjes niet meescrollen, staat bij #wrapper-tabel.

Van zichzelf is een span een inline-element. Door de span absoluut te positioneren, verandert hij in 'n soort blok-element, waardoor je eigenschappen als breedte en dergelijke kunt gebruiken.

top: 0;

Helemaal bovenaan div#content neerzetten.

div#content heeft aan de bovenkant een padding van 1,5 em. Hierdoor ontstaat er een lege ruimte van 1,5 em tussen div#content en de tabel. Door de kopjes helemaal bovenin div#content neer te zetten, komen ze precies in deze lege ruimte te staan. Waardoor het deel boven de tabel en de tabel zelf goed op elkaar aansluiten.

left: 0;

Helemaal links in div#content neerzetten. De andere drie kopjes komen verder naar rechts te staan, dat geef ik later apart voor die kopjes op.

width: 92px;

Breedte.

Ook weer 'n verschijnsel dat ik niet gelijk helemaal kan verklaren. De <th> waar deze span in staat, is 90 px breed. Die <th> heeft van zichzelf 'n kleine padding. Die kun je normaal genomen weghalen met padding: 0;. Dat blijkt echter niet te werken als de spans absoluut gepositioneerd zijn.

Als ik de span 2 px breder maak dan de bijbehorende <th>, vult de span de <th> wel volledig. Dat is van belang, omdat de span een achtergrondkleur heeft. Als niet de volledige <th> wordt gevuld, levert dat kieren in de achtergrondkleur op.

border-bottom: black solid 1px; Zwarte border aan onderkant header

Zwarte border aan de onderkant.

Als de pagina wordt geopend en de tabel dus nog niet gescrold is, valt dit randje samen met de border aan de onderkant van de <th>'s en zie je het dus niet. Als ik de tabel echter ga scrollen, scrollen de <th>'s en dus het randje aan de onderkant daarvan mee naar boven. Waardoor je het randje aan de onderkant van de <th>'s dus ook niet meer ziet.

Deze spans scrollen niet mee, het randje aan de onderkant dus ook niet. Zodra de tabel wordt gescrold en het randje van de <th>'s niet meer is te zien, wordt dit randje zichtbaar, zodat er altijd een randje aan de onderkant van de grijze balk met de kopjes zit.

Bovendien loopt het randje van de spans door tot boven de scrollbalk, het randje van de <th>'s niet.

Op de afbeelding is het randje aan de onderkant van de spans even rood gemaakt. Omdat het, als er nog niet is gescrold, precies boven het randje onder de <th>'s staat, zie je het normaal genomen niet, behalve het stukje boven de scrollbalk.

color: black;

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

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. 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.

Ik heb dit ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.

background: #ddd;

Grijze achtergrondkleur.

line-height: 1.6em;

Omdat geen hoogte is opgegeven, bepaalt deze regelhoogte ook de hoogte van de spans. Dit is precies de hoogte die nodig is om de opening boven de tabel te vullen. Als eenheid neem ik em, zodat ook bij Internet Explorer de regelhoogte mee verandert met de lettergrootte.

Tekst wordt automatisch in het midden van de regelhoogte gezet, zodat de kopjes netjes verticaal gecentreerd staan.

th + th .kopje

Het element met class="kopje" dat binnen een <th> staat, die gelijk op een andere <th> volgt. Dit zijn de spans voor de kopjes boven de tweede, derde en vierde kolom. Voor de spans boven de derde en vierde kolom geef ik later ook nog afwijkende css op.

Voor deze spans gelden ook de bij .kopje opgegeven eigenschappen.

left: 92px;

Tegen de eerste span aanzetten.

width: 81px;

Breedte.

Ook weer 'n verschijnsel dat ik niet gelijk helemaal kan verklaren. De <th> waar deze span in staat, is 80 px breed. Die <th> heeft van zichzelf 'n kleine padding. Die kun je normaal genomen weghalen met padding: 0;. Dat blijkt echter niet te werken als de spans absoluut gepositioneerd zijn.

Als ik de span 2 px breder maak dan de bijbehorende <th>, vult de span de <th> wel volledig. Dat is van belang, omdat de span een achtergrondkleur heeft. Als niet de volledige <th> wordt gevuld, levert dat kieren in de achtergrondkleur op.

(Ik maak hem 1 px breder, maar er komt ook nog 'n border links van 1 px breedte bij, dus dat is samen toch 2 px breder dan de <th>.)

border-left: black solid 1px;

Links staand randje. Dit komt precies boven de verticale lijntjes tussen de cellen te staan.

th+ th + th .kopje

Het element met class="kopje" dat binnen een <th> staat, die gelijk op een andere <th> volgt, die weer gelijk op 'n andere <th> volgt. Dit zijn de spans voor de kopjes boven de derde en vierde kolom. Omdat voor de vierde kolom later nog eigen css volgt, heeft dit in de praktijk alleen effect op de span boven de derde kolom.

Voor deze span gelden ook de bij .kopje en th + th .kopje opgegeven eigenschappen.

left: 174px;

Tegen de tweede span aanzetten.

width: 131px;

Ook weer 'n verschijnsel dat ik niet gelijk helemaal kan verklaren. De <th> waar deze span in staat, is 130 px breed. Die <th> heeft van zichzelf 'n kleine padding. Die kun je normaal genomen weghalen met padding: 0;. Dat blijkt echter niet te werken als de spans absoluut gepositioneerd zijn.

Als ik de span 2 px breder maak dan de bijbehorende <th>, vult de span de <th> wel volledig. Dat is van belang, omdat de span een achtergrondkleur heeft. Als niet de volledige <th> wordt gevuld, levert dat kieren in de achtergrondkleur op.

(Ik maak hem 1 px breder, maar er komt ook nog 'n border links van 1 px breedte bij, dus dat is samen toch 2 px breder dan de <th>.)

th + th + th + th .kopje

Het element met class="kopje" dat binnen een <th> staat, die gelijk op drie andere opeenvolgende <th>'s volgt. Dit zijn de spans voor de kopjes boven de vierde kolom.

Voor deze span gelden ook de bij .kopje en th + th .kopje opgegeven eigenschappen.

left: 306px;

Tegen de derde span aanzetten.

right: 0;

De span wordt gepositioneerd ten opzichte van de eerste ouder die zelf een relatieve, fixed of absolute positie heeft. Dat is hier div#content. De span loopt door deze instelling helemaal door tot aan de rechterkant van de div, en dus ook de in de span zittende achtergrondkleur, ongeacht hoe breed div#content wordt.

Dit zorgt ervoor dat de grijze achtergrondkleur altijd de volle breedte van de balk boven de tabel vult.

Alles in de tabel staat gecentreerd. Omdat deze vierde span altijd de resterende breedte volledig vult, staat de tekst in de span dus ook altijd gecentreerd in de resterende breedte. En omdat de vierde kolom zich precies hetzelfde gedraagt, staat het kopje ook altijd horizontaal gecentreerd boven de vierde kolom, ongeacht de breedte van deze kolom.

width: auto;

Bij .kopje heb ik een breedte van 92 px opgegeven. Die geldt ook voor deze span. Hiermee schakel ik die breedte uit. Als ik dat niet doe, heeft de right: 0; hierboven geen enkel effect: de span en dus de achtergrondkleur wordt niet breder dan 92 px, en het kopje staat ook niet horizontaal gecentreerd boven de kolom.

h2

Alle <h2>>'s. De tabel is ingedeeld in een aantal groepen. Boven elke groep staat zo'n kop.

margin: 0;

Van zichzelf heeft een <h2> een marge aan boven- en onderkant. Dat komt hier niet goed uit.

border-top: black solid 5px;

Brede zwarte rand aan de bovenkant, zodat (hopelijk) duidelijk is dat de kop bij het deel eronder hoort.

padding: 3px 0;

Omdat voor onder en links geen waarde is ingevuld, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 3px 0 3px 0 in de volgorde boven - rechts - onder - links. Boven en onder een kleine padding van 3 px, rechts en links geen padding.

Omdat alle tekst in de tabel gecentreerd staat, heeft een padding links en rechts geen nut. Het levert hooguit problemen op als ik de letters heel sterk zou vergroten.

color: black;

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

Hoewel dit de standaardkleur is, geef ik de kleur toch op. Hieronder geef ik een achtergrondkleur op. 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.

Ik heb dit ook al bij <body> opgegeven, maar sommige mensen hebben bij álle elementen de kleuren veranderd. Het heeft immers weinig zin als ze dat alleen bij de body doen, terwijl de sitebouwer de kleuren ook bij bijvoorbeeld de paragrafen heeft aangepast.

background: lightblue;

Lichtblauwe achtergrond.

(Ik ben nou eenmaal vrij zwart-wit in het beschrijven van de eigenschappen. Zal wel iets erfelijks zijn, dat dogmatische. Of invloed van de omgeving op m'n tere kinderzieltje ooit. Want ik geef grif toe dat er 'n statistisch net niet verwaarloosbare kans is dat extreem hoogbegaafde lezers misschien eventueel mogelijk deze betekenis zelf ook ongeveer enigszins ruwweg zouden hebben kunnen inschatten.)

font-weight: normal;

Van zichzelf is tekst in een <h> vet, dat vind ik hier te veel van het goede. 't Ding is van achteren al blauw en daar moet-ie maar tevreden mee zijn.

td

Alle cellen.

border: black solid;

Randje rondom de cellen. Omdat de rand niet aan alle kanten moet komen, geef ik de breedte hieronder apart op.

border-width: 0 0 1px 1px;

Kleur en soort van de rand heb ik hierboven al opgegeven.

Boven en rechts geen rand, onder en links 'n randje van 1 px breed. Als ik overal 'n rand zet, komt er op sommige plaatsen een dubbele rand te staan, omdat de randen van twee buren dan tegen elkaar aan komen te staan.

Normaal genomen zou je dat met border-collapse voorkomen, maar dat werkt hier niet goed, zoals beschreven bij border-spacing: 0;.

line-height: 1.5em;

Regelhoogte. Als eenheid neem ik em, zodat ook bij Internet Explorer de regelhoogte mee verandert met de lettergrootte.

Tekst wordt automatisch halverwege de regelhoogte gezet. Maar in een cel van een tabel wordt tekst altijd al verticaal gecentreerd, dus wat centreren betreft zou ik ook gewoon height kunnen gebruiken.

In de tabel staat echter in sommige cellen een kopje in een <h2>. Die <h2>'s hebben een lichtblauwe achtergrond. Als ik in plaats van regelhoogte 'n gewone hoogte gebruik, vult de hoogte van de <h2>'s bij sommige vergrotingen niet de hele cel. Waardoor je 'n lelijke kier krijgt tussen de blauwe achtergrond en de rand van de cel. Door regelhoogte te gebruiken, vult de <h2> altijd de hele cel.

td + td + td + td

De vierde cel binnen een serie van vier opeenvolgende cellen. In deze tabel zijn dat alleen de cellen in de vierde kolom.

padding-left: 5px;

De tekst in de tabel is bij table horizontaal gecentreerd, maar dat schakel ik hieronder voor deze cellen uit. Om toch wat afstand te krijgen tussen de rand van de cel en de tekst, geef ik daarom 'n kleine padding links op.

text-align: left;

Bij table is alle tekst in de tabel gecentreerd. Dat is voor de vierde kolom niet mooi, daarom zet ik de tekst hier gewoon links uitgelijnd neer.

td:first-child

Alle cellen, maar alleen als deze het eerste kind zijn. Dat zijn in deze tabel alleen de cellen uit de eerste kolom.

border-left: 0;

Bij td heb ik aan alle cellen een border onder en links opgegeven. Maar links van de eerste cel staat al een border: de border van div#content. Hierdoor zou er links van de eerste cel een dubbele border komen te staan. Dit voorkomt dat.

padding: 0;

Van zichzelf heeft een cel een klein padding.

Bij td is een regelhoogte opgegeven, en omdat tekst in een cel automatisch verticaal wordt gecentreerd, is een padding niet nodig. Omdat de regelhoogte vrij groot is, is die padding er toch al.

In de tabel staat echter in sommige cellen een kopje in een <h2>. Die <h2>'s hebben een lichtblauwe achtergrond. Door de padding in de cel, krijg je 'n lelijke kier tussen de blauwe achtergrond en de rand van de cel, zoals op de afbeelding is te zien. Dus haal ik de padding weg.

Omdat alle <h2>'s in de eerste cel staan, kan ik :first-child gebruiken. Als ik het voor álle cellen gebruik, worden de cellen allemaal wat lager en zou ik de regelhoogte weer wat moeten verhogen om dat weer te corrigeren.

Speciaal voor Internet Explorer 7

<!--[if IE 7]> <style> #voorbeeld {width: 764px;} table {width: 100.1%; border-collapse: collapse;} td {border: black solid 1px;} tbody th {width: auto;} </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 die uit de algemene stylesheet dan in principe overrulen.

Dit stukje geldt voor Internet Explorer 7, maar je kunt het ook voor andere versies aangeven.

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

<!--[if IE 7]> <link rel="stylesheet" href="../../css/naam-van-ie-stylesheet.css"> <![endif]-->

Op de plaats van "../../css/naam-van-ie-stylesheet.css" vul je pad naar en naam van jouw stylesheet voor Internet Explorer 7 in. De css voor Internet Explorer 6 komt dan apart in die stylesheet te staan, zodat het de andere browsers niet stoort.

Het is belangrijk dat de spaties in <!--[if IE 7]> en <![endif]--> precies zo worden overgenomen, zoals ze hier staan.

#voorbeeld

Het element met id="voorbeeld". Dat is hier de paragraaf met tekst op roze achtergrond boven de tabel.

width: 764px;

In de algemene css is de eigenschap box-sizing gebruikt, waardoor de breedte anders wordt berekend dan normaal. Internet Explorer 7 kent deze eigenschap niet, dus hier wordt de breedte op de normale manier opgegeven: marge, border en padding worden bij de breedte opgeteld. Zodat uiteindelijk de roze balk even breed wordt als in alle andere browsers en als de rest van de tabel.

table

Alle tabellen. Dat is er hier maar een.

width: 100.1%;

Een frummeltje te breed maken. Dat is om Joost mag weten wat voor reden nodig, omdat er anders geen verticale scrollbalk verschijnt.

Nu verschijnt er wel een horizontale scrollbalk, die volstrekt overbodig is, want de hele inhoud van de tabel staat ruim binnen het zichtbare deel. Maar het is niet anders in deze draak van een browser.

Waarschijnlijk zou dit wel op te lossen zijn, maar die tijd en energie vind ik deze lieveling van fabrikanten van kalmerende middelen niet meer waard.

border-collapse: collapse;

Omdat Internet Explorer 7 hiermee wel goed overweg kan, en met allerlei andere dingen uit de algemene css niet, gebruik ik dit om dubbele borders te voorkomen. Met de gelijk hieronder opgegeven border bij de cellen werkt dit prima.

td

Alle cellen.

border: black solid 1px;

Randje rondom de cellen. In combinatie met de hierboven opgegeven border-collapse werkt dit prima in deze browser, in tegenstelling tot allerlei andere dingen uit de algemene css die met borders te maken hebben.

h2

Alle <h2>'s. Dit zijn de kopjes met blauwe achtergrond binnen de tabel.

font-size: 1.1em;

Om een of andere reden geeft Internet Explorer 7 deze kopjes weer in een lettergrootte, waar De Telegraaf patent op genomen blijkt te hebben voor het aankondigen van de Derde Wereldoorlog. Om juridische problemen met De Telegraaf te voorkomen, verklein ik de letters.

Als eenheid gebruik ik em, zodat de gebruiker de lettergrootte kan veranderen.

(Oké, ik overdrijf misschien 'n heel klein tikkeltje, maar ik kan me beter op dit kreng afreageren dan op de kat van de buren. Dit mormel krabt in ieder geval niet terug.)

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 27 juli 2012.

Onder dit kopje staat alleen maar, hoe en waarin is getest. Eventuele problemen, ook die met betrekking tot zoomen en lettergroottes, staan hieronder bij Bekende problemen. Het is belangrijk dat te lezen, want uit een test kan ook prima blijken dat iets totaal niet werkt!

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

Dit voorbeeld is getest op de volgende systemen:

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

In resoluties groter dan 800x600 is ook in- en uitzoomen en - voor zover de browser dat kan - een kleinere en grotere letter getest. Er is ingezoomd en vergroot tot zover de browser kan, maar niet verder dan tot 200%.

Er is getest met behulp van muis en toetsenbord, behalve op de iPad en Android, waar een touchscreen is gebruikt.

Naast deze 'gewone' browsers is ook getest in Lynx, WebbIE, NVDA en Fangs Screen Reader Emulator. Lynx is een browser die alleen tekst laat zien en geen css gebruikt. WebbIE is een browser die gericht is op mensen met een handicap. NVDA is een screenreader, zoals die door blinden wordt gebruikt. Fangs Screen Reader Emulator is een extensie bij Firefox, die de pagina laat zien, zoals een screenreader hem ziet.

Als het voorbeeld in deze vier programma's toegankelijk is, zou het in principe toegankelijk moeten zijn in alle aangepaste browsers en dergelijke. En dus ook voor zoekmachines, want een zoekmachine is redelijk vergelijkbaar met een blinde. Eventuele opmerkingen over de toegankelijkheid specifiek voor dit voorbeeld staan onderaan Toegankelijkheid en zoekmachines onder het kopje Specifiek voor dit voorbeeld.

Alleen op de hierboven genoemde systemen en browsers is getest. Er is dus niet getest op bijvoorbeeld 'n Blackberry. De kans is (heel erg) groot dat dit voorbeeld niet (volledig) werkt op niet-geteste systemen en apparaten. Om het wel (volledig) werkend te krijgen, zul je vaak (kleine) wijzigingen en/of (kleine) aanvullingen moeten aanbrengen, bijvoorbeeld met JavaScript.

Er is ook geen enkele garantie dat iets werkt in een andere tablet of smartphone dan hierboven genoemd, omdat fabrikanten in principe de software kunnen veranderen. Dit is anders dan op de desktop, waar browsers altijd (vrijwel) hetzelfde werken, zelfs op verschillende besturingssystemen. Iets wat in Android browser werkt, zal in de regel overal werken in die browser, maar een garantie is er niet. De enige garantie is het daadwerkelijk testen op een fysiek apparaat. En aangezien er duizenden mobiele apparaten zijn, is daar eigenlijk geen beginnen aan.

De html is gevalideerd met de validator van w3c, de css ook. Als om een of andere reden niet volledig gevalideerd kon worden, wordt dat bij Bekende problemen vermeld.

Nieuwe browsers test ik pas, als ze uit het bèta-stadium zijn, omdat er anders 'n redelijke kans is dat ik 'n bug zit te omzeilen, die voor de uiteindelijke versie nog gerepareerd wordt. Dit voorbeeld is alleen getest in de hierboven met name genoemde browsers. Vragen over niet-geteste browsers kan ik niet beantwoorden, en het melden van fouten in niet-geteste browsers heeft ook geen enkel nut. (Melden van fouten, problemen, enz. in wel geteste browsers: graag!)

Bekende problemen

Waarop en hoe is getest, kun je gelijk hierboven vinden bij Getest in.

Internet Explorer 7

Deze browser heeft een horizontale scrollbalk. Die scrollbalk is in feite niet nodig, want de volledige inhoud van de tabel is netjes zichtbaar. Maar de tabel is iets breder gemaakt dan nodig, omdat er anders geen verticale scrollbalk verschijnt in deze browser. Je kunt nog steeds verticaal scrollen, maar zonder verticale scrollbalk is dat niet duidelijk.

Mogelijk is dit wel op te lossen, maar ook aan deze browser ga ik geleidelijk aan alleen nog maar minimale ondersteuning geven.

Internet Explorer 8

Deze browser lijkt niet helemaal goed met box-sizing uit de voeten te kunnen. Bij meer dan 150% inzoomen (vergroten) wordt het roze balkje boven de tabel zo'n halve centimeter breder dan zo moeten. Overigens ook nauwelijks 'n écht probleem.

Google Chrome op Linux, OSX en Windows en Safari op Windows en OSX

Bij zoomen ontstaat staan de verticale lijntjes in de kop boven de tabel niet meer helemaal precies boven de verticale lijntjes in de tabel zelf. Ook weer zo'n probleem waarvan ik me afvraag of ik soms niet té volledig ben bij het vermelden van Bekende problemen. Toch denk ik dat je beter iets te precies kunt zijn, dan dat je problemen gaat weglaten.

Alle browsers op Linux, OSX en Windows

Mobiele browsers

Deze constructie is zonder aanpassingen niet geschikt voor gebruik in mobiele browsers.

Als bij #wrapper-tabel hoogte en overflow worden weggehaald, is de hele tabel in alle geteste browsers te zien. De header scrolt dan wel mee. Ook vallen er aan de buitenkant borders weg. In Android browser op Android 4.0.3 is de balk gelijk onder de roze balk (die waarin ’Teken’, ’utf-8’, enz. staat) verdwenen.

Verder worden er veel vaste maten gebruikt, en dat kan op kleinere schermen al snel ’n probleem zijn.

Als de css bij #wrapper-tabel niet wordt gewijzigd, speelt uiteraard ook het probleem van de vaste maten. Daarnaast is het resultaat nogal wisselend:

Android Browser op Android 2.3.6: er kan niet worden gescrold, je ziet alleen maar wat bij opening van de pagina op het scherm staat.

Android Browser op Android 4.0.3: werkt zoals bedoeld (hele tabel te zien, header blijft stilstaan). Wel is de balk gelijk onder de roze balk (die waarin ’Teken’, ’utf-8’, enz. staat) verdwenen.

Opera Mobiel op Android 2.3.6 en Android 4.0.3: de hele tabel kan worden gescrold, inclusief de header, waardoor de hele tabel is te zien.

Opera Mini op de iPad en Android 2.3.6: er kan niet worden gescrold, je ziet alleen maar wat bij opening van de pagina op het scherm staat. In de éénkolomsstand kan wel worden gescrold, maar daarin is de tabel dermate verminkt, dat hij volstrekt onbruikbaar is.

Google Chrome op de iPad en Android 4.0.3, Firefox op Android 4.0.3, Safari op de iPad: werken zoals bedoeld (hele tabel te zien, header blijft stilstaan).

Wijzigingen

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

:

Nieuw opgenomen.

27 juli 2011: