Skip links en inhoudsopgave

Laatst aangepast: .

Oplosbare kruiswoordpuzzel met extra toeters en bellen

Korte omschrijving

Kruiswoordpuzzel die echt ingevuld kan worden. Afzonderlijke letters, woorden en de volledige oplossing kunnen (vooraf) worden bekeken.

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

Het hulpscherm is gewoon 'n simpele link met 'n plaatje. Bij hoveren daarover opent 'n pop-up met wat opgemaakte tekst.

De puzzel valt in feite in drie delen uiteen: de achtergrond met de vakjes, velden waarin je de letters in kunt vullen, en de extra's zoals het tonen van de oplossing.

De achtergrond van de puzzel is gewoon een zwart vierkant.

Op dit vierkant worden horizontale divs met een bepaalde hoogte en breedte absoluut gepositioneerd: de achtergrond voor de horizontale woorden. De divs hebben een witte achtergrond.

Binnen de divs staan spans, die als blok-element met een bepaalde breedte en hoogte worden neergezet. Ze worden naar links gefloat, zodat ze tegen elkaar aan komen te staan.

Deze spans hebben links en rechts een border. Het geheel levert vierkante vakjes op, zoals hiernaast op de afbeelding is te zien.

De te dikke dubbele border wordt later gedeeltelijk afgedekt door de divs voor de verticale woorden, zodat 'n border van 1 px breedte overblijft.

In de juiste spans worden getallen neergezet met een heel kleine lettergrootte. Omdat deze achtergrond helemaal los staat van de invoer, heeft deze lettergrootte geen invloed op de invoer.

Ik kan niet alle getallen hier neerzetten, want de divs voor de verticale woorden komen over de horizontale divs heen te staan. Daardoor zou ik getallen die onder zo'n verticale div komen te staan niet zien. Die getallen moet ik dus op de juiste plaats in een verticale div neerzetten, ook al horen ze bij horizontale woorden.

De achtergrond voor de verticale woorden bestaat ook uit divs met een witte achtergrond met een bepaalde breedte en hoogte. Ook deze worden absoluut gepositioneerd.

In deze divs komen de getallen voor de verticale woorden te staan, weer met een hele kleine lettergrootte.

Omdat deze divs boven de divs voor de horizontale woorden komen te staan, staan hier ook de getallen voor de horizontale woorden die anders onder 'n verticale div zouden komen te staan, zoals 10 en 22.

Als ik nu beide soorten div over elkaar heen zet, heb ik de achtergrond voor de puzzel.

Omdat deze puzzel toch volstrekt ontoegankelijk is voor spraakbrowsers en dergelijke, is er geen reden om hier niet 'n tabel te gebruiken. Dat zou makkelijker zijn geweest. Maar met 'n tabel was het niet mogelijk alles voor elke browser goed genoeg op de juiste plaats te krijgen.

De inputvelden voor de horizontale woorden zijn relatief eenvoudig. Het is een gewone <input>, waardoor je ook een maximaal aantal letters aan kunt geven. Ik gebruik een monospace-font in combinatie met een grote letter-spacing (en nog wat padding en zo). Hierdoor komen de letters in het midden van de span die het vakje van de achtergrond vormt te staan.

De <input> wordt absoluut op de juiste achtergrond gepositioneerd. Om alles op de juiste plaats te krijgen ontkom je er niet aan dat de <input> rechts 'n eindje uitsteekt, wat op de afbeelding is te zien door het rode lijntje dat rechts uitsteekt.

Als de <input> focus krijgt, wordt de achtergrond groen met behulp van een achtergrond-afbeelding. Het rechterdeel van die afbeelding is doorzichtig, omdat anders ook het groen rechts uit zou steken.

Omdat :focus niet werkt bij een <input> in Internet Explorer 6 en 7, wordt daarbij de achtergrond niet groen.

Het invoeren van de verticale woorden is 'n stuk ingewikkelder. Op dit moment kent css geen mogelijkheid om woorden verticaal in te voeren. Althans: dat kan wel in sommige browsers, maar dan kantelen de letters. Als css3 al volledig zou werken in alle browsers, zou je die gekantelde letters weer rechtop kunnen zetten.

Een css3-eigenschap die al wel werkt is word-wrap. word-wrap maakt het mogelijk om afbreken op een bepaalde breedte bínnen een woord te forceren. Dus ook na één letter. Maar word-wrap blijkt helaas niet te werken binnen <input>. Logisch, want <input> is per definitie bedoeld om op één regel te gebruiken, anders moet je <textarea> gebruiken. Maar <textarea> blijkt nog lastiger goed te krijgen dan de oplossing die ik nu heb gekozen.

Ik heb het als volgt opgelost: aan de buitenkant staat een verticale div absoluut gepositioneerd op de juiste plaats. Deze heeft overflow-y, dus verticale overflow, aan staan. Binnen deze div is een span als blok-element neergezet.

De inhoud van deze span is te bewerken omdat contenteditable op true is gezet. Dit is een html5-attribuut dat al werkt in alle browsers. Als contenteditable op true staat bij een willekeurig element, kun je de inhoud van dat element, hier dus de span, bewerken.

Omdat ik verticaal geen maximaal aantal letters kan opgeven, heb ik gezorgd voor een scrollbalk. Deze verschijnt zodra er meer dan het toegestane aantal letters onder elkaar wordt ingevuld. Dit is bedoeld als visuele indicatie dat er te veel letters zijn ingevuld.

De span is zo breed, dat er net geen twee letters naast elkaar in passen. Ook dit zijn weer monospace-letters van de juiste grootte.

Binnen een span werkt de eigenschap word-wrap wel. Door word-wrap op de breedte van één letter in te stellen, wordt na elke letter een nieuwe regel geforceerd: de letters staan onder elkaar.

Ik geef direct toe dat ik hier zwaar misbruik maak van css. Maar dit voorbeeld is puur voor de lol, het is niet voor echt gebruik bedoeld.

Omdat ik nou toch al op hol was geslagen met 'n idioot idee, ben ik nog maar even doorgegaan. 'n Paard op hol stopt uiteindelijk ook niet zo snel, en ik zal toch echt niet minder stom dan 'n paard zijn. Kwestie van gevoel van eigenwaarde.

En in 'n computer kun je natuurlijk dingen doen die zonder tovenaar in de buurt op papier niet kunnen, wat 't ook gewoon leuk maakt.

Bij hoveren over de knop linksonder opent een kleine pop-up. Als je daarna op de knop klikt, wordt de oplossing van de puzzel over de puzzel heen geprojecteerd. Niet gelijk als je hovert, want dan wordt de projectie al getoond als iemand per ongeluk over de knop zou hoveren: je moet echt klikken.

Omdat de pop-up gedeeltelijk over de puzzel staat, wordt deze juist weer gesloten als je op de knop klikt.

De projectie is niets anders dan een heel groot aantal spans, die als blok-element met een bepaalde grootte en breedte worden weergegeven. Ze worden naar links gefloat, zodat ze naast elkaar komen te staan. Tot de regel vol is, en dan weer verder op de volgende regel.

De spans zijn gewoon doorzichtig en hebben ook geen border. Elke span bestrijkt precies een vakje in de puzzel. Door in de juiste spans letters te zetten, worden die op de juiste plaats op de puzzel geprojecteerd.

De letters komen redelijk precies over de in de puzzel ingevulde letters te staan, zodat je snel kunt zien welke letters goed en welke fout zijn ingevuld. Daarom zijn ook geen getallen, lijntjes en zwarte vakjes nodig: die staan al in de puzzel en zijn gewoon door de doorzichtige projectie heen te zien.

Omdat Internet Explorer 6 alleen hoveren over 'n <a> herkent, werkt dit niet in Internet Explorer 6. Het was misschien wel werkend te krijgen geweest, maar ook het positioneren van de spans zou veel werk zijn geweest. En ik heb 't niet zo op oude lijken als Internet Explorer 6, dus ik vind 't wel best zo.

Als je over de knop rechtsonder hovert, opent een kleine pop-up boven de knop en een grote boven de omschrijvingen. De grote pop-up bevat de oplossing voor de puzzel, maar dan in kleiner formaat. Het is in feite een exacte kopie van de puzzel, maar dan kleiner. Dus de gebruikte technieken komen in grote lijnen overeen met de hierboven beschreven voor de echte puzzel. Alleen zijn hier de letters al ingevuld.

In eerste instantie is de oplossing afgedekt met een geel vlak. Anders zou de oplossing al getoond worden bij per ongeluk hoveren over de knop. Pas bij klikken op de knop verdwijnt de afdekking en wordt de oplossing zichtbaar.

In Internet Explorer 6 is er geen afdekking: de oplossing is gelijk zichtbaar, maar pas als je klikt op de knop, niet als je alleen over de knop hovert.

Rechts staan de omschrijvingen voor de puzzelwoorden. Die zijn ongetwijfeld grotendeels waardeloos, want ik ben geen puzzelmaker, maar daar gaat het niet om.

De omschrijvingen staan, met de getallen, in een gewone tabel, waar verder weinig spannends over is te melden. Ik geef direct toe dat het gebruik van 'n tabel hier eigenlijk niet hoort, omdat deze grotendeels voor opmaak wordt gebruikt. Maar omdat deze puzzel toch absoluut ontoegankelijk is voor spraakbrowsers en dergelijke, maakt dat hier weinig uit.

In de derde en vierde kolom van deze tabel staan knoppen. In Internet Explorer 6 staan deze er niet, want deze knoppen bleken in Internet Explorer 6 niet goed werkend te krijgen. Ze reageren op hoveren en dat werkt bij Internet Explorer 6 alleen in 'n <a>.

Bij hoveren over een knop uit de derde kolom opent een span met een zwarte achtergrond, die even hoog is als de div met omschrijvingen. Door elke knop 'n eigen id te geven kun je voor elke knop 'n eigen span openen.

Binnen deze span staan weer andere spans. Elk van deze geneste spans bevat een vraagteken. Deze vraagtekens zijn wit en daardoor goed zichtbaar op de zwarte achtergrond van de buitenste span.

Binnen de span met 'n vraagteken staat tenslotte nog 'n span. Deze span bevat een letter. Welke letter is afhankelijk van bij welke omschrijving de knop hoort en op welke plaats de span staat. De derde span in de rij toont de derde letter van het woord, enz. Dit geeft dus 'n mogelijkheid om slechts één letter van het woord op te zoeken.

De knoppen in de vierde kolom tonen bij hoveren erover een pop-up. Deze pop-up zit in een span, die als blok-element over de knop heen wordt neergezet, waardoor de cursor op de span komt te staan.

De span heeft een zwarte achtergrond met witte tekst. Binnen deze span staat een tweede span met 'n gele achtergrond. Deze tweede span wordt in het onderste deel van de buitenste span neergezet, maar beneden de cursor. Pas als je over deze tweede span hovert, wordt een derde geneste span geopend. Omdat deze tweede span niet onder de cursor staat maar je de cursor daar bewust heen moet bewegen, wordt het woord niet al getoond als je per ongeluk over de knop hovert.

Deze derde span bevat het woord dat bij de omschrijving hoort. Dit wordt absoluut gepositioneerd op de plaats waar het woord in de puzzel hoort te staan.

Dan is er nog 'n forse hoop aanpassingen nodig wat betreft padding, margin, z-index, noem maar op, om de hele handel goed te laten werken.

Internet Explorer 6 heeft relatief weinig aanpassingen nodig, maar dat komt voornamelijk omdat 'n groot deel van de extra's daar gewoon helemaal is uitgeschakeld.

Internet Explorer 7 heeft fors wat aanpassingen nodig, maar daar werkt alles dan ook, zei het met 'n enkel schoonheidsfoutje.

Internet Explorer 8 werkt eigenlijk foutloos. Maar omdat die conditional comments gewoon heel handig zijn, heb ik daar in dit geval gebruik van gemaakt om alles iets beter te positioneren binnen deze browser. Het zou bijzonder handig zijn als elke browser z'n eigen conditional comments zou hebben.

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 dan over die uit het algemene stylesheet heen gaan.

<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 <style> en </style> staat.

Technisch gezien is er geen enkel bezwaar om het in die stylesheet te zetten met dezelfde vreselijke lay-out als die ik in dit voorbeeld gebruik. Maar als je dat doet, garandeer ik je hele grote problemen omdat het volstrekt onoverzichtelijk is. Ik gebruik alleen deze lay-out 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 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).

De lettersoort hoort hier bij de essentiële code, omdat deze mede de grootte van de letters bepaalt. Bij het projecteren van de oplossing over de puzzel moet deze lettergrootte altijd hetzelfde zijn. Alweer een aanwijzing dat dit voorbeeld een leuk speeltje is, maar absoluut niet geschikt voor serieus gebruik. Een pagina die voor het goed functioneren afhankelijk is van een bepaalde lettersoort, is gewoon puur slecht geschreven.

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.

De lettergrootte hoort in dit voorbeeld bij de essentiële code, omdat de puzzel bij een andere lettergrootte onmiddellijk in een puinhoop verandert. Bij een goed geschreven pagina hoort dat natuurlijk niet te gebeuren, maar dit is alleen maar een leuk speeltje en niet bedoeld voor serieus gebruik.

color: black;

Zwarte letter.

div#wrapper

De div met id="wrapper". De div waarbinnen alles staat: puzzel, omschrijvingen, alles.

position: relative;

Door deze div een positie te geven, kan ik kinderen ervan positioneren ten opzichte van deze div, ook al vul ik hier verder niets in.

width: 796px;

Door een breedte aan de div te geven kan ik horizontaal centreren op de manier zoals ik gelijk hieronder doe.

margin: 0 auto;

Omdat geen waarde is ingevuld voor onder en links, krijgen die 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 oftewel: evenveel. Hierdoor staat deze div, en dus de inhoud, altijd horizontaal gecentreerd, ongeacht de grootte 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.

p#wrapper-help

De paragraaf met id="wrapper-help". Hierbinnen staat het hulpscherm en de link daarnaartoe (het plaatje met het vraagteken).

Dit staat voorin de html, zodat bij gebruik van de Tab-toets dit hulpscherm als eerste opent. Door hem voorin te zetten hoef ik tabindex niet te gebruiken.

position: absolute;

Om de link met het plaatje op een bepaalde plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een positie, dat is hier div#wrapper.

top: 10px;

Kleine ruimte aan de bovenkant.

left: 399px;

De link met het plaatje precies tegen de puzzel aan zetten.

margin: 0;

Een <p> heeft van zichzelf een marge aan boven- en onderkant, die is hier niet welkom.

z-index: 150;

Hoge z-index, zodat het hulpscherm altijd te zien is en niet wordt bedekt door andere elementen op de pagina. Ik gebruikt altijd nogal grote getallen voor de z-index, zodat je later nog makkelijk andere getallen kunt tussenvoegen. Je zou eventueel ook alle z-indexen uit dit voorbeeld door 10 kunnen delen, dan werken ze nog 't zelfde, maar zijn wat kleiner.

p#wrapper-help img

De afbeeldingen binnen de paragraaf met id="wrapper-help". Dit is hier alleen de kleine afbeelding met het vraagteken.

border: 0;

Een afbeelding binnen een link krijgt automatisch een border. Dat wil ik hier niet.

p#wrapper-help a

De links binnen de paragraaf met id="wrapper-help". Dat is er hier maar eentje: die waar het hulpscherm in zit. Het is hier trouwens geen echte link, maar hoveren werkt bij Internet Explorer 6 alleen bij 'n <a>, niet bij andere elementen.

text-decoration: none;

Normaal genomen wordt tekst binnen 'n link onderstreept. Dat geldt ook voor de tekst binnen de span met het hulpschermpje, want die staat ook binnen de link. Die onderstreping van de tekst wil ik hier niet.

color: black;

Ook de kleur van tekst binnen 'n link wordt veranderd, dat wil ik hier ook niet.

cursor: default

De cursor verandert normaal genomen boven 'n link in 'n handje. Omdat dit geen echte link is, wil ik dat de cursor er hier als 'n standaard-cursor blijft uitzien. Helaas werkt hoveren dan niet meer in de onvolprezen Internet Explorer 6 en 7, dus voor deze technologische hoogstandjes van Microsoft zorg ik later in aparte css voor die browsers dat de cursor wél in een handje verandert.

p#wrapper-help a span#help

De span met id="help" binnen 'n link die weer binnen de paragraaf met id="wrapper-help" ligt. Dit is de span waarbinnen de tekst van het hulpschermpje staat.

Dit schermpje wordt pas zichtbaar als ik over de link met het plaatje met het vraagteken hover, maar ik kan hier al alle opmaak opgeven.

position: absolute;

Om het schermpje op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een positie, dat is hier p#wrapper-help.

