Handboek HTML5 en CSS3

Leerboek en naslagwerk ineen

Sticky notes

Wat hier is te verwachten

Van het Handboek HTML5 en CSS3 is de de derde editie verschenen! Weer geactualiseerd.

Onder Tips is een artikel geplaatst over de viewport.

Het artikel over media queries is uitgebreid met uitleg over een extra kolom voor de twitterfeed.

Automatisch post-its verbergen (zonder scripting) in deel 4 van De CSS van de post-its.

Schots en scheve plakkers zonder scripting in deel 3 van De CSS van de post-its.

Het tweede artikel over de CSS van deze gele briefjes is geplaatst: tekst in de rand.

Eerste artikel over de CSS van deze gele briefjes is geplaatst: omgevouwen hoeken.

Onder Tips is een artikel geplaatst over het gebruik van media queries.

Vooruitlopend op de publicatie van vragen bij het boek is uitleg over localStorage toegevoegd, te vinden onder Vragen.

De boekcode is toegevoegd aan de site, te vinden onder Code. Of download direct het zipbestand.

Van de CSS-module Flexible Box Layout Level 1 is op 14 mei 2015 een nieuwe conceptversie gepubliceerd. Het belangrijkste verschil met de uitleg in het boek is dat bij de eigenschap flex-basis de waarde main-size is vervangen door de nieuwe waarde content.

Deze site hoort bij het Handboek HTML5 en CSS3. Hier zijn bijvoorbeeld de HTML- en CSS-codevoorbeelden uit het boek te vinden. Het is ook een demonstratieproject. De site is volledig handgecodeerd met HTML en CSS – tenzij het bij bepaalde functies echt niet anders kan. Niet uit principe, maar omdat het schone code oplevert waar een ander misschien iets van kan opsteken. Schoner in elk geval dan bij de meeste cms’en. U wordt dan ook van harte aangemoedigd om onder de motorkap te kijken en opmerkingen, vragen en suggesties te delen via @HTMLenCSS of mail reacties@handboek-html-css.nl.

Er komt ook een flexboxversie van de site. In hoofdstuk 12 van het boek vindt u de theorie en de voorbeelden. Hier doen we het live. Dat wordt een leerzaam experiment.

Op de lijst staan ook vragen en antwoorden over de inhoud van het boek, opgebouwd met formulierelementen en de in HTML5 ingebouwde validatie (uiteraard). Geschikt voor zelfstudie, maar natuurlijk ook in het onderwijs bruikbaar als ondersteuning van de lessen. Ook hier snijdt het mes aan twee kanten, hoe bouwt u zo'n formulier op, maar ook: hoe bewaart u de ingevoerde antwoorden? Dit wordt een experiment met localStorage, waarbij onvermijdelijk de grenzen van HTML en CSS worden opgerekt naar JavaScript.

Opmerkingen, vragen, kritiek en likes (over de site en het boek) kunnen worden gemaild naar reacties@handboek-html-css.nl. Artikelen kunnen wel worden gedeeld via Twitter @HTMLenCSS. De JavaScript-code daarvoor is een beetje van Twitter en beetje van mezelf. Een artikeltje volgt nog, want het is best een aardige oplossing.

Veel succes met het leren en experimenteren!

Tips

De ene viewport is de andere niet

Een webpagina is niet zonder meer goed te bekijken op een mobiel apparaat. Dat komt doordat breedte waarin de pagina wordt opgebouwd een andere breedte is dan die van het scherm. Met inzoomen en zijwaarts scrollen is de inhoud leesbaar te maken, maar een prettige gebruikerservaring is het zeker niet.

De oorzaak is een combinatie van de CSS-eigenschap width en de viewport van het mobiele apparaat. De viewport is op een desktopbrowser gelijk aan het browservenster. Wordt het browservenster groter of kleiner gemaakt, dan wordt ook de viewport groter of kleiner. Op een mobiel kan dat niet. De viewport van een browser op een telefoon heeft vaste afmetingen. Alleen zijn die niet in elke browser hetzelfde en om het nog lastiger te maken heeft een mobiele browser twee viewports: een zichtbare viewport en een lay-outviewport.

