Skip links en inhoudsopgave

Laatst aangepast: 12 december 2011

Door slepen van bovenaf tijdelijk afbeelding in nieuwe laten overvloeien

Korte omschrijving

Als je met de cursor van boven naar beneden over de afbeelding beweegt, vervaagt de afbeelding en komt geleidelijk aan een andere afbeelding tevoorschijn, die de originele afbeelding vervangt. Als je van onder of van opzij komt heeft dat geen effect.

In Internet Explorer 6 werkt het slepen niet en floept de afbeelding in één keer tevoorschijn.

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

De foto's zijn gemaakt in het Vondelpark in Amsterdam op Koninginnedag 2009. Als je jezelf herkent en de originele foto wilt hebben, stuur dan even 'n mailtje naar info@css-voorbeelden.nl.

De veranderde afbeelding verdwijnt weer als niet meer over de afbeelding wordt gehoverd, het gaat dus niet om een blijvende verandering.

Als iemand geen css gebruikt, zal de tweede afbeelding nooit verschijnen. Daarom moet je geen belangrijke informatie op deze manier geven. Als je dat toch doet, geef dan 'n alternatieve manier, bijvoorbeeld 'n link in de padding aan de bovenkant van div#spans.

Door het uitbundig gebruik van zaken als :hover en position is dit voorbeeld absoluut niet geschikt voor mobiele apparatuur (hier worden geen laptop/notebook/netbook en dergelijke mee bedoeld, want die gedragen zich als een gewone desktopcomputer).

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

Op Internet Explorer 6 na werkt bij alle nieuwere browsers :hover op alle elementen. Over Internet Explorer 6 later meer.

De hele constructie staat in een wrapper-div met position, zodat daarop gepositioneerd kan worden. Deze wrapper-div heeft 40 px meer hoogte dan de afbeeldingen, zodat er aan boven- en onderkant 20 px ruimte is voor 'n zone met 'n speciaal doel.

Binnen de wrapper-div komt een andere, absoluut gepositioneerde, div. Hierin zit alles wat nodig is om de nieuwe afbeelding zichtbaar te laten worden. Onder deze div komt een gewone afbeelding. Dat is van belang voor mensen die geen css gebruiken: die zien 'n gewone normale afbeelding. Vervangen kan uiteraard niet, want daarvoor is css nodig.

Omdat deze binnenste div absoluut is gepositioneerd, doet deze niet mee wat betreft de lay-out. Daardoor komt de afbeelding ook boven in de wrapper-div te staan. En omdat de afbeelding ook absoluut wordt gepositioneerd, dekt hij de div volledig af. Zonder absoluut positioneren van de afbeelding zou de bovenste div altijd reageren op hoveren, ook als dat nog niet de bedoeling is.

In de binnenste div staat 'n enorme serie lege <span>'s, waar via css van alles mee wordt gedaan. De hoogte van de spans is 5 px. Je kunt ook 'n grotere hoogte nemen, dan heb je minder code nodig, maar bij 'n te grote hoogte wordt de beweging schokkerig.

De vervangende afbeelding is een background-image. Die heeft van zichzelf geen hoogte en breedte, maar vult alleen het element op waar hij in staat. Dus de spans moeten de breedte van de afbeelding krijgen. Die krijgen ze bij hoveren, maar zonder hoveren is de hoogte 5 px. Omdat ze als blok-element worden weergegeven, beginnen ze automatisch op 'n nieuwe regel. Dit levert dus 'regels' van 5 px hoogte op. De spans moeten de hele afbeelding bedekken, dat is 'n kwestie van tellen en proberen.

En dan beginnen de problemen: Firefox en Safari gaan overal mee akkoord, maar Opera en Internet Explorer 7 vechten elkaar de tent uit. Wat de een het einde vindt, leidt bij de ander tot het virtuele equivalent van 'n woede-koliek. Bij de beschrijving van de code zal ik zoveel mogelijk erbij zetten waarom iets zo is gedaan, hier alleen het belangrijkste.