Een span is van zichzelf een inline-element. Door hem absoluut te positioneren, verandert hij in een blok-element. Daardoor kan ik attributen als breedte en hoogte gebruiken.

left: -8000px;

Parkeer het hele hulpschermpje ver links buiten het scherm. Nu is het onzichtbaar. Om het zichtbaar te maken hoef ik het alleen maar terug op het scherm te zetten.

width: 550px;

Breedte.

max-height: 420px;

In deze hoogte past de tekst ruimschoots. Hieronder bij overflow staat waarom ik 'n maximum hoogte aan het hulpschermpje geef.

border: black solid 2px;

Zwarte rand rondom de tekst, voor de leesbaarheid.

padding: 3px;

Kleine afstand tussen de rand van en de tekst in het schermpje.

font-size: 0.85em;

Iets kleinere letter. De lettergrootte van het hulpschermpje mag wel worden veranderd, dat sloopt de lay-out niet. Daarom gebruik ik em als eenheid, dan kunnen ook gebruikers van Internet Explorer de lettergrootte veranderen.

Dat heeft trouwens alleen in Internet Explorer 6 nut, in alle andere browsers werken allerlei dingen niet meer goed bij 'n andere lettergrootte.

background: white;

Witte achtergrond.

overflow: auto;

Als de tekst niet in het schermpje past, toon dan 'n verticale scrollbalk.

Als ik de letters sterk vergroot in een klein venster, maak ik me schuldig aan sadisme. Bij heel grote letters past de tekst niet meer in een klein venster. De tekst loopt er dan aan de onderkant af en is niet meer helemaal zichtbaar. En er verschijnt dus keurig 'n verticale scrollbalk.

Als ik echter die scrollbalk wil gebruiken, moet ik met de cursor het hulpschermpje verlaten, en dat sluit dan. Volgens mij kun je iemand daar helemaal gek mee maken... Je kunt wel 't scrollwieltje van de muis gebruiken en zo, maar heel veel mensen weten dat niet.

Als de tekst nu hoger wordt dan de opgegeven hoogte van 420px, verschijnt gewoon 'n scrollbalk in het hulpschermpje zelf. En die is gewoon op de normale manier te gebruiken zonder dat het schermpje sluit.

Internet Explorer 6 kent geen max-height, dus die krijgt geen scrollbalk.

span#help span.kopje

De spans met class="kopje" binnen de span met id="help". Binnen deze spans staan de kopjes van het hulpscherm.

Normaal genomen zou je misschien <h>'s nemen voor de kopjes, maar dat zijn blok-elementen. En 'n blok-element mag niet in 'n inline-element worden gezet, ook niet als dat inline-element als blok-element wordt weergegeven. Daarom zet ik de kopjes binnen 'n span en laat ze er 'handmatig' als 'n kopje uitzien.

display: block;

'n Span is 'n inline-element. Door er 'n blok-element van te maken komen ze op 'n nieuwe regel te staan.

Hè? En hierboven zeg je dat 'n blok-element niet mag binnen 'n inline-element. Ja, dat klopt, maar wel 'n inline-element dat alleen maar als blok-element wordt weergegeven. En niet op mij schieten, ik heb dit niet bedacht.

margin-top: 10px;

Boven elk kopje 'n kleine ruimte.

font-weight: bold;

Vette letter.

p#wrapper-help a:hover span#help, p#wrapper-help a:focus span#help

Doe iets met de span met id="help" die binnen 'n link ligt die weer binnen de paragraaf met id="wrapper-help" ligt. Maar alleen als over de link wordt gehoverd of als deze focus heeft.

Binnen deze span zit de tekst van het hulpschermpje.

:focus staat erbij omdat het schermpje dan ook opent als iemand hier met de Tab-toets aankomt. Normaal genomen zou ik er ook nog :active bij zetten, omdat Internet Explorer 6 en 7 dit foutief gebruiken alsof het :focus is, maar :active werkt hier om een of andere reden niet voor die twee browsers, dus laat ik het weg.

left: -170px;

De opmaak van het schermpje is al opgegeven bij p#wrapper-help a span#help. Ik hoeft het daar links buiten het scherm geparkeerde hulpvenstertje alleen maar binnen het scherm te zetten om het zichtbaar te maken. Iets naar links, zodat het altijd binnen het venster van de browser past, ook op kleinere schermen.

div#puzzel

De div met id="puzzel". Binnen deze div staat de eigenlijke puzzel.

position: relative;

Door de div een relatieve positie te geven kan ik kinderen van de div positioneren ten opzichte van de div. En ik kan de div zelf ook precies op de goede plaats zetten, maar dat zou ik ook met 'n marge of zo kunnen doen.

width: 390px; height: 390px;

Breedte en hoogte van de div en dus van de daarin zittende puzzel.

top: 10px;

Als ik niets zou opgeven, zou de div gewoon op de normale plaats worden gezet: bovenin z'n ouder div#wrapper, dus tegen de bovenkant van het venster van de browser. Nu is er 'n kleine afstand tussen bovenkant van het venster van de browser en de puzzel.

background: black;

Als ik de achtergrond zwart maak, heb ik in één klap alle zwarte vakjes gekleurd. De witte zet ik hier later gewoon bovenop.

border: black solid; border-width: 2px 1px;

Zwarte rand rondom de puzzel. Omdat bij de breedte van de rand links en onder niet zijn ingevuld, krijgen die automatisch dezelfde waarde als boven en rechts. Hier staat dus eigenlijk 2px 1px 2px 1px in de volgorde boven - rechts - onder - links.

Dit levert een border van overal 2 px op. Dat komt omdat de spans waar de vakjes van de puzzel in staan ook wat borders hebben, en die leveren links en rechts ook al 'n border van 1 px op.

Heel vaak zie je dit genoteerd als border-top: black solid 2px, border-left: black solid 1px; border-bottom: black solid 2px; border-right: black solid 1px;. Door de breedte apart te noteren kan de css 'n stuk korter.

div.hor

De divs met class="hor". Elke horizontale rij vakjes zit in een div. Deze divs hebben een aantal eigenschappen gemeenschappelijk. Daarom heb ik ze 'n class gegeven, zodat ik hier in één keer deze eigenschappen voor allemaal kan opgeven. De afwijkende eigenschappen voor elke div apart geef ik dan later op.

position: absolute;

Om de div op 'n bepaalde plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een positie, dat is hier div#puzzel. En omdat de verticale divs ook worden gepositioneerd ten opzichte van div#puzzel, zijn de horizontale en verticale divs ook indirect ten opzichte van elkaar gepositioneerd.

background: white;

Witte achtergrond. Hiermee geef ik alle vakjes voor de horizontale woorden 'n witte achtergrond. Nu hoef ik alleen nog maar op de juiste afstand verticale zwarte streepjes neer te zetten en ik heb vakjes voor de letters van de horizontale woorden. Die verticale streepjes zet ik later neer.

div#hor-7

De div met id="hor-7". Dit is de horizontale div die hoort bij woord nummer 7. De gemeenschappelijke instellingen voor de horizontale divs zijn al opgegeven bij div.hor. Hier geef ik alleen nog maar de instellingen speciaal voor deze div op.

top: 29px;

De eerste horizontale div, die bij woord 7 hoort, komt op de tweede regel te staan. Omdat de vakjes 30 px hoog zijn, zou je verwachten dat deze div 30 px van de bovenkant moet worden neergezet. Dat is eigenlijk ook zo. Maar het wit van deze div moet corresponderen met de horizontale zwarte lijntjes van de vakjes voor de verticale woorden. En die zwarte lijntjes worden 1 px omhoog gezet, omdat ze anders niet goed zijn te krijgen.

De afstand tússen de horizontale lijntjes voor de verticale woorden is 30 px, maar de eerste staat dus eigenlijk 1 px te hoog. Daarom moet deze div ook 1 px te hoog worden neergezet. Horizontale divs op lagere rijen staan wel steeds 30 px of 'n veelvoud daarvan lager.

Dit maakt niets uit, want het is met het blote oog niet te zien dat de bovenste rij 1 px te laag is. Althans: ik moet 't iets van 6 keer zo groot maken voor ik 't verschil zie.

width: 180px;

Elk vakje voor 'n letter is 30 px breed. In dit woord staan 6 letters, dus samen 180 px.

div#hor-8

De div met id="hor-8". Dit is de horizontale div die hoort bij woord nummer 8. De gemeenschappelijke instellingen voor de horizontale divs zijn al opgegeven bij div.hor. Hier geef ik alleen nog maar de instellingen speciaal voor deze div op.

top: 29px;

Hiervoor geldt hetzelfde als voor div#hor-7.

right: 0;

Dit woord komt aan de rechterkant van de puzzel te staan. Ik kan het vanaf links positioneren, maar het is veel makkelijk om het gewoon helemaal rechts neer te planten. Dat scheelt veel uitproberen en rekenen.

width: 180px;

Elk vakje voor 'n letter is 30 px breed. In dit woord staan 6 letters, dus samen 180 px.

div#hor-9

De div met id="hor-9". Dit is de horizontale div die hoort bij woord nummer 9. De gemeenschappelijke instellingen voor de horizontale divs zijn al opgegeven bij div.hor. Hier geef ik alleen nog maar de instellingen speciaal voor deze div op.

top: 89px;

De vakjes voor de letters zijn 30 px hoog. Woord 9 staat 2 rijen onder woord 7. Woord 7 stond op 29 px vanaf de bovenkant, dus woord 9 op 29 + 60 = 89 px.

width: 120px;

Elk vakje voor 'n letter is 30 px breed. In dit woord staan 4 letters, dus samen 120 px breed.

div#hor-10

De div met id="hor-10". Dit is de horizontale div die hoort bij woord nummer 10. De gemeenschappelijke instellingen voor de horizontale divs zijn al opgegeven bij div.hor. Hier geef ik alleen nog maar de instellingen speciaal voor deze div op.

top: 89px;

De vakjes voor de letters zijn 30 px hoog. Woord 10 staat 2 rijen onder woord 7. Woord 7 stond op 29 px vanaf de bovenkant, dus woord 10 op 29 + 60 = 89 px.

right: 0;

Dit woord komt aan de rechterkant van de puzzel te staan. Ik kan het vanaf links positioneren, maar het is veel makkelijk om het gewoon helemaal rechts neer te planten. Dat scheelt veel uitproberen en rekenen.

width: 240px;

Elk vakje voor 'n letter is 30 px breed. In dit woord staan 8 letters, dus samen 240 px breed.

div#hor-11 {top: 149px; width: 210px;}

t/m

div#hor-22 {top: 329px; right: 0; width: 180px;}

Voor al deze divs geldt hetzelfde als voor div#hor-9 of div#hor-10, afhankelijk van of ze aan de linkerkant of aan de rechterkant van de puzzel staan. Alleen de afstand vanaf de bovenkant verschilt en het aantal letters erin, dus de breedte. Het getal achter hor- in de id is het nummer van het woord waar de div bij hoort.

div.hor span

De spans binnen de divs met class="hor". Dit zijn de spans die voor de verticale lijntjes rondom de letters in de horizontale woorden zorgen. In sommige spans staat ook een nummer.

display: block;

Een span is van zichzelf een inline-element. Door er een blok-element van te maken kan ik eigenschappen als breedte en hoogte gebruiken.

float: left;

Een blok-element komt op een nieuwe regel te staan. Door ze naar links te floaten voorkom ik dat en komen ze naast elkaar te staan.

width: 28px;

De vakjes voor de letters zijn 30 px breed. Omdat links en rechts nog een border komt te staan van 1 px, is de totale breedte 30 px.

height: 29px;

Een blok-element wordt niet hoger dan nodig is om de inhoud te tonen. Hier hebben de meeste spans helemaal geen inhoud, want ik ben hier alleen met de achtergrond bezig. De invoer van de letters staat hier helemaal los van. 'n Enkele span heeft 'n getal als inhoud, maar dat is heel klein, dus ook die krijgen maar 'n hele lage hoogte.

Om de border links en rechts, de verticale zwarte streepjes rondom de vakjes met de letters, over de volle hoogte van de horizontale div met de witte achtergrond te krijgen moet ik dus zelf de hoogte opgeven.

Voor de horizontale divs waar deze spans in staan geldt trouwens hetzelfde. Ook die hebben geen echte inhoud, alleen deze spans staan erin. Die divs worden dus ook niet hoger dan deze spans. En die divs zorgen voor de witte achtergrond, dus als de spans te laag zijn, is de witte achtergrond ook te laag.

Je zou denken dat deze span 30 px hoog moet zijn. Dat is niet zo. De achtergrond van deze span is wit, want dat is de achtergrondkleur van de div waar deze span in staat.

De vakjes voor de letters in de verticale woorden (de 'verticale spans') zijn 29 px hoog, met 'n zwarte border aan de onderkant van 1 px. Deze verticale spans hebben dus 29 px wit in de hoogte.

Als ik nu de 'horizontale spans' 30 px hoog maak, krijg ik 30 px wit in de hoogte en komt de onderste px van de witte achtergrond naast de zwarte border aan de onderkant van de verticale spans te staan. Dat geeft een lelijk geblokt effect, zoals op bijgaande illustratie is te zien.

Door de horizontale spans 1 px lager te maken, ontstaat er voor het oog 'n doorlopende zwarte lijn, omdat ze nog maar 29 px wit in de hoogte hebben.

border: black solid; border-width: 0 1px;

Zwarte border van 1 px breed, maar alleen links en rechts.

Omdat bij border-width geen waarde voor onder en links is ingevuld, 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 1 px breed.

Omdat de spans gefloat worden staan de linker- en rechterborder tegen elkaar aan. Dus tussen twee spans staat een border van 2 px breed, wat niet de bedoeling is. Dat wordt weer gecorrigeerd door de divs voor de verticale woorden. Die hebben een witte achtergrond en halen de helft van de dubbele border weg, zodat er weer 'n lijntje van 1 px over blijft.

(Of ik niet gek ben geworden van al dit rekenwerk? Nou, misschien was ik dat al, want als je aan zoiets als dit begint... De eerlijkheid gebiedt me te zeggen dat ik voornamelijk maar wat heb uitgeprobeerd, tot het goed was in alle browsers. De uitleg van wat er nou precies gebeurt heb ik er grotendeels achteraf bij gehaald. En dat was voor mij af en toe ook nog even behoorlijk puzzelen.)

font-size: 11px;

Deze kleine lettergrootte is voor de getallen. Omdat de invoer van de letters helemaal los staat van deze achtergrond, kan ik deze lettergrootte gewoon opgeven zonder dat hij de invoer van de letters beïnvloedt.

Ik kan trouwens niet alle getallen in deze spans voor de letters in de horizontale woorden invullen. De getallen die de pech hebben geboren te worden op 'n plaats waar ook 'n verticale div staat, worden door de witte achtergrond van die div afgedekt. Die moet ik dus verplaatsen naar de juiste span in 'n verticale div, hoewel hij eigenlijk bij 'n horizontale div hoort.

letter-spacing: -1px;

Omdat er weinig ruimte is in 'n vakje zet ik dubbele getallen ietsje dichter op elkaar.

div.vert

De divs met class="vert". Elke verticale rij vakjes zit in een div. Deze divs hebben een aantal eigenschappen gemeenschappelijk. Daarom heb ik ze 'n class gegeven, zodat ik hier deze eigenschappen in één keer voor allemaal kan opgeven. De afwijkende eigenschappen voor elke div apart geef ik dan later op.

position: absolute;

Om ze op de goede plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een positie, dat is hier div#puzzel. En omdat de horizontale divs ook worden gepositioneerd ten opzichte van div#puzzel, zijn de horizontale en verticale divs ook indirect ten opzichte van elkaar gepositioneerd.

width: 30px;

30 px breed.

background: white;

Witte achtergrond. Hiermee geef ik alle vakjes voor de verticale woorden 'n witte achtergrond. Nu hoef ik alleen nog maar op de juiste afstand horizontale zwarte streepjes neer te zetten en ik heb vakjes voor de letters van de verticale woorden. Die horizontale streepjes zet ik later neer.

Omdat in de html deze divs na div.hor komen, bedekt deze witte achtergrond de horizontale divs. En de daarin zittende nummers. De nummers van de horizontale woorden die toevallig in 'n vakje staan waar ook 'n verticale div staat, zie ik daardoor niet. Deze moet ik daarom in de verticale div zetten en niet in de horizontale, ook al horen ze bij 'n horizontaal woord.

div#vert-1

De div met id="vert-1". Dit is de verticale div die hoort bij woord nummer 1. De gemeenschappelijke instellingen voor de verticale divs zijn al opgegeven bij div.vert. Hier geef ik alleen nog maar de instellingen speciaal voor deze div op.

Omdat deze verticale divs bovenaan in de puzzel komen te staan, hoef ik geen top op te geven.