De zichtbare viewport is het scherm van het mobiele apparaat. De lay-outviewport is bij de meeste apparaten veel groter. Hoe groot precies, verschilt per browser. De breedte varieert van zo’n 800 tot 980 pixels. Stel de lay-outviewport voor als een grote afbeelding die wordt afgedekt door een ondoorzichtige laag. De zichtbare viewport is een kleiner venster waardoorheen een deel van die onderliggende afbeelding zichtbaar is. (De volledige uitleg staat op Stack Overflow)

De CSS-eigenschap width is gerelateerd aan de lay-outviewport. Een pagina met width: 100% is dan 980 pixels breed, terwijl het scherm maar 375 pixels breed is (beide waarden gelden voor de iPhone 6. Die beweert overigens 750 pixels breed te zijn, maar dat is een ander probleem.)

Naast de CSS-eigenschap width bestaat de eigenschap device-width. Die komt overeen met de breedte van het telefoonscherm en is dan ook de afmeting waar de webpagina zich aan zou moeten aanpassen.

Zo komen we bij de metatag viewport. Door de width van viewport uitdrukkelijk in te stellen op de device-width, wordt een width van 100% hetzelfde als de breedte van het venster, bij de iPhone 6 375 pixels.

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

De toevoeging initial-scale=1 zorgt ervoor dat de webpagina niet wordt geschaald om hem in het venster te laten passen, dus 1 CSS-pixel is gelijk aan 1 pixel in de viewport. Overigens zou dat op een responsieve pagina vanzelf goed moeten gaan. Als de pagina niet responsief is (een vaste breedte heeft), is het sowieso niet aan te raden de metatag viewport te gebruiken. De browser perst dan de hele webpagina in het scherm, waardoor de gebruiker ver moet inzoomen om ook maar iets te kunnen lezen.

Schermafbeelding van Chrome DevTools.
In Chrome DevTools is te zien dat de width zonder de metatag viewport 980 pixels is.

CSS van de post-its 4: automatisch verbergen

Boven aan de pagina staan 'post-its'. Deze eenvoudige geeltjes hebben vier leuke CSS-dingetjes: een omgevouwen hoekje, tekst in de bovenrand, ze zijn 'willekeurig' scheef geplakt en een deel wordt automatisch verborgen op kleine schermen. Deze CSS-toepassingen worden in vier artikelen toegelicht.

In deel 3 in deze miniserie wordt uitgelegd hoe de post-its pseudononchalant op de pagina worden geplakt. Daarbij is een sleutelrol weggelegd voor de structurelepseudoklasseselector nth-of-type. Ook voor het laatste aardigheidje wordt deze selector gebruikt. Op het kleine scherm van een smartphone nemen de post-its al snel veel ruimte in beslag. Het zou daarom handig zijn als het aantal post-its op kleinere schermen kan worden beperkt.

Dat begint met de vraag hoe we de post-it selecteren. Net als in deel 3 wordt daarvoor eenvoudig de naam van klasse gebruikt.

De volgende stap is bepalen welke plakkers moeten worden verborgen. Ze staan op volgorde van plaatsingsdatum, dus de oudste staan onderaan. Dan ligt het voor de hand om vanaf een bepaalde plakker de rest te verbergen, zeg nummer 4. Met diezelfde selector nth-of-type is het koud kunstje om alle plakkers vanaf nummer 4 te verbergen: nth-of-type(n+4). De teller n loopt immers van 0 tot het aantal post-its en daar wordt telkens 4 bij opgeteld.

Met de eigenschap display worden elementen getoond en verborgen. Het ontwerp is gebaseerd op mobile first; verbergen is dus de begininstelling:

.post-it:nth-of-type(n+4) {
  display: none;
}

Met een media query worden alle post-its zichtbaar gemaakt:

@media screen and (min-width: 64rem) {
  .post-it:nth-of-type(n+4) {
    display: inline-block;
  }
}

Er komt natuurlijk een moment dat er te veel post-its zijn. Het aantal kan worden beperkt door in de media query een regel toe te voegen die alles vanaf nummer 7 verbergt. De HTML-code van die post-its kan blijven staan, zodat die beschikbaar blijft voor andere toepassingen.

@media screen and (min-width: 64rem) {
  .post-it:nth-of-type(n+4) {
    display: inline-block;
  }
  .post-it:nth-of-type(n+7) {
    display: none;
  }  
}

CSS van de post-its 3: willekeurig scheef zetten zonder scripting