Als ik de spans 'n hoogte en breedte geef, werkt 't niet in Opera en Internet Explorer 7, want die constateren hoveren dan niet. Als ik 'n doorzichtig plaatje boven de spans zet, werkt 't prima in Opera, maar Internet Explorer 7 wordt dan ongelooflijk traag. Zelfde verhaal voor 'n background-image in de spans. Opera en Internet Explorer 7 blijken uiteindelijk beide gelukkig met 'n span die 0 px hoog is (anders maakt Internet Explorer 7 'm veel te hoog), en 'n doorzichtige border. Door die border reageren de spans op hoveren, ook al zijn ze verder leeg. De border heeft de hoogte die eigenlijk de span zou moeten hebben.

Tot nu toe is alleen nog maar 't constateren van de hover bereikt. Er moet natuurlijk ook nog echt iets gebeuren als er over de spans wordt gehoverd.

Omdat de spans als blok-elementen worden weergegeven, staan ze onder elkaar. Door de border van 5px zijn ze feitelijk elk 5 px hoog. Als ik met de cursor van boven naar beneden over de afbeelding beweeg, passeer ik dus achtereenvolgens alle spans.

Zodra ik over 'n bepaalde span hover, krijgt die de vervangende afbeelding als achtergrond-afbeelding, en wordt de hoogte van de span de hoogte van de achtergrond-afbeelding. Op dat moment wordt de span ook nog absoluut gepositioneerd aan de onderkant van de originele afbeelding, zodat de nieuwe afbeelding de originele volledig bedekt.

Het enige wat nu nog moet gebeuren, is de doorzichtigheid regelen. De hele constructie bestaat namelijk simpelweg uit het steeds meer zichtbaar maken van de vervangende afbeelding, waardoor het lijkt alsof de originele afbeelding min of meer oplost in de nieuwe afbeelding, maar dat is dus niet zo. De nieuwe afbeelding wordt gewoon alleen maar steeds minder doorzichtig.

Door elke span 'n eigen id te geven, kun je bij hoveren over 'n span de doorzichtigheid aanpassen. Van boven naar beneden wordt elke span steeds iets minder doorzichtig. Helaas zijn daar twee opdrachten voor nodig, omdat Microsoft het handig vond niet de standaard-opdracht te gebruiken, waar inmiddels alle andere browsers mee werken, maar 'n eigen variant te bedenken.

Omdat de afbeelding de bovenste div volledig bedekt, reageert deze (en dus de daarin liggende spans) niet op hoveren. Aan de bovenkant is daarom een padding aangebracht van 20 px. Deze ligt boven de afbeelding en reageert dus wel op hoveren. Zodra hierover gehoverd wordt, krijgt de div met de spans 'n hogere z-index, waardoor deze boven de originele afbeelding komt te liggen en dus reageert op hoveren.

Omdat deze 'gevoelige' zone alleen aan de bovenkant ligt, verschijnt de nieuwe afbeelding alleen maar als de cursor vanaf de bovenkant de originele afbeelding binnengaat.

Zodra de nieuwe afbeelding volledig zichtbaar is en de cursor nog 1 px meer omlaag gaat, verdwijnt de nieuwe afbeelding. In de praktijk blijkt dit nogal sadistisch te zijn: net als je de afbeelding volledig zichtbaar hebt is hij floep, weg. Daarom is onderaan ook 'n zone van 20 px aangebracht waarin de nieuwe afbeelding nog volledig zichtbaar blijft.

Internet Explorer 6

Voor de brekebeen onder de browsers, Internet Explorer 6, werkt dit niet, want die herkent hover alleen maar bij 'n <a>. Helaas worden de spans wel herkend, waarbij als extra bonus transparent wordt veranderd in zwart. Heel apart, dat wel, maar toch niet helemaal wat je wilt hebben. Dus wordt wat css toegevoegd om dit te voorkomen, speciaal voor Internet Explorer 6.

Omdat Internet Explorer 6 hoveren over 'n <a> wel herkent, is in de html wat code toegevoegd die alleen door Internet Explorer 6 wordt gelezen. Aan de bovenkant van de originele afbeelding staat een <a> van 20 px hoog. Als de cursor daaroverheen hovert, wordt deze <a> vergroot en komt er een achtergrond-afbeelding in te staan, die de originele afbeelding vervangt. Deze nieuwe afbeelding verdwijnt weer als de cursor buiten de afbeelding komt.

Het langzaam binnenslepen van de vervangende afbeelding, zoals dat bij alle andere browsers wel kan, kan dus niet bij Internet Explorer 6: de vervangende afbeelding floept gewoon in één keer tevoorschijn.

(Het zou wel mogelijk zijn, maar dan moet je 76 <a>'s gebruiken. En gezien het slinkende gebruik van dit verouderde monster vind ik dit de moeite niet meer waard. Bovendien is dat 'n nachtmerrie voor mensen die spraakbrowsers en dergelijke gebruiken.)

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 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="nl" 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 http://www.w3.org/QA/2002/04/valid-dtd-list.html.

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

De toevoeging achter <html hierboven hoort bij het gekozen doctype.

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Zorgt dat de browser letters met accenten en dergelijke goed kan weergeven. Als je als doctype html hebt gekozen, moet je niet eindigen op />, maar op > (dit geldt voor alles in de head wat eindigt op />).

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" type="text/css" href="../../css/naam-van-stylesheet.css" /> <!--Instellingen voor Internet Explorer --> <!--[if IE]> <link rel="stylesheet" type="text/css" 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 type="text/css"> 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 type="text/css">

Voor de duidelijkheid staat de style hier in het bestand zelf, maar het is beter deze in een apart stylesheet te zetten, zoals hierboven beschreven. In die stylesheet komt alles wat tussen bovenstaande regel en </style> staat.

Technisch gezien is er geen enkel bezwaar om het in die stylesheet te zetten met dezelfde vreselijke lay-out 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).

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.