left: 30px;

Het eerste verticale woord staat in de tweede verticale kolom, dus 30 px vanaf links neerzetten.

height: 118px;

Er komen 4 letters in dit woord, dus 4 x 30 px = 120 px. Zou je denken. Maar de horizontale div#hor-9 staat op 89 px vanaf de bovenkant, en die is 30 px hoog, dus eindigt op 119 px. Om de onderkant van deze horizontale div en de verticale div#vert-1 op gelijke hoogte te krijgen, moet deze div dus 1 px korter.

Dan heb ik de spans in div#hor-9 geen 30 px hoog, maar height: 29px gegeven om 'n kleine correctie aan te brengen. Dus er gaat nog 1 px van de hoogte van div#vert-1 af. Waarmee je op 118 px hoogte uitkomt.

div#vert-2 {left: 90px; height: 390px;}

t/m

div#vert-6 {left: 330px; height: 238px;}

Zelfde verhaal als bij div#vert-1. Alleen is de waarde van left afhankelijk van waar de verticale div komt te staan. De hoogte correspondeert met het aantal letters in het woord.

Bij div#vert-2 en div#vert-5 is de waarde wel een veelvoud van 30 px, omdat deze tot onderaan de puzzel lopen. Daarom hoef ik hier niet de correctie van 2 px op de hoogte aan te brengen, zoals die staat beschreven bij height: 118px.

Het getal achter vert- geeft aan bij welk woord de div hoort.

div#vert-12 {top: 150px; left: 30px; height: 240px;}

t/m

div#vert-20 {top: 270px; left: 330px; height: 120px;}

Grotendeels het zelfde verhaal als bij div#vert-1. Omdat deze woorden en dus de verticale div waar ze in staan niet helemaal boven in de puzzel beginnen, moet ik nu ook top opgeven. De waarde van left is afhankelijk van waar de verticale div komt te staan.

De hoogte correspondeert met het aantal letters in het woord. Die waarde is hier gewoon een veelvoud van 30 px, omdat deze divs tot onderaan de puzzel lopen. Daarom hoef ik hier niet de correctie van 2 px op de hoogte aan te brengen, zoals die staat beschreven bij height: 118px.

Het getal achter vert- geeft aan bij welk woord de div hoort.

div.vert span

De spans binnen de divs met class="vert". Deze spans zorgen voor de horizontale lijntjes tussen de letters van de verticale woorden. Ook staan in sommige spans getallen.

position: relative;

Om een kleine correctie in de positie aan te kunnen brengen.

top: -1px;

De span 1 px omhoog zetten. Dit is een van de instellingen die ervoor zorgen dat de letters uit de verticale woorden goed boven de letters uit de horizontale woorden staan.

display: block;

Een span is van zichzelf een inline-element. Door er een blok-element van te maken kan ik eigenschappen als breedte gebruiken. Bovendien wordt elke span nu op een nieuwe regel gezet, wat precies de bedoeling is omdat deze spans bij de verticale woorden horen.

height: 29px;

Een blok-element krijgt niet meer hoogte dan nodig is om de inhoud weer te geven. Hier zijn de meeste spans leeg, dus die krijgen helemaal geen hoogte.

De spans hebben wel een border van 1px aan de onderkant. En omdat de spans geen hoogte hebben, komen al die borders tegen elkaar aan te staan. Zoals op de illustratie is te zien.

In een enkele span staat een getal, en die spans hebben wel wat hoogte, maar ook niet genoeg. Daarom geef ik 'n hoogte van 29 px op. Samen met de border van 1px aan de onderkant is de hoogte dan 30 px, precies wat het moet zijn.

border-bottom: black solid 1px;

Zwarte border aan de onderkant van 1 px breed

font-size: 11px;

Deze kleine lettergrootte is voor de getallen. Omdat de invoer van de letters helemaal los staat van deze achtergrond, kan ik deze lettergrootte gewoon opgeven zonder dat hij de invoer van de letters beïnvloedt.

Binnen deze spans voor de verticale woorden staan ook sommige nummers die bij horizontale woorden horen. Als een horizontaal woord begint in een vakje waar ook een verticale div overheen loopt, zie je dit nummer niet door de witte achtergrond van de verticale div.

Daarom worden dit soort nummers niet in een span van een horizontaal woord gezet, maar in een span die bij een verticaal woord hoort. Nu staan ze boven de verticale div met de witte achtergrond en niet eronder.

letter-spacing: -1px;

Omdat er weinig ruimte is in 'n vakje zet ik dubbele getallen ietsje dichter op elkaar.

input

Voor de invoer van de horizontale woorden maak ik gebruik van <input>. Een aantal waarden zijn voor alle <input>'s hetzelfde, die kan ik hier in één keer opgeven. De afwijkende waarden voor elke <input> apart geef ik dan later op.

Het voordeel van <input> is dat ik met maxlength het aantal letters kan opgeven dat ik in mag voeren. Als het woord 'vol' is, kan ik gewoon geen letters meer toevoegen.

position: absolute;

Om de <input> op de juiste plaats te kunnen zetten. Van zichzelf is een <input> een min of meer normaal inline-element. Door het absoluut te positioneren verandert het in een blok-element en kan ik eigenschappen als breedte gebruiken.

margin-right: -2px;

Het hele inputveld 2 px naar rechts verplaatsen. Dit is een van de instellingen die ervoor zorgen dat de letters uit de horizontale woorden goed onder de letters uit de verticale woorden staan.

border: 0;

Sommige browsers zetten 'n border rondom 'n inputveld als dit focus heeft. Dat vind ik niet mooi hier.

padding: 2px 0 0 6px;

2 padding boven en 6 padding links. Dit is een van de instellingen die ervoor zorgen dat de letters uit de horizontale woorden goed onder de letters uit de verticale woorden staan.

font-size: 24px;

Behoorlijk grote letter nemen.

text-transform: uppercase;

Alle letters in hoofdletters veranderen. Zo voorkom ik dat er in 'n horizontaal woord eventueel 'n kleine letter en in 'n verticaal woord op hetzelfde veld 'n hoofdletter wordt ingevoerd.

font-family: monospace;

De letters komen in vierkante vakjes. Normaal genomen is 'n M breder dan 'n I, maar hier moeten alle letters even breed zijn. Met behulp van de letter-spacing hier gelijk onder vult elke elke letter dan precies één vakje. Ik laat het aan de browser over om 'n lettersoort uit te zoeken, als het maar monospace is.

letter-spacing: 16px;

Met deze letter-spacing blijkt elke letter precies één vakje te vullen.

background: none;

Een inputveld heeft standaard 'n witte achtergrond. Hier wil ik geen achtergrond hebben, want die komt ook over de zwarte lijntjes die de vakjes afgrenzen te staan, zoals hiernaast is te zien.