Boven aan de pagina staan 'post-its'. Deze eenvoudige geeltjes hebben vier leuke CSS-dingetjes: een omgevouwen hoekje, tekst in de bovenrand, ze zijn 'willekeurig' scheef geplakt en een deel wordt automatisch verborgen op kleine schermen. Deze CSS-toepassingen worden in vier artikelen toegelicht.

CSS beschikt over een rijke sortering selectors, van de eenvoudige elementselector tot de geavanceerde structurele pseudoklassen. Met die structurele pseudoklassen kunnen onder meer elementen worden geselecteerd die de zoveelste van een bepaald type zijn. Het bekendste voorbeeld: de om en om gekleurde tabelrijen. Elke oneven rij wordt geselecteerd met bijvoorbeeld tr:nth-of-type(2n+1). Hoe zit dat?

Met nth-of-type wordt een bepaald type element geselecteerd, hier de tabelrij <tr>. Tussen haakjes staat de gewenste berekening/telling, hier 2n+1. De n is een teller die loopt van 0 tot zoveel keer als het gezochte element voorkomt. Het getal ervoor is de vermenigvuldiger. Het getal erna wordt er met plus bij opgeteld, maar kan er met min ook van worden afgetrokken. 2n+1 geeft dus 2 x 0 + 1 = 1, 2 x 1 + 1 = 3, 2 x 2 + 1 = 5 enzovoort. Op deze manier kunnen alle oneven elementen worden gevonden, maar met andere waarden ook alle even elementen of elke ander reeks.

De post-its lijken slordig opgeplakt. De ene plakker staat iets scheef naar links, de ander naar rechts en een volgende staat gewoon recht. Deze willekeur ontstaat door een combinatie van selectors: nth-of-type(2n+1) en nth-of-type(3n-1). Deze leveren twee reeksen op: 1, 3, 5 , 7, ... en 2, 5, 8, ... Eigenlijk zijn het drie reeksen, want alle getallen die erbuiten vallen worden gewoon recht geplaats. Hier is dat de vierde post-it.

See the Pen post-its 3: willekeurig scheef plakken by Peter Doolaard (@dool) on CodePen.

De scheve stand wordt bereikt met verschillende waarden voor transform: rotate(xdeg), waarbij een positieve of negatieve waarde het element naar links of rechts draait.

CSS van de post-its 2: tekst in de rand

Boven aan de pagina staan 'post-its'. Deze eenvoudige geeltjes hebben vier leuke CSS-dingetjes: een omgevouwen hoekje, tekst in de bovenrand, ze zijn 'willekeurig' scheef geplakt en een deel wordt automatisch verborgen op kleine schermen. Deze CSS-toepassingen worden in vier artikelen toegelicht.

Een rand is vaak smal en subtiel, maar dat hoeft natuurlijk niet. Juist met dikke randen zijn leuke effecten te bereiken. Hoewel het niet mogelijk is om in die rand tekst te plaatsen, kan er wel tekst op worden gezet. En daar zijn geen trucs voor nodig met extra elementen, lagen of andere kunstgrepen. Hoe zit dat bij de post-its?

Elke post-it heeft dezelfde eenvoudige opbouw: een alineaelement <p class="actueel"> met daarin een element <time> voor de publicatiedatum. Meer is er niet. (In de voorbeeldcode is de CSS voor het omgevouwen hoekje verwijderd.)

See the Pen Post-its: tekst in de rand 1 by Peter Doolaard (@dool) on CodePen.

Belangrijk in de CSS-code zijn natuurlijk de eigenschappen voor de bovenrand, met een donkerder tint en een dikte van 32 pixels. Belangrijk is echter ook de regel position: relative. Deze is nodig voor het omgevouwen hoekje (zie artikel 1), maar biedt ook de mogelijkheid om andere elementen absoluut te positioneren. En dat is precies wat nodig is om tekst in de rand krijgen. Het element <time> wordt gewoon absoluut gepositioneerd in de rand:

See the Pen Post-its tekst in de rand 2 by Peter Doolaard (@dool) on CodePen.

Het draait om de position: absolute en top: -1.6em. Daarmee wordt het element <time> vanuit zijn uitgangspositie linksboven in de post-it 1,6 em omhoog gezet, ongeveer anderhalve regel van de tekst in de post-it. Met die waarde komt de datum min of meer verticaal midden in de rand te staan.

CSS van de post-its 1: omgevouwen hoeken