background: #ff9;

Achtergrondkleurtje.

div#wrapper

De div waarin de hele handel staat.

position: relative;

Als ik elementen binnen deze div wil kunnen positioneren ten opzichte van deze div, moet ik 'n position geven. Ook al vul ik daar verder niets in, dat maakt niet uit, als ik maar 'n position geef.

margin: 60px auto 0;

Omdat hier maar drie getallen staan, staat hier eigenlijk margin: 60px auto 0 auto; De missende waarde voor links wordt automatisch hetzelfde genomen als die voor rechts. Hier staat dus eigenlijk 60px auto 0 auto in de volgorde boven - rechts - onder - links.

60 px vanaf de bovenkant, geen marge aan de onderkant, en links en rechts auto oftewel: evenveel. Waardoor de div en alles daarin dus horizontaal gecentreerd wordt. Deze manier om 'n blok-element horizontaal te centreren werkt alleen maar als het blok-element 'n breedte heeft.

width: 400px;

De breedte van de afbeelding. Als ik geen breedte opgeef, staat de div over de volle breedte van de pagina, en dat is niet de bedoeling. De breedte is ook nodig om met margin te kunnen centreren op de manier zoals hierboven is gedaan.

height: 426px;

De hoogte van de afbeeldingen is 386 px. Ik maak de wrapper-div 40 px hoger, zodat ik aan boven- en onderkant 20 px ruimte heb om later te gebruiken voor 'n speciaal doel.

div#spans

De div met id="spans". Dat is de div waar het hele regiment spans in staat.

position: absolute;

Het gebruik van 'n absolute positie zorgt ervoor dat deze div de afbeelding, die later wordt neergezet, niet in de weg zit. Ook die afbeelding wordt weer gewoon bovenaan gezet, omdat 'n absolute positie ervoor zorgt dat deze div niet meetelt voor de lay-out.

Tevens kan ik de binnen deze div staande spans nu positioneren ten opzichte van deze div.

padding-top: 20px;

Deze div komt gewoon bovenin div#wrapper te staan. De afbeelding wordt straks 20 px omlaag gezet, zodat er een strook ontstaat waar deze div bereikbaar is voor hoveren, ongeacht z-index en zo.

In eerste instantie is dus alleen maar een strook van 20 px boven de originele afbeelding gevoelig voor hoveren. Maar omdat de z-index wordt verhoogd door dit hoveren, is hierna deze hele div#spans gevoelig voor hoveren.

Omdat deze constructie niet werkt als css uitstaat, zou je in deze padding ook 'n gewone link kunnen aanbrengen naar de vervangende afbeelding. De <a> weergeven als blok-element met 'n hoogte van 20 px is 'n mogelijkheid. Je kunt 'm links buiten het scherm positioneren met css, zodat je 'm alleen ziet als css uit staat.

div#spans:hover

Als ik over de div met id="spans" hover. Dit is ook de reden dat dit niet werkt in Internet Explorer 6: die kent hoveren alleen maar bij 'n <a>.

height: 406px;

Deze div heeft aan de bovenkant 'n padding van 20 px. Samen met deze hoogte kom ik dus bij hoveren op 426 px uit, even hoog als div#wrapper. De originele afbeelding wordt gepositioneerd ten opzichte van div#wrapper. Omdat deze div#spans precies even groot is, kan ik nu de spans - met daarin de vervangende afbeelding - op 'n simpele manier positioneren ten opzichte van hetzelfde punt als de originele afbeelding, zodat ze precies over elkaar heen vallen.