Bovendien is een inputveld langer dan nodig is om het woord weer te geven, dus de witte achtergrond wordt ook te lang. (Voor die grotere lengte is een reden, die bij input#char-hor-7 wordt besproken.)

line-height: 28px;

Een letter wordt automatisch halverwege de regelhoogte neergezet. Dit is een van de instellingen die ervoor zorgen dat de letters uit de horizontale woorden goed onder de letters uit de verticale woorden staan.

z-index: 10;

De divs en dergelijke voor de invoer van de verticale woorden komen hierna pas. Die komen dus over deze inputvelden te staan. Omdat een deel van die verticale divs tamelijk breed is, komen die gedeeltelijk over de inputvelden te staan. Deze zijn daardoor niet meer volledig klikbaar. Door 'n iets hogere z-index te geven is wel het hele inputveld klikbaar.

Dat is te zeggen: waar een verticaal en een horizontaal woord een vakje delen, 'wint' het verticale woord als je op dat vakje klikt, want dit komt in de html na de horizontale woorden.

input#char-hor-7

Het inputveld met id="char-hor-7". Dit is het inputveld dat hoort bij woord nummer 7. De instellingen die voor alle inputvelden hetzelfde zijn, zijn al opgegeven bij input. Hier staan alleen maar de instellingen die afwijken voor de afzonderlijke inputvelden.

top: 29px;

Dit inputveld moet boven div#hor-7 komen te staan, de ruimte voor woord nummer 7. Via uitproberen heb ik bij elk inputveld de beste top gevonden voor alle browsers. Dat kan 'n pixel afwijken van de bijbehorende horizontale div.

width: 188px;

In dit woord horen 6 letters, dus 6 x 30 = 180 px. Maar dan heeft de laatste letter te weinig ruimte, vanwege de brede letter-spacing. Daardoor zouden bij een breedte van precies 180 px alle letters verspringen als ik de laatste letter invoer. Bij een breedte van 188 px blijkt het goed te gaan.

Nu is het inputveld echter wel 8 px breder dan de bijbehorende horizontale div. Daar komen nog 'n padding links van 2px en 'n negatieve marge rechts van ook 2 px bij. In totaal is de breedte dus 12 px te veel.

En omdat het inputveld een groene achtergrond krijgt als het focus heeft, is ook die groene achtergrond dus 12 px te breed en steekt bijzonder lelijk uit naar links. Dat corrigeer ik bij input:focus.

Tijdens het maken van deze puzzel leek het wel 'n beetje op de beroemde tafel met vier poten, waarvan er eentje te kort is. Als je eenmaal gaat zagen, blíjf je bezig.

input#char-hor-8

Het inputveld met id="char-hor-8". Dit is het inputveld dat hoort bij woord nummer 8. De instellingen die voor alle inputvelden hetzelfde zijn, zijn al opgegeven bij input. Hier staan alleen maar de instellingen die afwijken voor de afzonderlijke inputvelden.

top: 29px;

Dit inputveld moet boven div#hor-8 komen te staan, de ruimte voor woord nummer 8. Via uitproberen heb ik bij elk inputveld de beste top gevonden voor alle browsers. Dat kan 'n pixel afwijken van de bijbehorende horizontale div.

right: -12px;

Dit woord komt aan de rechterkant van de puzzel te staan. Het is daarom het makkelijkst vanaf de rechterkant te positioneren. Om het op de goede plaats te krijgen moet het 12 px extra naar links worden geplaatst:

Het inputveld is 8 px 'te lang' (zie hieronder bij width waarom). Bij de algemene instellingen voor <input> is links 'n padding van 2 px gegeven, en rechts 'n negatieve marge van 2 px. Bij elkaar is dat dus 8 + 2 + 2 = 12 px te veel naar rechts, dus dat corrigeer ik hier.

width: 188px;

In dit woord komen 6 letters, dus 6 x 30 = 180 px. Maar dan heeft de laatste letter te weinig ruimte, vanwege de brede letter-spacing. Daardoor zouden bij een breedte van precies 180 px alle letters verspringen als ik de laatste letter invoer. Bij een breedte van 188 px blijkt het goed te gaan.

input#char-hor-9 {top: 88px; width: 128px;}

t/m

input#char-hor-22 {top: 328px; right: -12px; width: 188px;}

Zelfde als bij input#char-hor-7 voor de woorden die links staan, en input#char-hor-8 voor de woorden die rechts staan. Alleen de waarden bij top en width en eventueel right variëren. Het getal achter char-hor- geeft aan bij welk woord de <input> hoort.

input:focus

Als een inputveld focus heeft. Het kan focus krijgen door ergens in het veld te klikken, of door er met de Tab-toets naartoe te gaan.

Als een horizontaal en een verticaal woord een vakje delen, 'wint' het verticale woord als je op dat vakje klikt.

outline: 0;

Sommige browsers zetten een outline rondom het inputveld als dat focus heeft. Dat vind ik hier niet zo geslaagd.

border: 0;

Alle browsers zetten een border rondom het inputveld als dit focus heeft. Dat verstoort hier het beeld nogal.

background: url(073-pics/input-back.png) right;

Als een <input> focus heeft, krijgt het een doorzichtig groene achtergrond-afbeelding. Doorzichtig, omdat het anders de lijntjes rondom de vakjes zou afdekken. Door het doorzichtig te maken zijn de zwarte lijntjes nog goed zichtbaar door het groen heen.

Om de hele afbeelding zichtbaar te maken is er hier even 'n zwart randje omheen gezet. Het rechterdeel is namelijk doorzichtig, en dat zou je anders niet zien. Dit deel is 12 px breed.

Omdat de invoervelden 12 px te breed zijn, zou je anders ook groen rechts van de <input> zien. Nu zie je gewoon wat er rechts van de <input> zit, door de doorzichtige achtergrond-afbeelding heen.

Omdat het te brede deel van de <input> aan de rechterkant zit, moet ik de achtergrond-afbeelding ook rechts neerzetten. De afbeelding is breed genoeg om ook de <input> van het langste woord helemaal groen te kleuren.

Omdat :focus (en ook :active) niet werken bij Internet Explorer 6 en 7, krijgen die geen groene achtergrond.

div.vert-wrap

De divs met class="vert-wrap". Dit zijn de divs die bij het invoeren van de verticale woorden horen. Ik geef hier de gemeenschappelijke instellingen op, later geef ik afwijkende instellingen voor elke div afzonderlijk op.

Helaas kan ik <input> niet gebruiken bij de verticale woorden. <input> werkt per definitie maar op één regel, anders moet je <textarea> gebruiken. Maar <textarea> is nog ingewikkelder goed te krijgen dan de oplossing die ik nu heb gekozen.

Ik zou de letters verticaal kunnen invoeren. Maar daarbij kantelen de letters ook, staan dus op hun zijkant, dus dat werkt ook niet. css3 heeft wel een eigenschap om verticaal ingevoerde letters normaal weer te geven, maar dat werkt nog in geen enkele browser.

Omdat ik geen <input> kan gebruiken, kan ik ook geen maximum aantal letters opgeven dat ingevoerd mag worden. Dat is lastig, omdat je nu gewoon door kunt gaan met het invoeren van letters, die netjes onder elkaar worden geplaatst. Waardoor het 'n enorme chaos kan worden, zonder dat gelijk duidelijk is, hoe dat komt.

Daarom staat de span waar je echt in kunt invoeren in een div. Die div heeft een maximum-hoogte: je kunt gewoon niet meer invoeren dan het aantal letters dat in die hoogte past. Dat wil zeggen: als je meer dan dat aantal invoert, verschijnt 'n scrollbalk. Dat is 'n duidelijk signaal dat er iets mis is, 'n scrollbalk midden in 'n puzzel, en het voorkomt de chaos van volledig door elkaar heen geplaatste letters.

Niet ideaal, bepaald niet, maar iets beters kon ik niet bedenken. Dit is een van de voornaamste redenen dat dit voorbeeld niet in de praktijk is te gebruiken: ondanks het hulpscherm ben ik bang dat veel mensen niet begrijpen wat er gebeurt, en hoe ze dat moeten oplossen. (Nog los van dat talen als Java en JavaScript gewoon geschikter zijn voor dit soort dingen.) (En 'n gewoon ouderwets stuk papier is nog geschikter.)

position: absolute;

Om de divs op de juiste plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een positie, dat is hier div#puzzel.

width: 45px;

(Opmerking 8 maart 2011: deze breedte was nodig omdat Firefox voor versie 3.5 en Opera word-wrap niet kenden. Inmiddels zijn die versies van Firefox zwaar verouderd en kent Opera word-wrap ook. Mogelijk is deze breedte dus helemaal niet meer nodig. Maar het veroorzaakt geen problemen, dus laat ik het gewoon staan, want wie weet wat er voor rampen elders gebeuren als ik dit weghaal.)

Binnen deze div staat de span waarin je daadwerkelijk kunt invoeren. Daarin wordt gebruik gemaakt van word-wrap om na elke letter een nieuwe regel te forceren, zodat de letters onder elkaar komen te staan.

word-wrap werkt echter niet in Firefox voor versie 3.5 en in Opera. In deze browsers moet daarom na elke letter een spatie worden ingevoerd, zodat de browser denkt dat er 'n nieuw woord begint en de volgende letter op 'n nieuwe regel zet.

Als je dit niet doet, komen de letters in deze browsers gewoon naast elkaar te staan.

Als ik nou geen of 'n heel grote breedte opgeef, kan er in deze browsers gewoon door worden getypt en komen de letters naast elkaar te staan, wat tot chaos leidt.

Als ik 'n heel kleine breedte opgeef, zie ik überhaupt niet dat er meerdere letters naast elkaar staan.

45 px blijkt 'n redelijk compromis te zijn: er ontstaat geen chaos, maar je ziet wel dat er twee letters in één vakje staan. Bovendien verschijnt in Opera en Firefox voor versie 3.5 een verticale scrollbalk bij het naast elkaar zetten van drie of meer letters. Je ziet dus gelijk dat er iets mis is. (Waar die scrollbalk vandaan komt is me eerlijk gezegd 'n raadsel, want volgens mij zouden de letters gewoon zichtbaar moeten zijn, omdat standaard overflow op visible staat. Maar het komt hier prima uit.)

overflow-y: auto;

De daadwerkelijke invoer vindt plaats in de span die binnen deze div staat. Als deze te hoog wordt, met andere woorden: als er te veel letters worden ingevoerd, laat dan een verticale scrollbalk verschijnen. Dat is een duidelijk teken dat er iets mis is, en iets beters kon ik niet verzinnen.

Het is duidelijk dat een plotsklaps in de puzzel verschijnende scrollbalk daar niet hoort. En omdat je niet meer letters ziet dan er in het woord horen, ontstaat er ook geen chaos van door elkaar heen staande letters.

Om deze overflow te laten werken moet ik elke div een hoogte geven. Die verschilt echter per div, is afhankelijk van de lengte van het in te vullen woord, dus dat moet ik voor elke div apart opgeven.

div.vert-wrap span

De spans in de divs met class="vert-wrap". Dit zijn de spans waarin de verticale woorden daadwerkelijk worden ingevoerd. Om dit mogelijk te maken staat in de html bij deze spans contenteditable="true". Dit is een eigenschap uit html5, die echter al in alle browsers werkt. Het maakt het mogelijk de inhoud van 'n willekeurig element (hier dus een span) te wijzigen.

display: block;

Van zichzelf is een span een inline-element. Door er 'n blok-element van te maken kan ik eigenschappen als breedte gebruiken.

width: 15px;

Deze breedte zorgt ervoor, in combinatie met word-wrap en de lettergrootte, dat elke letter op een nieuwe regel wordt gezet.

padding: 0 7px 0 6px;

Rechts een padding van 7 px, links van 6 px. Ik heb hierboven een breedte van 15 px opgegeven. Maar het puzzelvakje is 30 px breed. Als ik nu 'n achtergrond ga geven, wordt die maar 15 px breed. Door ook nog 15 px padding toe te voegen, wordt de totale breedte 30 px en vult de achtergrond dus de volle breedte.

Daarnaast zorgt de padding aan de linkerkant ervoor dat de letters in het midden van het hokje staan en goed boven de letters uit de horizontale woorden komen te staan.

text-transform: uppercase;

Alle letters in hoofdletters veranderen. Zo voorkom ik dat er in 'n horizontaal woord eventueel 'n kleine letter en in 'n verticaal woord op hetzelfde veld 'n hoofdletter wordt ingevoerd.

font-family: monospace;

De letters komen in vierkante vakjes. Normaal genomen is 'n M breder dan 'n I, maar hier moeten alle letters even breed zijn. Met behulp van de letter-spacing hier gelijk onder vult elke elke letter dan precies één vakje. Ik laat het aan de browser over om 'n lettersoort uit te zoeken, als het maar monospace is.

word-wrap: break-word;

Deze eigenschap bestaat al heel lang in Internet Explorer, al in versie 6. Inmiddels werkt het in alle browsers. Het is een onderdeel van css3, maar valideert nog niet. Aangezien op Opera na nu alle browsers dit hebben geïmplementeerd, neem ik aan dat het binnenkort ook wel zal valideren als je op css3 valideert.

word-wrap forceert het afbreken van een woord op een willekeurige plaats in dat woord, als het woord te breed is voor het element waar het in staat. Door een combinatie van een tamelijk kleine breedte (15 px) en een tamelijk grote letter (24 px), forceer ik hier het afbreken van het woord na elke letter. Oftewel: de letters komen onder elkaar te staan.

font-size: 24px;

Behoorlijk grote letter nemen.

line-height: 30px;

Letters en dergelijke worden automatisch halverwege de regelhoogte gezet. De spans voor de invoer moeten even hoog zijn als de vakjes van de puzzel waar ze op staan: 30 px. Door dit via de regelhoogte te doen, worden de letters in een moeite verticaal in het midden gezet en staan ze goed boven de letters uit de horizontale woorden.

div#vert-wrap-1

De div met id="vert-wrap-1". Dit is de verticale div die bij woord nummer 1 hoort. De algemene instellingen voor deze verticale divs zijn al opgegeven bij div.vert-wrap.

top: -1px; left: 31px; height: 123px;

Deze instellingen heb ik gewoon verkregen door uit te proberen. Dit levert 'n aanvaardbaar compromis op voor alle browsers. Het is niet zo moeilijk om de letters van de verticale en horizontale woorden in één bepaalde browser exact goed te krijgen, maar dan wijken ze in andere browsers weer te veel af.

Deze hoogte hoort bij vier letters, 4 x 30 = 120 px. De span binnen deze div wordt net iets minder hoog. En omdat bij deze div in de algemene instellingen voor dit soort divs de overflow-y op auto is gezet, levert dat bij het invoeren van meer dan vier letters een verticale scrollbalk op. Een duidelijke visuele indicatie dat er iets mis is. Niet ideaal, maar iets beters kon ik niet bedenken.

div#vert-wrap-1 span

De span binnen de div met id="vert-wrap-1". Dit is de span waarin daadwerkelijk de verticale woorden kunnen worden ingevoerd. Deze hoort bij het woord met nummer 1. De algemene instellingen die voor al dit soort spans hetzelfde zijn, zijn al opgegeven bij div.vert-wrap span.

(Ik kan invoeren in deze span door gebruik te maken van de html5-eigenschap contenteditable, waarmee je in elk willekeurig element kunt invoeren, zoals hier in 'n span.)

height: 119px;

Deze hoogte hoort bij vier letters onder elkaar. Hieromheen staat een div (in dit geval div.vert-wrap-1) die ongeveer even hoog is en waarbij overflow-y op auto is gezet. Daardoor krijg ik in die div een verticale scrollbalk als er meer dan vier letters worden ingevoerd.

div#vert-wrap-2 {top: -1px; left: 91px; height: 394px;}
div#vert-wrap-2 span {height: 391px;}

t/m

div#vert-wrap-20 {top: 270px; left: 331px; height: 123px;}
div#vert-wrap-20 span {height: 120px;}

Al deze paren divs met bijbehorende span werken hetzelfde als div.vert-wrap-1 en div.vert-wrap-1 span. Alleen zijn de waarden anders, omdat ze op 'n andere plaats in de puzzel staan en omdat de woorden langer of korter zijn. Het getal achter vert-wrap geeft aan bij welk woord ze horen.

span:focus

Als 'n span focus heeft. Dit geldt alleen maar voor de spans die in de html contenteditable="true" hebben staan. Alleen de inhoud van deze spans is te bewerken, en alleen deze spans kunnen dus focus krijgen. In Internet Explorer 6 en 7 werkt :focus (en ook :active) niet, dus de css die bij deze selector hoort werkt daar ook niet.

outline: 0; border: 0;

Sommige browsers geven een outline of border rondom de span die focus heeft. Dat vind ik hier niet mooi.

background: url(073-pics/input-back.png);

Als een span focus heeft, krijgt het een doorzichtig groene achtergrond-afbeelding. Doorzichtig, omdat het anders de lijntjes rondom de vakjes zou afdekken. Door het doorzichtig te maken zijn de zwarte lijntjes nog goed zichtbaar door het groen heen.

Dit is hetzelfde achtergrond-plaatje dat wordt gebruikt voor <input>, dus het is behoorlijk breed. Dat maakt niet uit: hier worden gewoon alleen de meest linkse 30 px gebruikt, en naar beneden toe wordt dit deel steeds herhaald.

Door hetzelfde plaatje te gebruiken spaar ik een aanroep naar de server uit.

p#projectie

De paragraaf met id="projectie". De paragraaf waar de oplossing in staat die over de puzzel wordt geprojecteerd.

position: relative;

Door deze paragraaf te positioneren, kan ik kinderen hiervan positioneren ten opzichte van deze paragraaf, ook al vul ik hier verder niets in. Ook kan ik nu gebruik maken van z-index, daarvoor is een positie nodig.

margin: 23px 0;

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

Boven en onder 23 px marge, links en rechts geen marge.

De marge van 23 px aan de bovenkant zorgt ervoor dat de onderkant van de knop met 'Projecteer oplossing' netjes op dezelfde hoogte komt te staan als de onderkant van het blok met omschrijvingen.

Maar aan de onderkant heb ik ook 23 px marge, wat is het nut daarvan? Geen enkel. Maar van die marge hebben we geen last. Normaal genomen krijgt een blok-element zoals deze paragraaf precies genoeg hoogte om de inhoud ervan weer te kunnen geven. Maar niet als, zoals hier, de inhoud is gefloat.

De hoogte van deze paragraaf is dus 0. Aan de bovenkant heb ik 'n marge van 23 px. Dan komt de paragraaf zelf, met de inhoud. Die paragraaf zelf heeft geen hoogte, want de inhoud is gefloat. Dus de marge aan de onderkant staat gelijk tegen de marge aan de bovenkant aan. De marge aan de onderkant is er dus wel degelijk.

Maar de inhoud van de paragraaf is hoger dan 23 px, dus de marge van de paragraaf valt weg achter de inhoud, want die inhoud is hoger dan de marge. Bij een lagere inhoud zou de marge aan de onderkant inderdaad onder de knoppen uitsteken.

text-align: center;

Tekst (en andere inline-elementen) horizontaal centreren.

z-index: 30;

De span met de vraag die opent als je over de knop met 'Projecteer oplossing' hovert, komt over de puzzel te staan. Dus ook over het horizontale woord 21.

<input> heeft 'n z-index van 10 gekregen. Daardoor staat de span met de vraag onder de letters van dit woord, als die al zijn ingevuld. En als het woord focus heeft zie je de groene achtergrond door de vraag heen.

Dus geef ik 'n hogere z-index aan p#projectie, waardoor ook de inhoud daarvan 'n hogere z-index krijgt ten opzichte van <input>.

p#projectie a

De links binnen de paragraaf met id="projectie". Hier is dat maar één link waarbinnen de spans staan met de vraag, de bevestiging en de projectie zelf. De link zelf ziet eruit als een lichtblauwe knop met wat tekst erin.

float: left;

Zet zo hoog mogelijk en dan zo ver mogelijk naar links neer.

p#projectie, de ouder van deze link, is een blok-element. Dat krijgt normaal genomen automatisch dezelfde breedte als zijn ouder, dat is hier div#puzzel. Dus nogal breed. En alle inline-elementen zoals links worden horizontaal gecentreerd in p#projectie. Dus normaal genomen zou deze link, en dus ook de tekst daarin, halverwege de puzzel komen te staan. Niet zo'n goed idee. Nu komt alles gewoon links te staan.

border: black solid 1px;

Zwart randje.

padding: 2px;

Kleine afstand tussen tekst in de link en rand eromheen.

color: black;

Normaal genomen krijgt tekst in 'n link 'n andere kleur, dat wil ik hier niet.

text-decoration: none;

Normaal genomen wordt tekst in 'n link onderstreept, dat wil ik hier niet.

background: #dff;

Lichtblauwe achtergrond.

cursor: default;

Omdat dit geen gewone link is, wil ik dat de cursor gewoon standaard blijft en niet in 't handje dat bij 'n link hoort verandert.

p#projectie a span

De spans die binnen 'n link liggen die weer binnen de paragraaf met id="projectie" ligt. Wat ik hier opgeef geldt voor álle spans binnen deze link. Instellingen die afwijken voor 'n bepaalde span geef ik later apart op.

display: none;

De spans, en dus de inhoud, verbergen. Hoewel de spans dus verborgen zijn, kan ik hier al alle instellingen opgeven. Dan hoef ik ze later alleen nog maar zichtbaar te maken op het juiste moment.

position: absolute;

Om ze op 'n bepaalde plaats neer te kunnen zetten. Er wordt gepositioneerd ten opzichte van de eerste ouder met een positie, dat is hier p#projectie.

Een span is van zichzelf een inline-element. Door hem absoluut te positioneren verandert hij in een blok-element, waardoor ik eigenschappen als breedte kan gebruiken.

top: -405px;

Flink eind omhoog zetten. Binnen deze span komt de projectie met de oplossing van de puzzel te staan, en die moet over de gewone puzzel heen worden geprojecteerd. Dit blijkt daarvoor de goede hoogte te zijn.

left: 0;

Dit zou niet nodig moeten zijn, want als je niets opgeeft is dit de standaard-instelling. Maar Internet Explorer 7 zet de span dan foutief rechts van de tekst in de link. Dit corrigeert dat, en andere browsers hebben er geen last van.

width: 390px;

Er staan 13 vakjes van elk 30 px breed naast elkaar, samen 390 px.

font-family: monospace;

De letters komen in vierkante vakjes. Normaal genomen is 'n M breder dan 'n I, maar hier moeten alle letters even breed zijn. Ik laat het aan de browser over om 'n lettersoort uit te zoeken, als het maar monospace is.

font-size: 24px;

De letters komen over de letters in de puzzel heen te staan en moeten dus even groot zijn als die letters.

p#projectie a span span

De spans die binnen 'n span staan, die weer binnen 'n link staat, die tenslotte weer binnen de paragraaf met id="projectie" staat. Binnen deze spans staan de letters van de projectie met de oplossing.

De geprojecteerde oplossing met de spans even zichtbaar gemaakt met behulp van een lijntje
De geprojecteerde oplossing met de spans even zichtbaar gemaakt met behulp van een lijntje.

Voor deze span gelden ook de algemene instellingen voor alle spans binnen p#projectie die al zijn opgegeven bij p#projectie a span.

Omdat deze oplossing over de puzzel zelf komt te staan en doorzichtig is, hoef ik niet voor getallen, lijntjes, witte vlakjes, enz. te zorgen, want die zitten al in de puzzel. Alleen de letters hoeven er maar in te staan.

float: left;

Een span is van zichzelf een inline-element. Door ze te floaten veranderen ze in een min of meer normaal blok-element, waardoor ik eigenschappen als breedte en hoogte kan gebruiken.

Bij de algemene instellingen voor alle spans binnen p#projectie zijn ze absoluut gepositioneerd, waardoor ze ook al in een blok-element veranderden, maar die absolute positie verwijder ik hieronder weer voor deze spans, dus die geldt niet meer.

position: static;

Bij de algemene instellingen voor de spans zijn ze absoluut gepositioneerd. Hier verander ik dat weer terug naar de standaardinstelling.

Absoluut gepositioneerde elementen zijn ook absoluut asociaal: ze trekken zich niets van elkaar aan. Elke span zou linksboven in de eerste ouder met een positie, hier p#projectie a span, worden neergezet. Allemaal over elkaar heen. En omdat in deze spans de letters van de oplossing staan, lijkt me dat eigenlijk niet zo'n goed idee. Je belooft 'n oplossing en in plaats daarvan verschijnt 'n nieuwe puzzel: alle letters over elkaar heen. Dat soort oplossingen zullen we maar aan de politiek overlaten.

width: 30px;

Breedte 30 px. Omdat de span waar deze spans in staan, p#projectie a span, 390 px breed is, passen er precies 13 van deze spans naast elkaar. En omdat ze zijn gefloat gaat de volgende span, gewoon naar de volgende regel.

In de html hoef ik dus niets anders te doen dan voor elke regel 13 x 13 spans neer te zetten. Elke veertiende span gaat netjes naar de volgende regel. Hierdoor zijn alle vakjes van de puzzel netjes bedekt en hoef ik alleen maar in de juiste span de juiste letter neer te zetten om de oplossing over de puzzel te projecteren.

height: 30px;

De spans worden niet hoger dan nodig is voor de inhoud, en sommige spans zijn helemaal leeg, daar staat geen letter in. Daarom geef ik zelf 'n hoogte op: even hoog als de vakjes van de puzzel.

p#projectie a span#projectie-vraag

De span met id="projectie-vraag" binnen 'n link die weer binnen de paragraaf met id="projectie" ligt. De span waarbinnen de tekst van de vraag ligt die je moet bevestigen voor de projectie echt wordt getoond.

Voor deze span gelden ook de instellingen die al zijn opgegeven bij p#projectie a span. Daar is de span ook verborgen. Ik kan hier al de hele opmaak neerzetten, dan hoef ik hem later alleen nog maar zichtbaar te maken op het juiste moment.

bottom: -1px;

De span gelijk boven de link met de knop neerzetten. 1 px omlaag, dan vallen de borders van de knop en de vraag netjes over elkaar heen.

top: auto;

Bij de instellingen voor alle spans binnen p#projectie heb ik 'n top van -450 px opgegeven. Als ik die hier niet weghaal, wordt de span met de vraag uitgerekt tussen bottom: -1px; en top: -450px;. Omdat ik de span vanaf onder neerzet, zal nu alleen de hoogte die nodig is worden gebruikt, en dan van de onderkant af naar boven.

Als ik de span met behulp van top ergens neer zou zetten, zou deze naar onder toe groter worden bij 'n grotere lettergrootte, en uiteindelijk de knop bedekken. En omdat naar die knop wordt verwezen in de vraag is dat verwarrend.

Door de span vanaf de onderkant neer te zetten zal hij omhoog groeien bij 'n grotere lettergrootte en kan hij de knop niet afdekken.

width: 200px;

Breedte.

border: black solid 1px;

Zwart randje rondom de span.

padding: 3px;

Kleine afstand tussen tekst en rand rondom de span.

font-size: 18px;

Bij de instellingen voor alle spans binnen p#projectie heb ik 'n lettergrootte van 24 px opgegeven. Dat is veel te groot voor de tekst binnen deze span.

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

Bij de instellingen voor alle spans binnen p#projectie heb ik monospace opgegeven, hier wil ik 'n gewone normale letter.

background: yellow;

Gele achtergrond.

p#projectie a:hover span#projectie-vraag

Doe iets met de span met id="projectie-vraag" binnen 'n link die weer binnen de paragraaf met id="projectie" ligt, maar alleen als ik over de link hover. Binnen deze span staat de vraag die ik bevestigend moet beantwoorden voor de projectie echt wordt getoond.

De link is op het scherm zichtbaar als de blauwe knop met 'Projecteer oplossing'.

display: block;

Toon de span, en dus de daarin zittende vraag.

p#projectie a:active span#projectie-vraag

Doe iets met de span met id="projectie-vraag" binnen 'n link die weer binnen de paragraaf met id="projectie" ligt, maar alleen zolang ik op de link klik. Binnen deze span staat de vraag die ik bevestigend moet beantwoorden voor de projectie echt wordt getoond.

Dat bevestigen doe ik door de muisknop in te drukken boven de link.

display: none;

Verberg deze span. Omdat de vraag gedeeltelijk over de puzzel heen staat, kan ik anders niet de hele puzzel zien, en dus de geprojecteerde oplossing niet vergelijken met de hele puzzel.

Ik moet dus expliciet de muis indrukken op de link om de vraag te verbergen. Als ik de muis niet meer indruk, zal de vraag weer verschijnen.

In Internet Explorer 7 werkt :active foutief zoals :focus hoort te werken. Als ik op de link klik, blijft de link daardoor :active. Om dat uit te schakelen moet je ergens buiten de link klikken. Als je dat niet doet, verschijnt de vraag niet als je weer over de link hovert, omdat deze dus nog steeds actief is. Hier is niets aan te doen, het was 'n bewuste keuze van Microsoft om dit verkeerd te implementeren. In Internet Explorer 8 werkt dit (eindelijk) zoals het hoort te werken.

p#projectie a:active span

Doe iets met de span in 'n link binnen de paragraaf met id="projectie", maar alleen zolang ik op de link klik. Binnen deze span staat de oplossing die op de puzzel geprojecteerd kan worden.

display: block;

Toon deze span, en dus de inhoud (de geprojecteerde oplossing). De opmaak van de inhoud is al opgegeven bij p#projectie a span en p#projectie a span span, dus ik hoef hem hier alleen maar zichtbaar te maken.

Ik moet dus expliciet de muis indrukken op de link om de oplossing te tonen. Als ik de muis niet meer indruk, zal de vraag weer verschijnen. Hiermee voorkom ik dat de oplossing per ongeluk al wordt getoond bij alleen hoveren over de link.

In Internet Explorer 7 werkt :active foutief zoals :focus hoort te werken. Als ik op de link klik, blijft de link daardoor :active. Om dat uit te schakelen moet je ergens buiten de link klikken. Als je dat niet doet, wordt de oplossing gelijk zonder klikken geprojecteerd als je weer over de link hovert, omdat deze dus nog steeds actief is. Hier is niets aan te doen, het was 'n bewuste keuze van Microsoft om dit verkeerd te implementeren. In Internet Explorer 8 werkt dit (eindelijk) zoals het hoort te werken.

p#tonen

De paragraaf met id="tonen". De paragraaf waar de opgeloste puzzel in het klein in staat.

position: relative;

Om de kinderen van deze paragraaf te kunnen positioneren ten opzichte van deze paragraaf, moet ik hem 'n positie geven, ook al vul ik daar verder niets bij in.

width: 392px;

De knop die in deze paragraaf komt te staan moet gelijk komen te staan met de rechterkant van de puzzel, dat ziet er het mooist uit. De puzzel is 300 px breed met rechts nog 'n border van 2 px, samen 392 px dus.

text-align: center;

Tekst (en andere inline-elementen) horizontaal centreren.

z-index: 100;

De kleine oplossing wordt boven de div met omschrijvingen gezet. Maar de div met omschrijvingen staat in de html na p#tonen, waardoor deze oplossing onder de omschrijvingen komt te staan en onzichtbaar is. Door de kleine oplossing 'n hogere z-index te geven is hij wel zichtbaar.

Ik gebruik altijd vrij grote getallen voor de z-index, zodat je er later makkelijk nog getallen tussen kan stoppen als dat nodig zou zijn.

p#tonen a

De links binnen de paragraaf met id="tonen". Hier is dat maar één link waarbinnen de spans staan met de vraag, de bevestiging en de oplossing zelf. De link zelf ziet eruit als een lichtblauwe knop met wat tekst erin.

float: right;

Zet zo hoog mogelijk en dan zover mogelijk naar rechts. Hierdoor komt de rechterkant van de link, en dus van de blauwe knop, netjes onder de rechterkant van de puzzel te staan.

border: black solid 1px;

Zwart randje.

padding: 2px;

Kleine afstand tussen tekst en zwarte randje.

color: black;

Tekst in een link krijgt normaal genomen een andere kleur. Dat wil ik hier niet.

text-decoration: none;

Tekst in een link wordt normaal genomen onderstreept. Dat wil ik hier niet.

background: #dff;

Lichtblauwe achtergrond.

cursor: default;

Omdat dit geen gewone link is, wil ik dat de cursor gewoon standaard blijft en niet in 't handje dat bij 'n link hoort verandert.

p#tonen a span

De spans binnen 'n link binnen de paragraaf met id="tonen". Binnen deze spans staan de vraag die bevestigd moet worden, de kleine opgeloste puzzel en het 'deksel' daarop dat voorkomt dat je de oplossing per ongeluk ziet als je alleen maar over de link hovert.

Ik kan hier al de hele opmaak opgeven, dan hoef ik het later alleen nog maar zichtbaar te maken op het juiste moment.

De <a> heeft twee spans. Binnen de ene staat de opgeloste puzzel, binnen de andere de vraag. Binnen deze spans staan weer geneste spans. Wat ik hier opgeef, geldt voor ál deze spans, want ze staan allemaal binnen p#tonen. Waar nodig geef ik later voor geneste spans andere instellingen op.

display: none;

Verberg alles.

position: absolute;

Om alles op de juiste plaats te kunnen zetten. Hierdoor kan ik ook 'n geneste span positioneren ten opzichte van z'n ouder-span, want ik kan alleen positioneren ten opzichte van 'n ouder als die zelf 'n positie heeft.

Een span is van zichzelf een inline-element. Door hem absoluut te positioneren, verandert hij in een blok-element en kan ik eigenschappen als breedte en hoogte gebruiken.

top: -273px;

Zet de opgeloste kleine puzzel 'n eind omhoog.

left: 418px;

Op deze afstand van links valt de linkerkant van de oplossing gelijk met de linkerkant van de omschrijvingen.

width: 246px; height: 246px;

Omdat de oplossing nou eenmaal 'n breedte en hoogte moet hebben.

border: green solid 10px;

Dikke groene border. Niet mooi, maar maakt de oplossing wel duidelijk zichtbaar.

background: white;

Witte achtergrond.

font-family: monospace;

De letters komen in vierkante vakjes. Normaal genomen is 'n M breder dan 'n I, maar hier moeten alle letters even breed zijn. Ik laat het aan de browser over om 'n lettersoort uit te zoeken, als het maar monospace is.

p#tonen a span span

De spans die zelf binnen 'n span staan, die weer binnen 'n link staat, die uiteindelijk binnen de paragraaf met id="tonen" staat.

Elke horizontale regel van de kleine oplossing staat binnen zo'n geneste span.

Voor deze spans gelden ook de instellingen voor alle spans binnen p#tonen, zoals opgegeven bij p#tonen a span.

position: static;

Bij de instellingen voor alle spans binnen p#tonen is een absolute positie opgegeven, met een top en 'n left. Daardoor zouden deze regels volkomen verkeerd komen te staan, daarom verander ik de absolute positie weer in de standaard-position.

Nu zit ik alleen met het probleem dat de span weer 'n gewoon inline-element is en dat ik dus eigenschappen als hoogte niet kan gebruiken. Daarom verander ik de spans bij p#tonen a:hover span (als ik over de link hover) weer in 'n blok-element.

height: 18px;

Hoogte van 'n regel binnen de kleine oplossing.

border: 0;

Bij de instellingen voor alle spans binnen p#tonen heb ik 'n groene border ingesteld. Weg ermee.

border-bottom: black solid 1px;

Maar ik wil wel aan de onderkant 'n border. Daarmee heb ik de horizontale zwarte lijnen in de kleine oplossing getrokken.

background: none;

Bij de instellingen voor alle spans binnen p#tonen heb ik 'n witte achtergrond opgegeven. Die stoort hier.

p#tonen a span span span

De spans die binnen 'n span liggen die zelf ook weer binnen 'n span ligt. Dat geheel moet binnen 'n link in de paragraaf met id="tonen" liggen. Dit zijn de spans waarin de getallen en letters staan.

Voor deze spans gelden ook de instellingen voor alle spans binnen p#tonen, zoals opgegeven bij p#tonen a span. En omdat het om twee keer geneste spans gaat, gelden ook de instellingen zoals opgegeven bij p#tonen a span span.

float: left;

Zet zover mogelijk omhoog en dan zover mogelijk naar links.

Bij de instellingen voor alle spans binnen p#tonen zijn de spans absoluut gepositioneerd, waardoor ze zijn veranderd in blok-elementen. Daardoor zou elke span op een nieuwe regel komen te staan. Door ze naar links te floaten komen ze naast elkaar te staan. Pas als ze niet meer op 'n regel passen, komt de volgende span op 'n nieuwe regel te staan.

width: 18px;

18 px breed maken. De buitenste span heeft bij p#tonen a span een breedte van 246 px gekregen. Omdat deze spans nog 'n border rechts krijgen van 1 px, zijn ze 19 px breed. Er passen dan precies dertien spans naast elkaar.

Passen? Niet helemaal. Dertien spans zijn precies 1 px te breed. Daarom krijgt de laatste span uit de rij geen border rechts, dan past het wel precies.

Als ik dat niet zou doen, zou de laatste span op de volgende regel worden gezet, want 'n gefloat element dat niet meer past wordt altijd op 'n nieuwe regel gezet. Die border haal ik verderop weg bij p#tonen span.l.

border-right: black solid 1px;

Rechts 'n border. Hiermee zijn de verticale strepen in de kleine oplossing aangebracht.

font-size: 12px;

Tamelijk kleine letter, maar de oplossing staat ook in 'n tamelijk klein venster.

line-height: 22px;

De letters worden automatisch halverwege de regelhoogte gezet. Deze regelhoogte is eigenlijk te hoog, omdat de spans waar de regel in staat maar 18 px hoog zijn. Hierdoor komen de letters iets te laag te staan. Daardoor staan ze iets verder onder de getallen, die ik ook nog in dit kleine geheel moet zien te priegelen.

p#tonen span.zw

De spans met class="zw" binnen de paragraaf met id="tonen". Dit zijn de spans die een zwarte achtergrond krijgen en voor de zwarte blokjes in de kleine oplossing zorgen.

Omdat dit dubbel geneste spans zijn, gelden ook alle instellingen die gelden voor p#tonen a span span span. Het enige verschil is dat deze spans ook nog 'n extra class "zw" hebben.

background: black;

Zwarte achtergrond geven.

p#tonen span.nr

De spans met class="nr" binnen de paragraaf met id="tonen". Dit zijn de spans waarin een getal staat.

Omdat dit dubbel geneste spans zijn, gelden ook alle instellingen die gelden voor p#tonen a span span span. Het enige verschil is dat deze spans ook nog 'n extra class "nr" hebben.

Feitelijk zijn dit driedubbel geneste spans, want de spans met het nummer staan binnen de span die voor het betreffende vakje zorgt.

width: 4px; height: 4px;

Omdat hier alleen de heel kleine getallen in staan kleine breedte en hoogte geven.

margin-top: -7px;

De spans met de nummers staan bínnen de span met de letter waar ze bij horen. Daardoor drukken ze de letter in de span waar ze in staan iets naar rechts, zoals hiernaast is te zien.

Dat komt omdat de beide spans worden gefloat. Ongeacht de breedte (hier 4 px), duwt de ínhoud van de gefloate span (hier de getallen) de tweede span opzij. Als ik nu deze span met het nummer, en dus het nummer zelf, 7 px omhoog zet, komt het nummer net boven de letter en duwt deze niet meer opzij.

Nu staan de letters weer goed. 't Is wat krap allemaal, maar 't past net.

border: 0;

De eerder voor de spans opgegeven border is hier niet welkom.

font-size: 7px;

Hele kleine letter, anders past het niet.

font-family: sans-serif;

Eerder heb ik monospace opgegeven, maar dat neemt meer ruimte in dan een proportioneel font (waar de M meer ruimte krijgt dan de I). Daarom maak ik er hier weer 'n gewoon font van. Ik laat het aan de browser over om het font te kiezen, als het maar geen streepjes heeft. Het maakt hier allemaal weinig uit, want de getallen zijn zo klein dat je toch nauwelijks ziet wat voor soort letter het is.

letter-spacing: -1px;

En als klap op de vuurpijl zet ik getallen die uit twee cijfers bestaan iets dichter op elkaar. Ik wil niet veel zeggen, maar als ik over de woonruimte ging in Nederland was iedereen allang onderdak geweest. Wel 'n beetje krap, maar 't zit er allemaal in.

p#tonen span.l

De spans met class="l" (van 'laatst') binnen de paragraaf met id="tonen". Dit zijn de spans die steeds als laatste op een regel staan.

Omdat dit dubbel geneste spans zijn, gelden ook alle instellingen die gelden voor p#tonen a span span span. Het enige verschil is dat deze spans ook nog 'n extra class "l" hebben.

border: 0;

De laatste span mag geen border hebben. De reden staat bij width: 18px.

p#tonen a span#oplos-vraag

De span met id="oplos-vraag" binnen 'n link die weer binnen de paragraaf met id="tonen" ligt. Dit is de span waarbinnen de vraag ligt die bevestigend beantwoord moet worden voordat de kleine oplossing echt wordt getoond.

Ik kan hier alvast de hele opmaak opgeven, dan hoef ik de span en dus de inhoud later alleen nog maar op het juiste moment zichtbaar te maken.

Voor deze span gelden ook de instellingen die voor alle spans binnen p#tonen zijn opgegeven bij p#tonen a span, hoewel heel veel van die instellingen hier worden overruled voor deze span.

display: none;

Verberg de span en dus de inhoud ervan.

bottom: -1px;

De span gelijk boven de link met de knop neerzetten. 1 px omlaag, dan vallen de borders van de knop en de vraag netjes over elkaar heen.

top: auto;

Bij de instellingen voor alle spans binnen p#tonen heb ik 'n top van -273 px opgegeven. Als ik die hier niet weghaal, wordt de span met de vraag uitgerekt tussen bottom: -1px; en top: -273px;. Omdat ik de span vanaf onder neerzet, zal nu alleen de hoogte die nodig is worden gebruikt, en dan van de onderkant af naar boven.

Als ik de span met behulp van top ergens neer zou zetten, zou deze naar onder toe groter worden bij 'n grotere lettergrootte, en uiteindelijk de knop bedekken. En omdat naar die knop wordt verwezen in de vraag is dat verwarrend.

Door de span vanaf de onderkant neer te zetten zal hij omhoog groeien bij 'n grotere lettergrootte en kan hij de knop niet afdekken.

left: 184px;

Nu staan de rechterkant van de knop en de rechterkant van de span netjes op één lijn.

width: 200px;

Breedte.

height: auto;

Bij de instellingen voor alle spans binnen p#tonen heb ik 'n hoogte van 246 px opgegeven. Hier is de hoogte afhankelijk van de lettergrootte en wordt die automatisch aangepast.

border: black solid 1px;

Randje rondom de span en dus rondom de tekst daarin.

padding: 3px;

Kleine afstand tussen randje en tekst.

font-size: 18px;

In het vuur van de strijd is 'n enkele browser hier de juiste lettergrootte vreemd genoeg wat kwijtgeraakt. Daarom geef ik hier de goede lettergrootte nog 'ns op.

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

Hier wil ik gewoon de standaardletter. monospace leest niet echt lekker.

background: yellow;

Gele ondergrond.

p#tonen a span#oplos-vraag span#afdek

De span met id="afdek" binnen de span met id="oplos-vraag", die weer binnen 'n link ligt binnen de paragraaf met id="tonen".

Als je hovert over de knop, wordt de vraag of je de oplossing echt wilt zien getoond, maar ook de kleine oplossing zelf. Daardoor zou je de oplossing al ongewild kunnen zien als je alleen per ongeluk over de knop hovert.

Deze span zorgt ervoor dat de kleine oplossing wordt afgedekt. Pas als je daadwerkelijk klikt op de link wordt de kleine oplossing zichtbaar.

Voor deze span gelden ook de instellingen die voor alle spans binnen p#tonen zijn opgegeven bij p#tonen a span. En omdat het 'n geneste span is, gelden ook de instellingen die zijn opgegeven bij p#tonen a span span. Veel van de daar opgegeven instellingen worden hier overruled.

position: absolute;

Om hem op de goede plaats neer te kunnen zetten. Van zichzelf is een span een inline-element. Door hem absoluut te positioneren verandert hij in een blok-element en kan ik eigenschappen als breedte en hoogte gebruiken.

top: auto;

Eerder heb ik 'n top van -273 px opgegeven voor alle spans in p#tonen. Die moet ik hier weer uitschakelen, anders wordt deze span uitgerekt tussen die top en de bottom die ik hieronder opgeef.

bottom: 16px;

Nu staat dit 'deksel' goed over de kleine oplossing heen, zodat deze is afgedekt.

Als ik hem niet van onderaf, maar met behulp van top van bovenaf neerzet, blijken Google Chrome, Safari en Firefox 3.5 (niet Firefox 3.0) de span 3 px hoger neer te zetten dan andere browsers. Vreemd, vooral het verschil tussen de versies van Firefox. Maar als ik hem van onderaf positioneer gaat 't wel overal goed, dus opgelost.

left: 243px;

Nu staat de linkerkant van de kleine oplossing netjes gelijk met de linkerkant van de omschrijvingen.

width: 237px; height: 237px;border: 0;

Met deze breedte en hoogte staat de span met de afdekking precies tussen de groene border van de kleine oplossing.

padding: 5px;

Kleine afstand tussen buitenkant van de span en de tekst erin. (Ook op de afdekking staat een tekst.)

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

Eerder heb ik monospace opgegeven voor alle spans binnen p#tonen. Dat leest niet prettig, dus hier wil ik weer de gewone normale letters hebben.

background: yellow;

Gele achtergrond valt lekker op.

p#tonen a:hover span, p#tonen a:hover span#oplos-vraag

Als ik over 'n link binnen de paragraaf met id="tonen" hover, doe dan iets met de daarin liggende spans.

De tweede selector zegt in feite hetzelfde, maar bevat ook nog 'n extra id. Dat moet, omdat anders de selector p#tonen a span#oplos-vraag 'n hogere specificiteit (meer gewicht) heeft. Bij die selector wordt de span verborgen, en hij zou dan nooit zichtbaar kunnen worden. Nu heeft deze selector evenveel gewicht en omdat hij later in de css staat, 'wint' hij nu van de eerdere selector.

display: block;

Maak de spans, en dus de inhoud ervan, zichtbaar.

Ik maak hier dus de kleine oplossing, de vraag die bevestigend beantwoord moet worden, en de span met de afdekking zichtbaar. Daardoor staat de afdekking over de kleine oplossing heen, zodat deze nog niet te zien is. Dit voorkomt dat je de oplossing al ziet als je per ongeluk over de link hovert.

p#tonen a:active span#oplos-vraag

Doe iets met de span met id="oplos-vraag" binnen 'n link die weer binnen de paragraaf met id="tonen" ligt, maar alleen zolang ik op de link klik.

Binnen deze span staat de vraag die ik bevestigend moet beantwoorden voor de afdekking over de kleine oplossing verdwijnt, zodat ik de kleine oplossing echt kan zien.

De span met de afdekking zelf is genest binnen deze span, dus wat hier gebeurt geldt ook voor de afdekking.

display: none;

Verberg deze span. Hierdoor verdwijnen de span met de vraag én de daarin geneste span met de afdekking. De kleine oplossing is nu dus echt zichtbaar. (Dat de vraag ook verdwijnt is hier eigenlijk niet van belang, het gaat om de afdekking.)

Ik moet dus expliciet de muis indrukken om de afdekking onzichtbaar te maken. Als ik de muis niet meer indruk, zal de afdekking weer verschijnen.

In Internet Explorer 7 werkt :active foutief zoals :focus hoort te werken. Als ik op de link klik, blijft de link daardoor :active. Om dat uit te schakelen moet je ergens buiten de link klikken. Als je dat niet doet, verschijnen vraag en afdekking niet als je weer over de link hovert, omdat deze nog steeds actief is. Hier is niets aan te doen, het was 'n bewuste keuze van Microsoft om dit verkeerd te implementeren. In Internet Explorer 8 werkt dit (eindelijk) zoals het hoort te werken.

In Internet Explorer 6 speelt dit niet, want daar zie je de kleine oplossing alleen maar als je klikt op de link. Er is ook geen afdekking. Misschien had ik hoveren en de afdekking wel werkend kunnen krijgen, maar dat zou behoorlijk wat tijd en moeite kosten, en daar had ik geen zin in voor dit oude lijk. Dit is ook acceptabel, want de oplossing is zichtbaar te maken, maar pas na klikken.

div#omschrijving

De div met id="omschrijving". Binnen deze div staan alle omschrijvingen.

position: absolute;

Om op de juiste plaats neer te kunnen zetten. Ik kan nu ook de kinderen van deze div positioneren ten opzichte van deze div. Om dat te kunnen doen, moet de div zelf 'n positie hebben.

top: 10px;

Op gelijke hoogte zetten met de andere onderdelen van de pagina. Er wordt gepositioneerd ten opzichte van de eerste ouder die zelf 'n positie heeft, dat is hier div#wrapper.

left: 418px;

Precies tegen de afbeelding met het vraagteken plaatsen.

div#omschrijving table

De tabel binnen de div met id="omschrijving". De omschrijvingen en de knoppen om letters of het hele woord te tonen staan in een tabel. Dat was het makkelijkste hier, en deze puzzel werkt toch niet in spraakbrowsers en dergelijke, dus er is eigenlijk geen reden om geen tabel te gebruiken. Daarnaast kun je ook verdedigen dat dit nou precies de soort data is waar 'n tabel voor is bedoeld.

In de eerste kolom staan de getallen van de woorden.

In de tweede kolom staat de omschrijving van de woorden.

In de derde kolom staat een knop die bij hoveren de afzonderlijke letters van het woord laat zien.

In de vierde kolom staat een knop die bij hoveren het woord laat zien.

Daarnaast staan er nog wat kopjes en zo in de tabel.

border: black solid 1px;

Zwart randje rondom de hele tabel.

font-size: 0.7em;

Iets kleinere letter. Ik gebruik hier em als eenheid, zodat ook gebruikers van Internet Explorer 7 de lettergrootte kunnen veranderen. Dat heeft trouwens alleen in Internet Explorer 6 nut, in alle andere browsers werken allerlei dingen niet meer goed bij 'n andere lettergrootte.

background: white;

Witte achtergrond.

cursor: default;

Als je over 'n knop hovert en 'n venstertje opent, verandert behalve Opera elke browser de cursor in een streepje, zoals gebruikelijk boven tekst. Dat is hier heel verwarrend, dus ik houd boven de tabel gewoon de standaardcursor.

td

De cellen in de tabel.

padding: 0 2px;

De meeste browsers regelen automatisch iets met padding. Ik stel het zelf in, zodat het overal hetzelfde is.

Omdat geen waarde is opgegeven voor onder en links, krijgen die automatisch dezelfde waarde als boven en links. Hier staat dus eigenlijk 0 2px 0 2px in de volgorde boven - rechts - onder - links. Boven en onder geen padding, links en rechts 2 px. Dit levert wat afstand op tussen de diverse onderdelen van de tabel.

div#omschrijving td.kopje

De cellen met class="kopje" binnen de div met id="omschrijving". In deze cellen staan de kopjes 'Omschrijvingen' en 'TOON'. Ik zou ook 'n <h3> of zo kunnen gebruiken, maar ik zie daar hier de meerwaarde niet van.

font-size: 1.3em;

Iets grotere letter. Ik gebruik em als eenheid, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen. Dat heeft trouwens alleen in Internet Explorer 6 nut, in alle andere browsers werken allerlei dingen niet meer goed bij 'n andere lettergrootte.

font-weight: bold

Vette letter.

text-align: center;

De kopjes bestrijken elk twee kolommen (met behulp van colspan in de html). Tekst horizontaal in het midden zetten.

div#omschrijving td.richting, div#omschrijving td:first-child

De cellen met class="richting" binnen de div met id="omschrijving". Dit zijn de cellen waar de kopjes 'horizontaal' en 'verticaal' in staan.

Daarnaast alle cellen binnen de div met id="omschrijving", maar alleen als het de eerste cel binnen een <tr> is. Omdat Internet Explorer 6 :first-child niet kent, negeert die deze css.

font-weight: bold;

Vet maken. Omdat de getallen van de woorden in de eerste <td> staan, worden de getallen vet. Behalve in Internet Explorer 6 dus.

div#omschrijving td span.toon-letter, div#omschrijving td span.toon-woord

De spans met class="toon-letter" en de spans met class="toon-woord" binnen een cel in de div met id="omschrijving". Binnen .toon-letter liggen de knoppen die bij hoveren erover de afzonderlijke letters latten zien, binnen .toon-woord de knoppen die bij hoveren het hele woord laten zien.

display: block;

Een span is van zichzelf een inline-element. In deze spans staat alleen een vraagteken. Daardoor worden ze heel smal. Door er een blok-element van te maken, vult het automatisch de hele breedte van zijn ouder. Dat is hier de <td> waar hij in staat.

Bovenaan in dezelfde kolommen als deze span staan twee woorden: 'letter' en 'woord'. Omdat deze de breedste woorden uit deze kolommen zijn, bepalen deze de breedte van de <td>. Omdat de spans zijn veranderd in een blok-element, worden ze ook even breed als de <td>, dus even breed als 'letter' en 'woord'. Als ik ze niet in 'n blok-element verander, worden ze niet breder dan nodig is om 'n vraagteken weer te geven, zoals hiernaast is te zien.

border: black solid 1px;

Zwart randje rondom de spans met de vraagtekens.

font-size: 0.8em;

Iets groter dan de letters van de omschrijvingen. Ik gebruik em als eenheid, zodat ook gebruikers van Internet Explorer de lettergrootte kunnen veranderen. Dat heeft trouwens alleen in Internet Explorer 6 nut, in alle andere browsers werken allerlei dingen niet meer goed bij 'n andere lettergrootte.

text-align: center;

Vraagtekens horizontaal in het midden zetten.

background: #dff;

Lichtblauwe achtergrond.

div#omschrijving td span.toon-letter span

De spans die binnen een span met class="toon-letter", die zelf weer binnen 'n cel ligt, die weer binnen de div met id="omschrijving" ligt. Binnen deze spans liggen de witte vraagtekens en letters op 'n zwarte achtergrond, die zichtbaar worden bij hoveren over het vraagteken in de derde kolom (de kolom onder 'TOON letter').

Wat ik hier opgeef geldt voor alle spans binnen span.toon-letter. Later geef ik aparte instellingen voor de verschillende soorten spans die weer hierbinnen liggen.

display: none;

Verberg de spans en dus de inhoud.

position: absolute;

Om op de juiste plaats neer te kunnen zetten. Een van span is van zichzelf een inline-element. Door hem absoluut te positioneren verandert hij in een blok-element en kan ik eigenschappen als breedte gebruiken.

Er wordt gepositioneerd ten opzichte van de eerste ouder die zelf een positie heeft, dat is hier div#omschrijving.

font-size: 28px;

Behoorlijk grote letter.

color: white;

Witte tekst.

background: black;

Zwarte achtergrond.

div#omschrijving td span.toon-letter:hover span.vraagtekens

Als ik over 'n span met class="toon-letter" hover die binnen 'n cel ligt, die weer binnen de div met id="omschrijving" ligt, doe dan iets met de daarin liggende spans met class="vraagtekens".

In normale mensentaal: als ik over een van de knoppen onder 'TOON letter' in de derde kolom van de tabel hover, doe dan iets met de binnen die knop liggende span.vraagtekens.

span.vraagtekens is een span waarbinnen weer 'n span voor elke letter en vraagteken ligt. Deze 'overkoepelende' span regelt het totaal van alle letters en vraagtekens die bij één woord horen.

Voor deze span gelden ook de instellingen voor álle spans binnen span.toon-letter zoals opgegeven bij div#omschrijving td span.toon-letter span.

display: block;

Maak de span, en dus de inhoud daarvan, zichtbaar.

bottom: 0;

Helemaal onderaan zetten. Omdat er wordt gepositioneerd ten opzichte van div#omschrijving, de eerste ouder die zelf een positie heeft, is dat dus gelijk met de onderkant van de omschrijvingen.

width: 40px;

40 px breed maken.

margin-left: -1px;

Deze span heeft 'n zwarte achtergrond. Als ik geen horizontale positie opgeef, komt die zwarte achtergrond precies naast de 1 px brede borders van de blauwe knoppen te staan. Dat is niet mooi, want dan heb je 'n lange zwarte achtergrond van deze span, en 'n border die er bij elke knop 1 px naast komt te staan, zoals hiernaast is te zien.

right of left zou ik kunnen gebruiken, maar er wordt gepositioneerd ten opzichte van div#omschrijving, en de randen daarvan zijn nogal 'n eind uit de buurt. Dan moet ik gaan rekenen en dan word ik moe.

Het kan veel simpeler: gewoon 'n negatieve marge van 1 px naar links geven.

height: 432px;

Met deze hoogte wordt de span, en dus de zwarte achtergrond, precies even hoog als div#omschrijving.

z-index: 20;

Als ik over 'n bepaalde knop hover, opent de span met vraagtekens en letters. Die span komt gedeeltelijk over andere knoppen te staan. Maar omdat die knoppen in de html deels ná de knop komen waar ik over hover, verdwijnt de span onder die knoppen, zoals hiernaast is te zien.

Door een z-index te geven 'wint' de span die bij hoveren opent van de knoppen die later in de html staan.

div#omschrijving td span.toon-letter span.vraagteken

De spans met class="vraagteken" die weer binnen 'n span met class="toon-letter" liggen, die weer binnen 'n cel die uiteindelijk binnen de div met id="omschrijving" ligt.

(Je kunt wat bytes uitsparen door de selector zo kort mogelijk te maken. Maar dan wordt het helemaal onduidelijk waar die bij hoort. Ik vind de bytes die ik uitspaar niet opwegen tegen de toegenomen onduidelijkheid.)

Deze spans staan binnen span#vraagtekens, dus de selector had ook kunnen zijn: div#omschrijving td span.toon-letter span.vraagtekens span.vraagteken, maar dat vond zelfs ik wel erg lang worden.

Binnen deze span staat het grote witte vraagteken dat bij hoveren over 'n knop in de derde kolom (onder 'TOON letter') verschijnt.

Voor deze span gelden ook de instellingen voor álle spans binnen span.toon-letter zoals opgegeven bij div#omschrijving td span.toon-letter span.

display: block;

Van zichzelf is een span een inline-element. Door er een blok-element van te maken kan ik eigenschappen als breedte en hoogte gebruiken.

Deze span moet alleen zichtbaar worden als ik over 'n knop uit de derde kolom (onder 'TOON letter') hover. Toch hoef ik hem niet te verbergen. Deze span is een kind van span#vraagtekens, en die wordt in z'n geheel verborgen bij div#omschrijving td span.toon-letter span. Pas bij hoveren over de knop wordt span#vraagtekens weer zichtbaar. En dat geldt dus ook voor de inhoud van span#vraagtekens, waaronder deze span.

position: relative;

Binnen deze span ligt weer 'n span. Dat is de span waarbinnen de grote witte letter staat. Om die te kunnen positioneren ten opzichte van deze span, moet ik hem 'n positie geven, ook al vul ik daar verder niets bij in.

height: 32px;

Bij deze hoogte passen er precies 13 letters onder elkaar, het maximale aantal dat in deze puzzel voorkomt. Dit geeft de mogelijkheid om voor elke letter eerst 'n vraagteken te tonen.

Ik hoef geen breedte op te geven, want 'n blok-element krijgt normaal genomen automatisch dezelfde breedte als z'n ouder.

border-bottom: white solid 1px;

Witte lijn aan de onderkant. Omdat elke vraagteken/letter z'n eigen span heeft, worden alle vraagtekens/letters dus gescheiden door 'n witte lijn.

div#omschrijving td span.toon-letter span.vraagteken:hover span

Doe iets met 'n span die binnen 'n span met class="vraagteken" ligt, die weer binnen 'n span met class="toon-letter" ligt, die weer binnen 'n cel ligt die uiteindelijk binnen de div met id="omschrijving" ligt, maar alleen als ik over span.vraagteken hover.

span.vraagteken is de span waarbinnen het grote witte vraagteken staat. Deze vraagtekens worden zichtbaar als je over 'n knop uit de derde kolom (onder 'TOON letter') hovert.

Binnen span.vraagteken ligt weer 'n span, en binnen deze span staat de letter. Deze wordt pas zichtbaar als je over de span.vraagteken (met het daarin zittende vraagteken) hovert die bij de betreffende letter hoort. Op deze manier wordt steeds maar één letter gelijktijdig zichtbaar en zie je niet per ongeluk voortijdig het hele woord.

Voor deze span gelden ook de instellingen voor álle spans binnen span.toon-letter zoals opgegeven bij div#omschrijving td span.toon-letter span.

display: block;

'n Span is van zichzelf 'n inline-element. Door er 'n blok-element van te maken kan ik eigenschappen als breedte en hoogte gebruiken.

top: 0;

Er wordt gepositioneerd ten opzichte van de eerste ouder met een positie, dat is hier span.vraagteken, de rechtstreekse ouder van deze span.

Als ik geen positie op zou geven, zou deze span met letter gewoon onder de span met het vraagteken worden gezet. Nu komt de span op gelijke hoogte als de span met het vraagteken, dus de letter komt over het vraagteken te staan.

width: 40px;

Een blok-element krijgt automatisch dezelfde breedte als z'n ouder, maar niet als het absoluut is gepositioneerd. En dat is gebeurd bij de instellingen voor álle spans binnen span.toon-letter. Daarom moet ik een breedte opgeven, anders wordt de span niet breder dan nodig is om de letter weer te geven. De 'D' op de afbeelding hiernaast bedekt daardoor niet het hele vraagteken. Als ik de span even breed maak als z'n ouder, bedekt de 'D' (en andere letters natuurlijk) wel het hele vraagteken.

height: 32px;

Als ik geen hoogte opgeef, wordt de span iets te hoog in sommige browsers. Kennelijk levert de combinatie van lettergrootte, positie, enz. afrondingsverschillen of zo op. De witte lijn aan de onderkant wordt dan net bedekt en is daardoor niet meer zichtbaar. Als ik gewoon 'n hoogte opgeef is 't opgelost.

div#omschrijving td span.toon-woord

De spans met class="toon-woord" binnen een cel die weer binnen de div met id="omschrijving" ligt. Binnen deze span staan de vraag die bevestigend beantwoord moet worden en het woord dat dan wordt getoond.

Voor deze span zijn de meeste instellingen al opgegeven bij div#omschrijving td span.toon-letter, div#omschrijving td span.toon-woord.

Deze span vormt de blauwe knop in de vierde kolom van de tabel, onder 'TOON woord'.

position: relative;

Om kinderen van deze div te kunnen positioneren ten opzichte van deze div moet hij een positie hebben, ook al vul ik daar verder niets bij in.

div#omschrijving td span.toon-woord span

De spans binnen de spans met class="toon-woord", die weer binnen 'n tabel liggen die binnen de div met id="omschrijving" ligt.

Het gaat hier om 'n paar verschillende soorten span. Ik geef hier de dingen op die voor álle spans binnen span.toon-woord gelden, later geef ik dan aparte instellingen voor de afzonderlijke soorten op.

display: none;

Verberg de spans en dus alles wat erin zit.

position: absolute;

Om op 'n bepaalde plaats neer te kunnen zetten. Een span is een inline-element. Door hem absoluut te positioneren verandert hij in een blok-element, waardoor ik eigenschappen als breedte en hoogte kan gebruiken.

color: white;

Witte tekst.

background: black;

Zwarte achtergrond.

div#omschrijving td span.toon-woord:hover span.vraag-woord

Doe iets met de spans met class="vraag-woord" die binnen 'n span met class="toon-woord" ligt, die zelf weer binnen 'n cel ligt die binnen de div met id="omschrijving" ligt. Maar alleen als ik over span.toon-woord hover.

In normale mensentaal: doe iets met span.vraag-woord als ik over 'n knop in de vierde kolom, die onder 'TOON woord', hover.

Binnen span.vraag-woord zit de vraag die bevestigend beantwoord moet worden om het woord te tonen. Dat woord zelf zit ook binnen deze span, in een geneste span.

Voor span.vraag-woord gelden ook de algemene instellingen voor álle spans binnen span.toon-woord zoals opgegeven bij div#omschrijving td span.toon-woord span.

display: block;

Bij de instellingen voor alle spans binnen span.toon-woord is de span onzichtbaar gemaakt. Maak hem nu weer zichtbaar.

top: -10px;

Dit is ten opzichte van de eerste ouder met een positie, dat is hier span.toon-woord. Als ik hier niets opgeef, komt de vraag gelijk onder de knop te staan. Dat vind ik wat verwarrend, daarom zet ik hem iets hoger, zodat hij de knop waar hij bij hoort afdekt.

right: -1px;

Rechterkant van de span met de vraag gelijk zetten met de rechterkant van de knop waar hij bij hoort.

width: 300px;

Breedte.

padding: 3px;

Kleine afstand tussen tekst en rand van de span.

font-size: 1.8em;

Bij div#omschrijving table heb ik 'n tamelijk kleine lettergrootte opgegeven. Hier wil ik weer 'n normale letter hebben. Omdat ik uit moet gaan van die tamelijk kleine letter, moet ik hem dus tamelijk fors vergroten om uiteindelijk 'n normale grootte te krijgen.

z-index: 20;

Om te voorkomen dat knoppen die lager in de html staan over de vraag heen komen te staan. Uitgebreidere uitleg bij z-index: 20.

De z-index in Internet Explorer 7 is, heel netjes gezegd, 'n beetje buggy. Zelfs het inschakelen van 'n magneet bracht Internet Explorer 7 er niet toe dit goed af te handelen, dus bij dat eigenwijze kreng staan de knoppen wel over de span heen. Daarom zet ik met css speciaal voor Internet Explorer 7 de tekst voor die sukkel wat opzij.

div#omschrijving td span.toon-woord span.vraag-woord-doorgaan

De spans met class="vraag-woord-doorgaan", die binnen 'n span met class="toon-woord" liggen, die weer binnen 'n cel binnen de div met id="omschrijving" ligt.

Dit is 'n geneste span binnen span.vraag-woord. De volledige selector zou kunnen zijn div#omschrijving td span.toon-woord span.vraag-woord span.vraag-woord-doorgaan. Maar dat vind zelfs ik te lang.

Bij hoveren over de knop in de vierde kolom, die onder 'TOON woord', verschijnt in eerste instantie de vraag of je door wilt gaan. Als je dat wilt, moet je vervolgens de cursor naar deze span bewegen. Pas dan wordt het woord getoond. Dat voorkomt dat je het woord al ziet als je per ongeluk over de knop hovert. Deze handeling is dus expres wat lastig gemaakt.

Voor span.vraag-woord-doorgaan gelden ook de algemene instellingen voor álle spans binnen span.toon-woord zoals opgegeven bij div#omschrijving td span.toon-woord span.

display: block;

Deze span mag alleen zichtbaar worden als ik over 'n knop uit de vierde kolom uit de tabel (die onder 'TOON woord') hover. Toch hoef ik hem niet te verbergen, want bij de algemene instellingen voor alle spans in span.toon-woord is zijn ouder span.vraag-woord verborgen, en die wordt pas zichtbaar bij hoveren over de knop. En omdat dit 'n kind is van span.vraag-woord, wordt ook deze span dus pas zichtbaar bij hoveren over die knop.

right: 0;

Er wordt gepositioneerd ten opzichte van de eerste ouder met een positie, dat is hier span.vraag-woord. Zet de rechterkant gelijk daarmee.

width: 298px;

De ouder van deze span is 300 px breed. Maar deze span krijgt links en rechts een border van 1 px breed. Samen met deze border levert deze breedte ook 300 px op.

border: black solid 1px;

Zwart randje om de span.

padding: 3px;

Kleine afstand tussen rand van de span en tekst.

color: black;

De ouder van deze span span.vraag-woord heeft een witte letterkleur gekregen. Hier wil ik weer zwart.

background: yellow;

Gele achtergrond.

div#omschrijving td span.toon-woord span.vraag-woord-doorgaan:hover span.woord

Binnen span.woord ligt het woord dat getoond moet worden. Doe iets met deze span als ik over z'n ouder, 'n span met class="vraag-woord-doorgaan", hover. Die span moet zelf weer binnen 'n span met class="toon-woord" liggen, en die weer binnen 'n cel binnen de div met id="omschrijving".

Als ik over 'n knop uit de vierde kolom, die onder 'TOON woord', hover, opent in eerste instantie alleen maar 'n vraag. Pas als ik de cursor naar het onderste deel van de vraag beweeg opent het te tonen woord. Dat voorkomt dat je het per ongeluk ziet als je even over de knop hovert. Dat onderste deel van de vraag zit in span.vraag-woord-doorgaan. Dus pas als ik daaroverheen hover wordt het te tonen woord zichtbaar.

Ik geef hier de instellingen op die voor alle spans met class="woord" gelden. Later geef ik aparte instellingen voor de individuele spans op.

Voor span.woord gelden ook de algemene instellingen voor álle spans binnen span.toon-woord zoals opgegeven bij div#omschrijving td span.toon-woord span.

display: block;

Bij de algemene instellingen voor alle spans binnen span.toon-woord heb ik deze span onzichtbaar gemaakt. Nu mag hij zichtbaar worden.

border: yellow solid 1px;

Gele border om het woord.

padding: 3px;

Kleine afstand tussen letters en gele rand.

font-size: 24px;

Letter even groot maken als de letters in de puzzel zelf.

font-family: monospace;

De 'I' moet evenveel ruimte krijgen als de 'M'. Ik laat het aan de browser over om te bepalen welke letter hij hiervoor wil gebruiken.

letter-spacing: 16px;

Zelfde letter-spacing als in de puzzel zelf.

line-height: 24px;

Hierboven heb ik 'n lettergrootte van 24 px opgegeven. Dat geeft automatisch ook min of meer de juiste hoogte voor deze spans. Maar als ik ook nog 'n regelhoogte opgeef die even hoog is als de span moet zijn, worden de letters in alle browsers verticaal op de goede hoogte gezet: in het midden van de 24 px.

Deze regelhoogte is alleen de juiste voor de horizontale woorden. Voor de verticale geef ik later 'n andere op.

color: white; background: black;

Witte letters op zwarte achtergrond.

div#omschrijving td span#toon-woord-7 span.vraag-woord-doorgaan span.woord

De span met class="woord" binnen de span met class="vraag-woord-doorgaan" die weer binnen de span met id="toon-woord-7" ligt, die weer binnen 'n cel binnen de div met id="omschrijving" ligt. Binnen span.woord zit het te tonen woord.

Voor deze span.woord gelden ook de algemene instellingen voor alle spans binnen span.vraag-woord-doorgaan zoals opgegeven bij div#omschrijving td span.toon-woord span.vraag-woord-doorgaan:hover span.woord.

De spans met class="toon-woord" hebben niet alleen die class, maar elk ook 'n id. Dat is hier "toon-woord-7". Deze hoort bij woord nummer 7, maar dat had je misschien al bedacht. Hierdoor kan ik voor elke span met een te tonen woord ook aparte instellingen opgeven naast de algemene die voor alle spans met 'n te tonen woord gelden.

top: -50px; left: -471px;

Zet de span en dus het woord daarin 50 px omhoog en 471 px naar rechts. Er wordt gepositioneerd ten opzichte van de eerste ouder die zelf 'n positie heeft, dat is hier span.vraag-woord-doorgaan. Via uitproberen bleek dat deze positie de beste plaats is in alle browsers. Het is wel 'n compromis: als hij in de ene browser perfect staat, wijkt hij in de andere iets te veel af.

width: 172px;

Bij de algemene instellingen voor deze spans is 'n padding van 3px en 'n border van 1 px opgegeven. De totale breedte is dus 1 + 3 + 172 + 3 + 1 = 180 px, precies de breedte van 'n woord van 6 letters.

div#omschrijving td span#toon-woord-8 span.vraag-woord-doorgaan span.woord {top: -67px; left: -263px; width: 174px;}

t/m

div#omschrijving td span#toon-woord-22 span.vraag-woord-doorgaan span.woord {top: 63px; left: -263px; width: 174px;}

Zelfde als bij div#omschrijving td span.toon-woord-7 span.vraag-woord-doorgaan span.woord, maar nu voor de andere horizontale woorden, dus met andere waarden omdat deze op een andere plaats moeten staan en een andere lengte hebben.

Het getal achter toon-woord- geeft aan bij welk woord de div hoort.

De woorden aan de linkerkant zijn 2 px breder dan je zou verwachten, want de woorden links blijken gemiddeld beter uit te komen als ik ze 2 px langer maak. Ook dit is weer een compromis om het acceptabel in alle browsers te krijgen.

div#omschrijving td span#toon-woord-1 span.vraag-woord-doorgaan span.woord

De span met class="woord" binnen de span met class="vraag-woord-doorgaan" die weer binnen de span met id="toon-woord-1" ligt, die weer binnen 'n cel binnen de div met id="omschrijving" ligt. Binnen span.woord zit het te tonen woord.

Voor deze span.woord gelden ook de algemene instellingen voor alle spans binnen span.vraag-woord-doorgaan zoals opgegeven bij div#omschrijving td span.toon-woord span.vraag-woord-doorgaan:hover span.woord.

De spans met class="toon-woord" hebben niet alleen die class, maar elk ook 'n id. Dat is hier "toon-woord-1". Deze hoort bij woord nummer 1. Hierdoor kan ik voor elke span met een te tonen woord ook aparte instellingen opgeven naast de algemene die voor alle spans met 'n te tonen woord gelden.

top: -300px; left: -442px;

Zet de span en dus het woord daarin 300 px omhoog en 442 px naar rechts. Er wordt gepositioneerd ten opzichte van de eerste ouder die zelf 'n positie heeft, dat is hier span.vraag-woord-doorgaan. Via uitproberen bleek dat deze positie de beste plaats is in alle browsers. Het is wel 'n compromis: als hij in de ene browser perfect staat, wijkt hij in de andere iets te veel af.

width: 20px;

Het gaat hier om de verticale woorden, daarom moet de span maar 'n kleine breedte hebben. Links komt nog 'n padding van 7 px en rechts en links 'n border van 1px. De totale breedte wordt dus 29 px. Dat blijkt beter uit te komen dan 30 px.

Bij de verticale woorden heb ik 'n spatie tussen de letters gezet. Hierdoor denkt de browser, die gewoon niet zo slim is, dat er 'n nieuw woord begint en zal hij de volgende letter dus netjes op de volgende regel zetten. De letters komen dus onder elkaar te staan en ziedaar: ik heb mijn verticale woord.

height: 114px;

Dit woord is vier letters lang. Samen met de border boven en onder kom ik maar aan 116 px, terwijl je 4 x 30 = 120 px zou verwachten. Ook dit is weer 'n compromis tussen de verschillende browsers. Bij sommige andere verticale woorden heb ik weer 'n andere kleine afwijking. Gewoon 'n kwestie van uitproberen.

padding-left: 7px;

Om de letters horizontaal in het midden te krijgen moet ik ze iets naar rechts schuiven.

line-height: 30px;

De letters worden automatisch halverwege de regelhoogte geplaatst.

div#omschrijving td span#toon-woord-2 span.vraag-woord-doorgaan span.woord {top: -318px; left: -382px; width: 20px; height: 388px; padding-left: 7px; line-height: 30px;}

t/m

div#omschrijving td span#toon-woord-20 span.vraag-woord-doorgaan span.woord {top: -182px; left: -143px; width: 20px; height: 116px; padding-left: 7px; line-height: 30px;}

Zelfde als bij div#omschrijving td span.toon-woord-1 span.vraag-woord-doorgaan span.woord, maar nu voor de andere verticale woorden, dus met andere waarden omdat deze op een andere plaats moeten staan en een andere lengte hebben.

Het getal achter toon-woord- geeft aan bij welk woord de div hoort.

Speciaal voor Internet Explorer 6

<!--[if IE 6]> <style> .hide-ie-6, div#omschrijving td span.toon-letter, div#omschrijving td span.toon-woord {display: none;} p#wrapper-help a:hover {cursor: pointer;} div.hor {margin-top: 1px;} p#tonen {padding: 6px 0;} p#tonen a {float: none;} p#tonen a span {display: block; top: -315px; visibility: hidden;} p#tonen a span span {position: relative; top: 1px; left: 0; height: 19px; margin-top: -1px;} p#tonen a span span span {line-height: 18px;} p#tonen span.nr {font-size: 8px;} p#tonen a:active span {visibility: visible;} p#tonen span#oplos-vraag {visibility: hidden;} div.vert span {top: 0; width: 29px; border-width: 0 0 1px 0;} </style> <![endif]-->

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

De style voor Internet Explorer moet ná de normale komen, omdat de opdrachten voor Internet Explorer dan over de normale heen gaan.

Dit stukje geldt voor Internet Explorer 6, 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 6]> <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 6 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 6]> en <![endif]--> precies zo worden overgenomen zoals ze hier staan.