Boven aan de pagina staan 'post-its'. Deze eenvoudige geeltjes hebben vier leuke CSS-dingetjes: een omgevouwen hoekje, tekst in de bovenrand, ze zijn 'willekeurig' scheef geplakt en een deel wordt automatisch verborgen op kleine schermen. Deze CSS-toepassingen worden in vier artikelen toegelicht.

Het omgevouwen hoekje is een veelbesproken aardigheidje met CSS (googel maar eens 'css folded corner'). De code is uiteraard te vinden in de stylesheet, maar de declaraties voor de klasse bevatten ook andere stijlregels en dat maakt de code uitgebreider dan strikt noodzakelijk. Voor een omgevouwen hoekje zijn twee dingen nodig: een relatief gepositioneerd (inline) blok en een absoluut gepositioneerd before- of after-pseudo-element. Bekijk de HTML en de CSS:

See the Pen Omgevouwen hoekje by Peter Doolaard (@dool) on CodePen.

De basis is een div (of elk ander blokelement).
De div wordt relatief gepositioneerd, zodat het pseudo-element ::before daar absoluut in kan worden gepositioneerd. Dat is essentieel. De positie is in dit voorbeeld rechtsonder: bottom: 0; right: 0.
Het pseudo-element is leeg (content: "") en heeft geen breedte (width: 0). Het heeft wel een stevige rand; denk om de eigenschap border-style, anders is de rand nooit zichtbaar. De rand staat onder en links: border-width: 0 0 24px 24px; De onderrand steekt omhoog en de linkerrand naar rechts. Daardoor ontstaat een vierkantje rechtsonder in de div, met zijden ter grootte van de randdikte. Dat is goed te zien door zelf de randbreedte van alle zijden op 24px in te stellen. De randen vormen een kruis vanuit de hoekpunten. De kleur van de rand maakt dat de buitenkant wegvalt in de achtergrond en dat de binnenkant omgevouwen lijkt. Boven en onder heeft de rand de achtergrondkleur (wit) en links en rechts een donkere variant van de gele div-achtergrondkleur: border-color: white hsla(60, 75%, 50%, 1.00);.
Met wat schaduw krijgt het hoekje diepte (box-shadow).

Zo'n omgevouwen hoekje kan op elke hoek worden gemaakt door de positie van het pseudo-element en de randeigenschappen aan te passen. Bekijk bijvoorbeeld de volgende code. Daarin staat het pseudo-element bovenaan (top: 0) en is de rand ingesteld op de boven- en linkerkant.

See the Pen Ander omgevouwen hoekje by Peter Doolaard (@dool) on CodePen.

Het is geen toepassing voor dagelijks gebruik, maar het experimenteren met de hoek maakt u vertrouwd met de werking van absolute positionering en de randeigenschappen.

Opmaak op basis van schermgrootte: media queries

Update 21 juni 2015: extra media query vanaf 1648 pixels

Media queries maken het mogelijk de opmaak en lay-out van een HTML-pagina aan te passen op basis van onder meer de schermgrootte, zonder dat daar JavaScript voor nodig is. Deze site zou zonder media queries óf op mobiel onleesbaar zijn en uit elkaar vallen, óf op een groot scherm niet profiteren van de beschikbare ruimte. Nu kan de inhoud op elk schermformaat goed worden bekeken en past de lay-out zich automatisch aan. Omdat de site mede is bedoeld als demoproject heb ik me bij de media queries niet ingehouden. Bovendien is het gewoon leuk om te kijken hoe ver je kunt komen met automatische lay-outaanpassingen zonder scripting. Het zal je nog verbazen.
Laten we eens kijken naar de opbouw van deze site bij verschillende schermformaten.

Vanuit het principe mobile first is deze site gebouwd op een scherm van 360 x 640, een gangbaar mobiel formaat. Bij de ontwikkeling is dankbaar gebruik gemaakt van de apparaatemulatie in Chrome DevTools.

Schermafbeelding van Chrome DevTools.
De schakelaar voor de emulatie van (mobiele) apparaten in Chrome DevTools.

Alle basisopmaak van deze site staat in de eerste 260 regels van het CSS-bestand. Wat daarin wordt gedefinieerd geldt voor alle apparaten en schermformaten. Pas als in een media query voor een element een andere CSS-declaratie wordt ingesteld, wordt de oorspronkelijke regel overschreven. Die overschrijving geldt zolang de voorwaarde van de media query van kracht is. Verandert bijvoorbeeld de schermgrootte en valt die buiten de media query, dan geldt weer de oorspronkelijke opmaak of een volgende media query.