De afbeelding is maar 386 px hoog. Door de hoogte van deze div 20 px meer te nemen krijg ik aan de onderkant extra ruimte voor 'n span met 'n speciaal doel: span#onderste.

z-index: 10;

Door de z-index te verhogen wordt nu de hele div#spans gevoelig voor hoveren. En dus alle daarin liggende spans, waarin het vervangende plaatje als background-image komt te staan.

div#spans span

De spans binnen de div met id="spans". Dat zijn de spans waarmee de voor hoveren gevoelige zone als het ware in horizontale regels wordt verdeeld. Door aan elke span straks 'n andere doorzichtigheid mee te geven, wordt de nieuwe afbeelding geleidelijk aan zichtbaar.

position: relative;

Zonder 'n relatieve positie gebeurt er bij hoveren over de afbeelding helemaal niets in Internet Explorer 7, en in de andere browsers werkt de bovenste span, maar die dekt daarna alle andere spans af, waardoor deze niet meer reageren op hoveren.

Waarom dit werkt is me niet helemaal duidelijk, want bij 'n relatieve positie blijft het element gewoon op 'n normale manier z'n ruimte innemen. De elementen worden ook niet verplaatst en er wordt ook geen z-index gebruikt. Kennelijk voorkomt dit dat bij hoveren de absolute positie die de spans dan krijgen 'wint'.

display: block;

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

width: 400px;

De span moet even breed zijn als de afbeelding, zodat het hoveren over de volle breedte werkt.

Bij het hoveren wordt een background-image toegevoegd aan de span. Ook hiervoor is een breedte nodig, want een background-image heeft van zichzelf geen afmetingen, het vult alleen maar het element waar het in staat.

height: 0;

Elke span is als het ware een horizontale regel die over de afbeelding wordt gelegd. En bij elke 'regel' hoort een :hover, zodat de nieuwe afbeelding bij elke volgende 'regel' iets beter zichtbaar wordt. Hoe kleiner ik de hoogte van de spans maak, hoe vloeiender de verandering. Maar de hoeveelheid code neemt dan ook toe. Voor elke 'regel' staat er één keer <span></span> en één extra regel in de css.

Ik wil 'regels' van 5 px hoog. Echter: als ik de spans 5 px hoog maak, werkt het hoveren niet in Opera en Internet Explorer 7. Die reageren dan helemaal nergens op. Ik kan dat opvangen door 'n transparante achtergrond te geven aan de span, maar als ik ook maar iets met achtergrond doe in de spans, maakt niet uit wat, wordt Internet Explorer 7 ongelooflijk traag. Position, padding, niets werkt goed bij álle browsers (bij Safari en Firefox werkt vreemd genoeg elke methode goed, nog veel meer dan ik hier beschrijf. Tja.)

Maar als ik elke span 'n border geef van 5 px blijkt dat in alle browsers goed te werken. Ik moet dan wel 'n hoogte van 0 opgeven, omdat Internet Explorer 7 anders van ontroering of zo dat 't lukt spontaan de hoogte van de spans tot ongeveer 20 px oprekt.

border-top: transparent solid 5px;

Voor uitleg zie hierboven. Omdat deze border onzichtbaar moet zijn, maak ik hem doorzichtig. De enige functie is om in alle browsers hoveren mogelijk te maken. 5 px hoog, dan is de beweging nog redelijk vloeiend en bij 'n kleiner getal wordt Opera erg traag.

div#spans span:hover

Als ik over een van de spans binnen de div met id="spans" hover.

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

position: absolute;

De spans staan netjes onder elkaar, alsof het regels zijn. Maar bij hoveren krijgen ze 'n achtergrond-afbeelding die de originele afbeelding moet vervangen.

Daarom moet bij hoveren de span onderaan worden gezet. Als ik de span dan de goede hoogte geef, komt de vervangende afbeelding precies boven de originele te staan.

Het eerste ouder-element met een positie is div#spans, dus er wordt gepositioneerd ten opzichte van die div.

bottom: 20px;