.hide-ie-6, div#omschrijving td span.toon-letter, div#omschrijving td span.toon-woord

In Internet Explorer 6 zijn sommige dingen gewoon niet werkend te krijgen, of alleen ten koste van heel veel moeite, wat ik die oude browser gewoon niet meer waard vind. Daarom verberg ik sommige onderdelen gewoon voor deze browser.

display: none;

Verberg.

Met de class .hide-ie-6 verberg ik de hele projectie van de oplossing en de kopjes 'TOON', 'letter' en 'woord' uit de omschrijvingen.

Om het tonen van afzonderlijke letters en woorden helemaal te verbergen, heeft de class hide-ie-6 te weinig specificiteit (gewicht). Ik heb in de algemene css selectors gebruikt die 'winnen' van de class hide-ie-6. Daarom heb ik nog twee langere selectors met meer specificiteit nodig om tonen van letters en woorden te voorkomen.

p#wrapper-help a:hover

Als ik over de link in de paragraaf met id="wrapper-help" hover. Binnen deze link zit het hulpschermpje.

cursor: pointer;

In de algemene css houd ik de cursor gewoon standaard, omdat dit geen echte link is. Maar dan werkt hoveren niet in Internet Explorer 6, dus voor die browser verander ik de cursor wel in 'n handje.