Kleiner dan 1024 pixels (40rem)

Tot en met een breedte van 1023 pixels is de achtergrondafbeelding van de header schermvullend en staat het menu gecentreerd tegen de onderrand van het scherm. (Ja, op mobiel is een menuslider of pop-upmenu mooier, maar dat kan niet met alleen HTML en CSS.)
Ook het tekstblok vult de hele breedte. De koppen van de secties en artikelen staan in het blok, boven de artikeltekst.

Telefoon op z'n kant

Wordt bij dit schermformaat de telefoon gekanteld, dan wordt het menu links uitgelijnd en de tekst wordt groter; zo wordt de ruimte beter benut.

Vanaf 1024 pixels (64rem)

Vanaf 1024 pixels gebeurt er van alles. De header krijgt een hoogte van 200px, waardoor ook de afbeelding nog maar gedeeltelijk is te zien. Bovendien wordt een bovenmarge ingesteld, waardoor de header omlaag komt. In de vrijgekomen ruimte wordt de navigatie geplaatst door gebruik te maken van absolute positionering.
Tegelijkertijd wordt op de achtergrond — in de container-div — een afbeelding zichtbaar die tot nu toe verborgen was. Deze is transparant gemaakt (opacity). De headerafbeelding is precies uitgelijnd met deze tweede afbeelding, zodat het lijkt alsof het één gedeeltelijk transparante afbeelding is.
Omdat het tekstblok nu breder wordt, kunnen de tekstregels te lang worden. Daarom wordt het blok nu verdeeld tussen de sectiekoppen (20% breedte) en artikeltekst (80%). De header float naar links, de artikeltekst naar rechts. Zou die ook naar links floaten, dan kwam het volgende artikel in de headerkolom terecht.
Bij deze breedte is er ook genoeg ruimte om boven aan het tekstblok meer dan twee sticky notes te tonen; de weergavewaarde van de derde (en volgende) geeltjes wordt omgeschakeld van display: none naar display: inline-block.

Vanaf 1280 pixels (80rem)

Vanaf dit punt is er steeds meer schermruimte. Die wordt benut door het menu te verplaatsen naar de linkerkant, naast de eerste sectie. De grap is dat de navigatie een kind is van de paginaheader, maar daar nu volledig buiten staat. Dat is gerealiseerd met absolute positionering met negatieve waarden voor top en left. In de grote ruimte links wordt nu ook een knop zichtbaar waarmee de gebruiker terugkomt aan de bovenkant van de pagina.

Vanaf 1648 pixels (103rem)

Op grote schermen blijft boven de 1280 pixels toch nog veel ruimte onbenut. Daarom wordt vanaf 1648 pixels (103 rem) een extra kolom toegevoegd. Daarin vinden de twitterfeed van het boek en verwijzingen naar de hoofdstukken in het boek een plekje (en wat verder nog wordt bedacht). Nu wordt de twitterfeed al op de pagina getoond vanaf 1024 pixels (64rem). Bij dat schermformaat staat de feed als float in het eerste artikel op de pagina. Onder 1024 pixels is de weergave van de feed uitgeschakeld met display: none.

Het is niet fraai om vanaf 103rem de nieuwe rechterkolom domweg naast de tekstkolom te plakken. Voor meer samenhang wordt de header van de pagina breder gemaakt. Omdat de achtergrondafbeelding van de header en de vage weergave van hetzelfde beeld (de <img> binnen de container-div) elkaar overlappen, moeten de afbeeldingen naadloos op elkaar aansluiten:

.container > img {
  width: 86.4rem;
  top: -624px;
  right: -360px;
}

De extra kolom is geen 'echte' aparte kolom; de inhoud staat in de HTML op een logische plaats in het desbetreffende artikel (u weet wel, de scheiding van inhoud en presentatie). Door middel van positionering wordt het blok naar rechts verschoven, naar de volgende 'kolom'. Voor het blok met de twitterfeed ziet dat er als volgt uit:

aside.twitter {
  position: absolute;
  right: -360px;
  top: 180px;
  margin-top: 3rem;
  float: none;
  height: 650px;
}

De positie wordt bepaald met top en right en daarnaast wordt de float uitgeschakeld die eerder was ingesteld in de media query vanaf 1024 pixels. De bovenmarge creëert wat afstand tot de header en de hoogte van dit blok wordt ingesteld op 650px.
De andere lichtblauwe kaders worden op een vergelijkbare manier in de rechterkolom geplaatst. Bekijk voor de details de CSS-code van deze pagina.