20 px boven de onderkant van div#spans neerzetten. Boven de onderkant? Tja, dat zit zo: ik ben begonnen op basis van iets anders dat al klaar was, en daar móést vanaf de onderkant worden gepositioneerd. Waarschijnlijk kan 't ook vanaf de bovenkant, wat misschien intuïtiever zou zijn, maar dit bestond nou eenmaal al min of meer... Sorry, lui en conservatief, ik weet 't, ik weet 't, en ik ben er nog best tevreden mee ook...

Oké. Genoeg ge-ohaad. 20 px? Ja, gaat-ie:

div#wrapper is 426 px hoog. Daarbinnen staat de originele afbeelding. Die is 386 px hoog, en staat 20 px absoluut omlaag gepositioneerd. De onderkant van de originele afbeelding staat dus 20 px boven de onderkant van div#wrapper. En omdat div#spans even hoog is als div#wrapper, moet de span met de vervangende afbeelding dus ook 20 px boven de onderkant van div#spans komen ten staan.

height: 386px;

Van zichzelf heeft een span geen hoogte, ook niet als het 'n blok-element is. 'n Achtergrond-afbeelding heeft ook geen maat van zichzelf, die vult alleen maar het element waar hij in staat. Dus de span 'n hoogte geven die even groot is als die van de vervangende afbeelding.

background: url(053-pics/vervang.jpg);

De vervangende afbeelding als achtergrond-afbeelding in de span zetten.

span#s-1:hover

Als ik hover over de span met id="s-1".

Elke span heeft 'n eigen id, s-1 t/m s-75, daardoor kan ik ze allemaal 'n eigen doorzichtigheid geven.

opacity: 0.013;

De standaardmanier (in css 3) om doorzichtigheid mee aan te geven. De waarden lopen van 0 tot 1. 0.013 is dus vrijwel onzichtbaar.

filter: alpha(opacity=1);

Deze opdracht is voor Internet Explorer 7 en 8. Hier lopen de waarden van 0 tot 100. Dit is geen valid css, maar persoonlijk til ik daar niet zo zwaar aan: ik weet precies waarom de validator begint te mopperen. Zie verder bij Bekende problemen.

Internet Explorer 9 herkent eindelijk het standaard opacity.

span#s-2:hover {opacity: 0.026; filter: alpha(opacity=3);}

t/m

span#s-75:hover {opacity: 0.981; filter: alpha(opacity=99);}

Deze spans werken precies hetzelfde als die hierboven. Alleen de id's veranderen, zodat ik ze 'n eigen doorzichtigheid kan geven.

Omdat het 75 spans zijn en de doorzichtigheid van 0 tot 1 (standaard) of van 0 tot 100 (Internet Explorer) loopt, kun je uitrekenen hoe groot de tussenliggende getallen ongeveer moeten zijn.

div#spans span#onderste:hover

Als ik over de span met id="onderste" binnen de div met id="spans" hover.

Omdat deze span ook voldoet aan de selector div#spans span en div#spans span:hover, gelden de regels van die selectors dus ook voor deze span.

Dit is 'n aparte span helemaal onderaan, die wat afwijkt van de andere. Als ik met m'n cursor omlaag ga en de onderkant van de originele afbeelding heb bereikt, zijn de spans 'op'. Als ik nog 1 px meer omlaag ga en buiten de afbeelding kom, sluit de nieuwe afbeelding gelijk. Dus je moet 'n verrekt vaste hand hebben om precies de onderkant van de originele afbeelding te bereiken: 1 px te hoog en je ziet de nieuwe afbeelding niet volledig, 1 px te laag en de nieuwe afbeelding floept weg. Deze span voorkomt dat.

'n Instelling voor doorzichtigheid hoeft deze span niet te hebben, want hier moet de achtergrond-afbeelding gewoon op de normale, ondoorzichtige, manier worden weergegeven.

Het is mogelijk dat alle spans bij elkaar niet helemaal tot onderaan de afbeelding komen en dat er onderaan, gelijk boven span#onderste, 'n kleine kier zit. De basis voor dit voorbeeld bestond namelijk al en ik had geen zin om al die waardes voor doorzichtigheid opnieuw te gaan uitrekenen. En het maakt niets uit, want het betekent alleen dat de laatste overgang van 0.981 naar 1 (99 naar 100 bij Internet Explorer) 'n paar px lager plaats vindt dan wanneer alles afgedekt zou zijn. Als je dat kunt zien, kun je jezelf als verrekijker gaan verhuren.

bottom: 0;