div.hor

De divs met class="hor". Dit zijn de divs die bij de achtergrond van de horizontale woorden horen.

margin-top: 1px;

Om wat voor reden dan ook krijg je 'n ongelijkmatige horizontale zwarte lijn bij de instellingen die voor alle andere browsers wel werken. top is al in gebruik in de algemene css, maar ik kan ze ook omlaag zetten met behulp van 'n marge.

div.vert span

De spans binnen de divs met class="vert". De spans binnen de divs met class="vert". Deze spans zorgen voor de horizontale lijntjes tussen de letters van de verticale woorden. Ook staan sommige getallen binnen deze spans.

top: 0;

Kleine correctie om ongelijke horizontale lijnen te voorkomen.

p#tonen

De paragraaf met id="tonen". De paragraaf waar de opgeloste puzzel in het klein in staat.

padding: 6px 0;

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

Bij Internet Explorer 6 verdwijnen de border boven- en onderaan de knop met 'Toon oplossing'. Als ik 'n padding van 6 px aan boven- en onderkant geef komen ze op wonderbaarlijke wijze weer terug.

p#tonen a

De links in de paragraaf met id="tonen". Hier is dat alleen maar de link met de knop met 'Toon oplossing', want de link met de knop met 'Projecteer oplossing' is verborgen voor deze browser.