Conclusie

Media queries zijn een geweldige mogelijkheid voor het maken van flexibele en responsieve websites. Hoewel met floats al de nodige vloeibaarheid kan worden aangebracht, geven media queries veel meer controle over de lay-out. Bekijk de W3C-aanbeveling uit 2012 en volg de ontwikkeling van Media Queries level 4.

Het toegepaste lettertype vinden

Het kan soms lastig zijn om te beoordelen of in de browser ook werkelijk het in de stylesheet ingestelde lettertype wordt getoond. In de Hulpmiddelen voor ontwikkelaars is natuurlijk wel de stijlregel voor het lettertype terug te vinden en ook de berekende stijl (computed style) is uit te lezen. Toch weet u dan nog niet welk lettertype uit de declaratie van font-family daadwerkelijk is toegepast.

Schermafbeelding van Chrome DevTools
Een tekstelement geselecteerd in Chrome DevTools. Het toegepaste lettertype staat onder Rendered Fonts.

Chrome DevTools biedt een handig controlemiddel: het deelvenster Rendered Fonts. Rechtsklik op een tekstelement in de HTML-pagina en kies Element inspecteren. Activeer in DevTools zo nodig het tabblad Computed. Onder aan de lijst met CSS-eigenschappen vindt u het deelvenster Rendered Fonts met daarin het weergegeven lettertype.

Ook Firefox heeft een dergelijke voorziening, te vinden op een eigen tabblad met de naam Lettertypen in het onderdeel Inspector (Ctrl+Shift+I of snelmenuoptie Element inspecteren).

Schermafbeelding van Firefox Inspector
Het tabblad Lettertypen in Firefox toont welk font het geselecteerde element heeft.

Uitleg flexbox met dobbelstenen

De uitleg over het werken met flexbox in hoofdstuk 12 is niet het makkelijkste onderdeel van het boek, dus alles wat het verhaal extra kan verduidelijken is meegenomen. Een jaloersmakende uitleg is te vinden op het blog van developer David Welsh. Getting dicey with flexbox, geschreven door Landon Schropp, is verhelderend en demonstreert weer eens hoe met eenvoudige code mooie resultaten mogelijk zijn. Op CodePen staat alle HTML- en CSS-code.

Rekenhulp voor specificiteit

In hoofdstuk 8 wordt uitgebreid stilgestaan bij selectors. Belangrijk daarbij is hoe zwaar een selector telt of met andere woorden: hoe moeilijk die is te overschrijven. Zo telt een id zwaarder dan een class en een class telt zwaarder dan een element. Dit wordt de specificiteit van een selector genoemd. Bij onverwachte resultaten in de opmaak kan dit principe een rol spelen. Keegan Street heeft een handige online calculator gemaakt. Daarin kunnen concurrende declaraties worden ingevoerd om te achterhalen welke het zwaarst telt, en vooral waarom.

Probleem met SVG-achtergrond in IE

Wanneer je een SVG gebruikt als achtergrondafbeelding en die de hele container wilt laten bedekken (zoals op deze site de headerafbeelding), moeten in het SVG-bestand een breedte en hoogte zijn aangegeven. Ontbreken die, dan geeft Internet Explorer de afbeelding altijd volledig weer, maar zo geschaald dat de hele afbeelding in de container past. Het effect is het verschil in weergave tussen background-size: cover (wat je wilt) en background-size: contain (wat je krijgt).

In Chrome en Firefox treedt dit effect niet op.

Maak je de SVG in Adobe Illustrator met de de optie Responsief, dan open je daarna het SVG-bestand in een editor en pas je code aan. De waarden voor breedte en hoogte haal je uit het attribuut viewbox of enable-background. Na deze twee eigenschappen voeg je width en height toe, zoals in het voorbeeld:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 478.1 599" enable-background="new 0 0 478.1 599" width="478.1" height="599" xml:space="preserve"></svg>

Code uit boek

Voorbeelden van HTML- en CSS-code