div#spans is even hoog als div#wrapper. Dat is aan de onderkant 20 px meer dan de afbeelding beslaat. Daarom staan alle spans met de vervangende afbeelding 20 px naar boven. Behalve deze. Hierdoor krijg ik aan de onderkant 'n ruimte van 20 px, waarin geen achtergrond-afbeelding staat, maar waar het hoveren nog wel werkt. Dit voorkomt dat de vervangende afbeelding gelijk verdwijnt als ik ook maar 1 px beneden de afbeelding kom met de cursor.

height: 406px;

De spans zijn blok-elementen van 5 px hoog. Deze span ook, zolang er niet over wordt gehoverd, want pas bij hoveren wordt de hoogte meer. Deze span staat ongeveer onderaan de afbeelding op het ogenblik dat erover wordt gehoverd, omdat de spans gewoon onder elkaar steeds op 'n nieuwe regel worden gezet. Bij hoveren wordt deze span aan de onderkant van div#spans gezet, 20 px omlaag.

Als ik nu de hoogte geen 386 px maak, maar 406 px heb ik dus aan de onderkant 20 px extra, waar hoveren ook werkt. Zodat de nieuwe afbeelding niet gelijk wegfloept als ik 1 px te laag kom met de cursor.

background: url(053-pics/vervang.jpg) no-repeat;

Omdat de afbeelding 386 px hoog is en deze span 406 px, zou de afbeelding zich gaan herhalen, zoals 'n welopgevoede background-image hoort te doen. Dat wil ik hier niet. De afbeelding wordt gewoon bovenin de span gezet, en onderaan heb ik 'n kier van 20 px. Daar werkt hoveren dus wel, maar zie ik verder niets.

Ik moet de naam van de afbeelding herhalen, omdat anders wordt gedacht dat ik opdracht geef om geen background-image te plaatsen in deze span.

div#wrapper img

Alle afbeeldingen binnen de div met id="wrapper". Dat is hier alleen de originele afbeelding.

position: absolute;

Door de afbeelding absoluut te positioneren maakt hij de div met de spans ongevoelig voor hoveren (behalve het deel van de div dat bovenaan uitsteekt boven de afbeelding).

top: 20px;

Bovenin div#wrapper zit een 'kier' van 20 px waar hoveren werkt. Daar wil ik geen afbeelding, want dan zou hoveren daar ook niet werken. 20 px afstand tot de bovenkant van div#wrapper dus.

Speciaal voor Internet Explorer 6

<!--[if IE 6]> <style type="text/css"> div#spans span {border: none;} a#voor-ie-6 {display: block; position: relative; top: 20px; width: 400px; height: 20px; background: url(053-pics/space-1x1.gif);} a#voor-ie-6:hover {height: 386px; background: url(053-pics/vervang.jpg); cursor: default;} </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" type="text/css" 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.

div#spans span

De div met id="spans" waar alle spans in staan.

border: none;

Hoewel Internet Explorer 6 geen hover kent bij andere elementen dan 'n <a>, worden de spans wel gewoon weergegeven. En dus ook de border van 5 px. Die is weliswaar doorzichtig, maar ook dat kent Internet Explorer 6 niet. Dus wordt het doorzichtige veranderd in massief zwart: logica op z'n Microsofts. En dat dan 77 keer, het aantal spans. Bovendien wordt ook nog 'ns de hoogte vergroot tot ongeveer 10 px als ik deze opdracht niet geef.

Dit kan natuurlijk wel helpen om mensen weg te jagen bij Internet Explorer 6. Maar als je daar niet aan wilt meewerken, dan helpt dit om Internet Explorer 6 gewoon alleen de originele afbeelding te laten zien.

a#voor-ie-6

De a met id="voor-ie-6". Dit is de link die alleen door Internet Explorer 6 wordt gezien.

display: block;

Van zichzelf is een link 'n inline-element. Door er 'n blok-element van te maken kan ik allerlei attributen zoals hoogte gebruiken.

position: relative;

Om te kunnen positioneren. Het positioneren gebeurt ten opzichte van div#wrapper, de eerste ouder met een positie.

top: 20px;

Omdat div#spans en img (de afbeelding) beide absoluut zijn gepositioneerd, hebben deze geen invloed op de plaats van deze <a>. Met deze instelling komt de voor hoveren gevoelige zone precies bovenaan de originele afbeelding zelf te staan.

width: 400px; height: 20px;