float: none;

In de algemene css wordt deze link naar rechts gefloat. Hier moet dat niet. In de algemene css worden inline-elementen zoals links in p#tonen horizontaal gecentreerd. Daardoor komt deze link met de daarin zittende knop horizontaal midden onder de puzzel te staan.

p#tonen a span

De spans binnen 'n link die weer binnen de paragraaf met id="tonen" ligt. Dit zijn de spans waarbinnen de kleine oplossing van de puzzel zit.

display: block;

In de algemene css worden deze spans onzichtbaar gemaakt met behulp van display: none, maar in Internet Explorer 6 zijn ze dan niet meer zichtbaar te krijgen.

top: -315px;

In de algemene css staat -273 px, maar dat is te laag voor Internet Explorer 6.

visibility: hidden;

Omdat display: none; niet gebruikt kan worden, gebruik ik voor deze browser deze eigenschap. Die blijkt wel te werken.

p#tonen a span span

De spans die zelf binnen 'n span staan, die weer binnen 'n link staat, die uiteindelijk binnen de paragraaf met id="tonen" staat.

Elke horizontale regel van de kleine oplossing staat binnen zo'n geneste span.

In Internet Explorer 6 staan kieren en ongelijke lijnen in de kleine oplossing. Dat ga ik hier corrigeren.