Vrijwel alle codevoorbeelden uit het boek zijn beschikbaar, gerangschikt per hoofdstuk. Het lijkt misschien een allegaartje, maar zelf zie ik het meer als een snoeptrommel (of wat u ook associeert met heimelijk jeugdig gegraai). De komende tijd zal ik nog wat toelichtingen schrijven bij de bestanden; hier en daar vindt u in de code al wat opmerkingen. Deze code is gebruikt bij de productie van het boek en komt – behoudens correcties – overeen met wat u in het boek terugvindt, en meer.

Speel ermee, experimenteer en als niets meer werkt downloadt u de bestanden gewoon opnieuw.

Alle bestanden en noodzakelijk afbeeldingen zijn verzameld in een handzaam zipbestand (46 MB, inclusief het videobestand dat is gebruikt in hoofdstuk 5).
Er is ook een versie zonder video (10 MB).

Vragen

Achtergrond — Web Storage API

Van het begin af aan was het de bedoeling om op deze site vragen bij het boek op te nemen. Daarbij is het beschikbaar houden van de antwoorden de grootste uitdaging. Het is natuurlijk niet erg zinvol en zeker niet stimulerend als alle eerder gegeven antwoorden bij een volgend bezoek verdwenen zijn. Aanvullende eis: ik wil geen database met gebruiksaccounts optuigen. Er moet daarom een lokale opslagmogelijkheid zijn, op het systeem/in de browser van de bezoeker. Dat is precies wat mogelijk is met die andere kant van HTML5: de API's.

Naast nieuwe elementen zijn er HTML5-programmeerinterfaces, kortweg API of voluit Application Programming Interface genoemd. Via een API heeft een programmeur toegang tot de functies van een applicatie. Om bijvoorbeeld uw locatie op Google Maps te laten weergeven gebruikt u de Geolocation API. Voor de vragen en antwoorden op deze site willen we toegang tot de opslagmogelijkheden van de browser en daarvoor gebruiken we de Web Storage API.

JavaScript

Het opslaan en terughalen van gegevens uit de webopslag is niet mogelijk zonder programmeren. Hebt u daar geen enkele ervaring mee, dan zal het niet meevallen om het script te doorgronden. Hopelijk maken de praktische mogelijkheden van het voorbeeld u zo enthousiast dat u zich direct in JavaScript wilt gaan verdiepen. Lees daarom ook als niet-programmeur vooral het vervolg.

De Web Storage API is een mechanisme voor het veilig opslaan van sleutel-waardeparen. Iets dergelijks bestaat al jaren — cookies — maar Web Storage is flexibeler en eenvoudiger. De gegevens kunnen gedurende verschillende perioden worden opgeslagen:

  • totdat de browser of het tabblad wordt afgesloten: sessionStorage;
  • zolang als nodig, totdat ze worden verwijderd: localStorage.

Functionele eisen

De antwoorden op de vragen moeten beschikbaar zijn totdat de gebruiker ze zelf verwijdert en daarom kiezen we voor localStorage. Het voorbeeld is opgebouwd rond de volgende uitgangspunten:

  • er is een meerkeuzevraag, initieel is geen enkel keuzerondje ingeschakeld (niet beantwoord);
  • door een keuzerondje in te schakelen, wordt de vraag beantwoord;
  • het antwoord wordt direct opgeslagen;
  • bij een antwoord krijgt de gebruiker feedback: juist of onjuist;
  • met een knop kan het antwoord worden gewist;
  • bij het opnieuw laden van de pagina worden eerdere antwoorden opgehaald uit de localStorage;
  • van opgeslagen antwoorden worden de desbetreffende rondjes ingeschakeld;
  • van opgeslagen antwoorden wordt de feedback juist/onjuist hersteld.

Demovragen

Hieronder staan twee demovragen. Klik antwoorden aan, wis antwoorden, sluit het tablad en open de pagina opnieuw. U zult zien dat aan alle beschreven uitgangspunten is voldaan. Neem de broncode erbij en bekijk de HTML. Belangrijk is dat elk antwoord de attributen name en value heeft. Die vormen het sleutel-waardepaar. Voor de feedback heeft het juiste antwoord class="juist". De wisknop heeft als id dezelfde waarde als de naam van de antwoorden. Dat is nodig om de knop te koppelen aan vraag, zodat het juiste antwoord wordt gewist.

LocalStorage

Het script is in de kern eenvoudig. Met localStorage.setItem(naam, waarde) wordt een antwoord opgeslagen, met localStorage.removeItem(naam) wordt het verwijderd en met localStorage.getItem(naam) wordt het opgehaald. Alleen bij setItem zijn de naam en de waarde nodig; getItem en removeItem hebben genoeg aan de naam. Tot slot is er localStorage.clear(). Met deze opdracht worden alle gegevens voor dit domein gewist (niet in het voorbeeld opgenomen).