Grootte van de <a>, en dus van de voor het hoveren gevoelige zone.

background: url(053-pics/space-1x1.gif);

Nodig omdat Internet Explorer 6 anders niet reageert op het hoveren.

a#voor-ie-6:hover

De a met id="voor-ie-6" bij hoveren. Dit is de link die alleen door Internet Explorer 6 wordt gezien.

height: 386px;

De <a> nu even hoog maken als de vervangende afbeelding is.

background: url(053-pics/vervang.jpg);

Vervangende afbeelding openen als achtergrond-afbeelding.

cursor: default;

Omdat dit geen link is, moet de cursor niet in een handje veranderen.

Html speciaal voor Internet Explorer 6

<!--[if IE 6]> <a id="voor-ie-6" href="#" ></a> <![endif]-->

Deze html wordt alleen gelezen door Internet Explorer 6, uitleg bij Speciaal voor Internet Explorer 6. De uitleg daar is voor css, maar voor html werkt het precies hetzelfde.

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 12 december 2011.

(Internet Explorer 6 is voor het laatst gecontroleerd op 24 december 2009. Op deze browser test ik niet meer. Maar omdat de code niet 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.

Naast deze 'gewone' browsers is ook getest in Lynx, WebbIE, Jaws 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. Jaws 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.

Dit voorbeeld is niet getest op geschiktheid voor mobiele apparaten (hier worden geen laptop/notebook/netbook en dergelijke mee bedoeld, want die gedragen zich als een gewone desktopcomputer). Er wordt in veel voorbeelden css en/of html gebruikt, waar niet elk mobiel apparaat mee uit de voeten zal kunnen. En lang niet alles is geschikt voor schermen met een breedte van minder dan 800 px.

Dingen die problemen zouden kunnen opleveren, zijn onder andere een te grote breedte, het gebruik van (te veel) afbeeldingen en/of css en html die niet (volledig) wordt ondersteund, zoals :hover, float en position.

Onder Opmerkingen staat mogelijk nog wat meer over de geschiktheid van dit voorbeeld voor mobiele apparaten.

(Terzijde: de site zelf is zeker niet geschikt voor kleine mobieltjes. Dat gaat ook niet veranderen. Ik kan me namelijk niet voorstellen dat iemand zo masochistisch is 'n uitleg van tientallen schermen op 'n klein mobieltje te gaan lezen. Voor de site zelf is een minimale breedte van 800 px vereist.)

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.

7 januari 2009:

Nieuw opgenomen.

26 maart 2009:

12 april 2009:

Hierboven vermelde meta-tag weer weggehaald. Ook Internet Explorer 8 gebruikt nog steeds niet de standaard voor doorzichtigheid, maar 'n door Microsoft zelf bedachte methode. Nu werkt dit voorbeeld ook in de standaardmodus van Internet Explorer 8.

Overigens opmerkelijk dat Microsoft dit de 'super standards mode' noemt, terwijl zoiets simpels als opacity nog niet eens volgens de standaard werkt. En dan heb ik het maar helemaal niet over svg, css en html5, waarin deze 'super standards'-browser jaren en jaren achterloopt op álle concurrenten.

30 december 2009:

Afbeeldingen van lp's vervangen door eigengemaakte foto's van Koninginnedag 2009 in het Vondelpark in Amsterdam. Dit in verband met copyright. Ook op deze afbeeldingen bleek dat te zitten. Tja.

12 december 2011:

Tekst aangepast aan de inmiddels verschenen Internet Explorer 9. De code is niet gewijzigd.

Bekende problemen

Valideren

De opdracht voor doorzichtigheid is onderdeel van css 3. Om valide code te krijgen moet je dus valideren op css 3. Maar ook dan krijg je geen valide code, omdat de opdracht met filter voor Internet Explorer 7 en 8 geen standaard-css is.

Persoonlijk vind ik dit geen probleem, omdat ik precies weet waarom de css niet valid is. Maar als je erg fundamentalistisch bent op dit gebied kun je de regel voor Internet Explorer opnemen in een conditional comment (als je zo fel bent op valid code ga ik ervan uit dat je weet wat conditional comments zijn).

Internet Explorer 9 herkent eindelijk opacity, dus geleidelijk aan zal het gebruik van filter gaan verdwijnen.

Internet Explorer 6

In deze zwaar verouderde en onveilige browser opent de afbeelding in één keer, dus zonder slepen. Zie verder bij Internet Explorer 6.