Als je me nou vraagt waarom dit werkt heb ik 'n heel duidelijk, technisch goed onderbouwd antwoord, wat daardoor misschien wat moeilijk te begrijpen is: omdat Internet Explorer 6 op de vreemdste momenten de hik heeft. Oftewel: geen flauw idee. Maar 't werkt, en daar gaat 't maar om.

position: relative;

In de algemene css is 'n position: static; gegeven aan deze spans. Maar om te kunnen corrigeren verander ik dat voor Internet Explorer 6 in 'n relatieve positie.

top: 1px;

1 px omlaag zetten.

left: 0;

In de algemene css is left: 418px; opgegeven bij de instellingen voor alle spans binnen p#tonen. Dat moet ik hier weer uitschakelen, anders komen deze regels ook 418 px naar links te staan. Wat 'n beetje lastig leest, buiten 't venster van de browser...

height: 19px;

1 px hoger dan voor de andere browsers.

margin-top: -1px;

Weer 1 px terug omhoog zetten.

Ik mag hangen als ik begrijp wat er nou gebeurt als ik 't eerst 1 px omlaag zet met top: 1px; en hier weer die zelfde px omhoog. Maar 't werkt. Ik kan er alleen maar uit afleiden dat Internet Explorer 6 kennelijk gevoelig is voor 't placebo-effect.

p#tonen a span span span

De spans die binnen 'n span liggen die zelf ook weer binnen 'n span ligt. Dat geheel moet binnen 'n link in de paragraaf met id="tonen" liggen. Dit zijn de spans waarin de getallen en letters van de kleine oplossing staan.

line-height: 18px;

De regelhoogte van 22 px uit de algemene css is te groot en blijkt de oplossing in een tweede puzzel te veranderen.

p#tonen span.nr

De spans met class="nr" binnen de paragraaf met id="tonen". Dit zijn de spans waarbinnen de nummer van de kleine oplossing staan.

font-size: 8px;

De lettergrootte uit de algemene css is iets te klein, dan zijn de cijfers echt niet meer leesbaar.

p#tonen a:active span

Doe iets met de spans binnen de link binnen de paragraaf met id="tonen", maar alleen als ik op de link de muis indruk.

Omdat :active door Microsoft in Internet Explorer 6 (en 7) foutief is geïmplementeerd, werkt dit ook als de link focus heeft. Nadat de eerste keer op de link is geklikt, blijft de oplossing daardoor zichtbaar, tot buiten de link is geklikt. Hier is niets aan te doen: het was een bewuste keuze van Microsoft om dit foutief te implementeren.

visibility: visible;

Bij p#tonen a span zijn, speciaal voor Internet Explorer 6, deze spans onzichtbaar gemaakt met visibility: hidden;, omdat display: none; niet werkt voor deze prachtbrowser. Maak ze weer zichtbaar.

p#tonen span#oplos-vraag

De span met id="oplos-vraag" binnen de paragraaf met id="tonen". Dit is de vraag of je de kleine oplossing écht wilt zien. Als bevestiging moet je nog 'ns extra klikken.

visibility: hidden;

Omdat dit bij Internet Explorer 6 niet (zonder heel veel extra moeite) goed werkend was te krijgen, schakelen we de hele vraag gewoon uit door de span waar de vraag in staat onzichtbaar te maken.

Speciaal voor Internet Explorer 7

<!--[if IE 7]> <style> p#wrapper-help a:hover {cursor: pointer;} p#tonen {left: -169px;} p#tonen a span#oplos-vraag {top: -91px; bottom: auto;} p#tonen a span#oplos-vraag span#afdek {top: -174px;} div#omschrijving td span.toon-letter:hover span.vraagtekens {right: 35px;} div#omschrijving td span.toon-letter span.vraagteken:hover span {left: 0;} div#omschrijving td span.toon-woord span.vraag-woord-doorgaan {text-align: left; top: 48px;} div#omschrijving td span#toon-woord-12 span.vraag-woord-doorgaan span.woord, div#omschrijving td span#toon-woord-17 span.vraag-woord-doorgaan span.woord, div#omschrijving td span#toon-woord-20 span.vraag-woord-doorgaan span.woord {margin-top: -2px;} </style> <![endif]-->

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

p#wrapper-help a:hover

Als ik over de link in de paragraaf met id="wrapper-help" hover. Binnen deze link zit het hulpschermpje.

cursor: pointer;

In de algemene css houd ik de cursor gewoon standaard, omdat dit geen echte link is. Maar dan werkt hoveren niet in Internet Explorer 7, dus voor die browser verander ik de link wel in 'n handje.

p#tonen

De paragraaf met id="tonen". De paragraaf waar de opgeloste puzzel in het klein in staat.

left: -169px;

Om een of andere reden wordt deze paragraaf veel te breed in Internet Explorer 7, waardoor de inhoud ervan op de verkeerde plaats komt te staan. De simpelste oplossing is om de hele handel 'n eind naar links terug te zetten.

p#tonen a span#oplos-vraag

De span met id="oplos-vraag" binnen 'n link die weer binnen de paragraaf met id="tonen" ligt. Dit is de span waarbinnen de vraag ligt die bevestigend beantwoord moet worden voordat de kleine oplossing echt wordt getoond.

top: -91px;

In de algemene css wordt deze span, en dus ook de daarin zittende span met de afdekking, gepositioneerd vanaf de onderkant. Dat gaat niet goed in Internet Explorer 7, daarom positioneer ik voor deze browser vanaf de bovenkant.

bottom: auto;

Maar dan moet ik de positionering vanaf de onderkant wel uitschakelen.

div#omschrijving td span.toon-letter:hover span.vraagtekens

Als ik over 'n span met class="toon-letter" hover die binnen 'n cel ligt, die weer binnen de div met id="omschrijving" ligt, doe dan iets met de daarin liggende spans met class="vraagtekens".

In normale mensentaal: als ik over een van de knoppen onder 'TOON letter' in de derde kolom van de tabel hover, doe dan iets met de binnen die knop liggende span.vraagtekens.

span.vraagtekens is een span waarbinnen weer 'n span voor elke letter en vraagteken ligt. Deze span regelt het totaal van alle letters en vraagtekens die bij één woord horen.

right: 35px;

De witte vraagtekens op zwarte achtergrond worden op de verkeerde plaats getoond. Dit corrigeert dat.

div#omschrijving td span.toon-letter span.vraagteken:hover span

Doe iets met 'n span die binnen 'n span met class="vraagteken" ligt, die weer binnen 'n span met class="toon-letter" ligt, die weer binnen 'n cel ligt die uiteindelijk binnen de div met id="omschrijving" ligt, maar alleen als ik over span.vraagteken hover.

span.vraagteken is de span waarbinnen het grote witte vraagteken staat. Deze vraagtekens worden zichtbaar als je over 'n knop uit de derde kolom (onder 'TOON letter') hovert.

Binnen span.vraagteken ligt weer 'n span, en binnen deze span staat de letter. Deze wordt pas zichtbaar als je over de span.vraagteken (met het daarin zittende vraagteken) hovert die bij de betreffende letter hoort. Op deze manier wordt steeds maar één letter gelijktijdig zichtbaar en zie je niet per ongeluk voortijdig het hele woord.

left: 0;

De letters worden foutief naast de vraagtekens geplaatst. Dit corrigeert dat, nu dekken ze het vraagteken af.

div#omschrijving td span.toon-woord span.vraag-woord-doorgaan

De spans met class="vraag-woord-doorgaan", die binnen 'n span met class="toon-woord" liggen, die weer binnen 'n cel binnen de div met id="omschrijving" ligt.

Dit is 'n geneste span binnen span.vraag-woord. De volledige selector zou kunnen zijn div#omschrijving td span.toon-woord span.vraag-woord span.vraag-woord-doorgaan. Maar dat vind zelfs ik te lang.

Bij hoveren over de knop in de vierde kolom, die onder 'TOON woord', verschijnt in eerste instantie de vraag of je door wilt gaan. Als je dat wilt, moet je vervolgens de cursor naar deze span bewegen. Pas dan wordt het woord getoond. Dat voorkomt dat je het woord al ziet als je per ongeluk over de knop hovert.

text-align: left;

Doordat z-index zo ongelooflijk buggy is in Internet Explorer 7, lukt het niet om deze span en dus de daarin zittende tekst boven de andere knoppen te krijgen. Daarom zet ik de tekst naar links. De span valt dan nog wel gedeeltelijk onder de knoppen, maar de tekst in ieder geval niet.

top: 48px;

Het te tonen woord komt te hoog te staan. De span waar het woord in zit, zit binnen deze span. Het is het makkelijkste te corrigeren door gewoon deze hele span, en dus ook de daarin zittende span met het woord, op deze manier op de goede hoogte te zetten.

div#omschrijving td span#toon-woord-12 span.vraag-woord-doorgaan span.woord, div#omschrijving td span#toon-woord-17 span.vraag-woord-doorgaan span.woord, div#omschrijving td span#toon-woord-20 span.vraag-woord-doorgaan span.woord

De span met class="woord" binnen de span met class="vraag-woord-doorgaan" die weer binnen de span met id="toon-woord-12" ligt, die weer binnen 'n cel binnen de div met id="omschrijving" ligt. Binnen span.woord zit het te tonen woord. Deze span hoort bij woord nummer 12. De twee selectors daarna zijn precies hetzelfde, maar dan voor de woorden 17 en 20.

margin-top: -2px;

Om een of andere reden worden precies deze drie woorden iets te laag neergezet. Dit corrigeert dat.

Speciaal voor Internet Explorer 8

<!--[if IE 8]> <style> input {padding: 1px 0 0 6px;} </style> <![endif]-->

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

input

Voor de invoer van de horizontale woorden maak ik gebruik van <input>.

padding: 1px 0 0 6px;

Deze padding wijkt iets af van die in de algemene css. Maar het ziet er in Internet Explorer 8 daardoor net iets beter uit. Jammer dat niet alle browsers iets als conditional comments hebben, want voor dit soort kleine correcties is het echt heel erg handig.

De code aanpassen aan je eigen ontwerp

Toegankelijkheid en zoekmachines

Eventuele opmerkingen specifiek voor dit voorbeeld staan bij Opmerkingen.

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:

Getest in

Laatst gecontroleerd op 22 februari 2012.

(Internet Explorer 6 is voor het laatst gecontroleerd op 10 november 2009. Op deze browser test ik niet meer. Maar omdat de code nauwelijks is veranderd, neem ik aan dat dit voorbeeld ook nog werkt in Internet Explorer 6.)

Dit voorbeeld is getest in Firefox, Opera, Safari, Google Chrome, Internet Explorer 6, 7, 8 en 9 in de resoluties 800x600, 1024x768, 1280x1024 en 1440x900. Steeds met de laatste versie van die browsers, 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 de resoluties 1024x768, 1280x1024 en 1440x900 is ook in- en uitzoomen en een kleinere en grotere letter getest. Er is ingezoomd en vergroot tot zover de browser kan, maar niet verder dan tot 200%.

Eventuele problemen met betrekking tot zoomen en lettergrootte staan bij Bekende problemen.

Er is getest met behulp van muis en toetsenbord.

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 van dit voorbeeld staan bij Opmerkingen.

Alleen op de hierboven genoemde systemen en browsers is getest. Er is dus niet getest op bijvoorbeeld mobiele systemen als iOS of Android, en ook niet op apparaten als smartphones, iPad, enz. De kans is heel erg groot dat dit voorbeeld niet (volledig) werkt op dat soort systemen en apparaten. Om het wel (volledig) werkend te krijgen, zul je vaak wijzigingen en/of aanvullingen moeten aanbrengen.

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

Wijzigingen

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

:

Nieuw opgenomen.

7 maart 2011:

22 februari 2012:

Bekende problemen

Dit voorbeeld is niet bedoeld om 'in het echt' te gebruiken. Ik wilde alleen kijken of het mogelijk was zoiets te doen. Als je de waslijst aan grotere en kleinere problemen hieronder ziet, is het hopelijk duidelijk dat je dit niet serieus moet gebruiken.

Internet Explorer 6 en 7

Internet Explorer 6

Internet Explorer 7

Opera

Alle browsers