Het script

Nadat de pagina is geladen (window.onload) en alle elementen beschikbaar zijn, wordt het script uitgevoerd. Er worden eventlisteners gekoppeld aan de keuzerondjes en de knoppen, waarmee het in- en uitschakelen en het erop klikken worden gedetecteerd. Als reactie daarop worden functies uitgevoerd die de antwoorden opslaan en verwijderen, de fieldset groen markeren bij een juist antwoord en de laatste situatie herstellen als de pagina opnieuw wordt geladen. Het script is zeker geen voorbeeld van perfecte en efficiënte code, maar het doel ervan is dat u kunt zien wat er gebeurt. Het is daarom ruim voorzien van commentaar. U vindt de scriptcode aan het eind van de HTML-code. In onder meer Chrome DevTools kunt u naast de HTML- en JavaScript-code ook de inhoud van localStorage realtime bekijken (DevTools, tabblad Resources, Local Storage).

1 — Welk element is een leeg element?

2 — Welk element markeert een tabelrij?

Over het boek

Snel naar een beschrijving van het boek, de inhoudsopgave of bestelinformatie.

Beschrijving

Eind juni 2016 is de derde editie uitgebracht van het Handboek HTML5 en CSS3. In juli 2011 verscheen de eerste editie en in de jaren erna is er veel veranderd. De tweede editie uit maart 2015 was daarom een volledige herziening van de eerste en ook de opbouw werd aangepast. De derde editie borduurt daarop voort. Het is daardoor – nog steeds – een leerboek en naslagwerk ineen.

Opbouw

HTML en CSS worden na elkaar behandeld. Eerst leert u hoe u alle content markeert met HTML zodat de paginastructuur klopt. Daarna leert u hoe alle onderdelen op de pagina worden opgemaakt met CSS. Het uitgangspunt daarbij is dat u niet alleen leert dát dingen werken, maar vooral waaróm ze werken.

HTML

Met de specificatie van HTML5 als rode draad leert u eerst een HTML-document te structureren en alle onderdelen te markeren: paginakop, artikelkoppen, tekst, lijsten, hyperlinks, afbeeldingen, video en audio, tabellen en formulieren. Een goede paginastructuur is de beste garantie voor een geslaagde lay-out en opmaak met CSS. Daarom zijn voorbeelden opgenomen van verschillende typen webpagina’s: een eenvoudige persoonlijke pagina, een productpresentatie en een blog.

CSS

De tweede helft van het boek behandelt het opmaken en lay-outen met CSS. De basis daarvoor is ook vandaag nog CSS 2.1, de webstandaard uit 2011. Daar worden doorlopend nieuwe mogelijkheden aan toegevoegd en dat is wat gemakshalve CSS3 wordt genoemd. U leert onder meer hoe u lettertypen downloadt, tekst opmaakt, navigatiemenu’s vormgeeft, kleur gebruikt en achtergronden maakt. Tot slot wordt uitgelegd hoe u met responsive design flexibele lay-outs maakt die er op elk beeldscherm goed uitzien, van smartphone tot desktopscherm.

Meelezer Peter Kassenaar heeft het manuscript voorzien van waardevolle opmerkingen en suggesties, waarvoor ik hem erg dankbaar ben. Als er nu nog wat aan mankeert, komt dat volledig voor mijn rekening.

Inhoudsopgave

Dit is de inhoudsopgave van het Handboek HTML5 en CSS3:

  1. Webtalen, browsers en editors
  2. De basis van HTML5
  3. Tekst markeren
  4. Koppelingen maken
  5. Beeld, geluid en andere externe inhoud
  6. Tabellen maken
  7. Formulieren maken
  8. De basis van CSS
  9. Boxmodel, weergavemodel en positionering
  10. Tekst en typografie
  11. Kleur, randen en achtergronden
  12. Lay-outs maken met media queries en flexbox

Op deze site komen:

  • codevoorbeelden uit het boek;
  • aanvullende HTML- en CSS-voorbeelden;
  • onderwerpen waar in het boek geen ruimte voor was;
  • actuele HTML- en CSS-ontwikkelingen;
  • de onvermijdelijke verbeteringen.