Ensar Yufka

Proeftuin · 48 effecten in 8 families

Wat er allemaal kan

48 effecten, verdeeld over 8 families. Allemaal echt werkend op deze pagina, niet als plaatje. Bij elk effect staat wat het kost en waar het misgaat, want dat is de helft van het antwoord op de vraag of je het moet willen.

Geen enkele bibliotheek van buiten. Alles stopt zodra je besturingssysteem om minder beweging vraagt. Alles werkt zonder JavaScript, alleen dan zonder de beweging.

6 effecten

Scroll

Deze familie laat de scrollpositie van de bezoeker het werk doen: lagen die op verschillende snelheid meeschuiven, inhoud die opkomt op het moment dat je erbij bent en panelen die even blijven staan terwijl het verhaal doorloopt. Zet je hem in op lange pagina’s waar je richting en ritme wilt geven, niet op korte pagina’s met één boodschap, want daar kost het alleen maar hoogte en aandacht.

01

Lagen op verschillende snelheid

Achtergrondfoto, tekstkaart en voorgrondvel schuiven per scrollstap een andere afstand af, waardoor er diepte in het beeld komt. Bruikbaar voor een sfeerblok halverwege een pagina, waar je even wilt vertragen.

Kost: Per frame één rechthoekmeting en één custom property per paneel; de zware lagen krijgen een eigen compositielaag. Geen extra bestanden, wel iets meer geheugen op de GPU. De achtergrondfoto is 118 procent bij 132 procent van het raam, dus je laadt bewust meer pixels dan je ziet.
Let op: Twee klassieke fouten. Te grote verplaatsingen laten aan de randen de achtergrond doorschemeren, daarom staan de lagen ruim over maat. En tekst rechtstreeks op een foto is niet op contrast te controleren: hier staat de tekst daarom op een dekkend paneel in --grond-op, ruim boven 4,5 op 1. Bij prefers-reduced-motion wordt --sc-par-p met !important op 0 gezet, wat wint van de inline waarde die de JS eventueel al had geschreven.

Een rond vel yufka bakt op een hete plaat boven een vlam.

Vers gebakken

Drie lagen, drie snelheden. De plaat traag, dit kaartje sneller de andere kant op, het vel het snelst.

02

Voortgangsbalk bij een artikel

Een balkje in de vastgeplakte kop van het artikel dat aangeeft hoeveel je al gehad hebt, met een teller in procenten ernaast. Handig bij lange leespagina’s, waar mensen willen weten of ze bijna klaar zijn.

Kost: Bijna niets: een deling per frame en een scaleX in plaats van een width, zodat de browser geen layout hoeft te herberekenen. De waarde wordt alleen weggeschreven als het afgeronde percentage verandert.
Let op: De noemer verandert bij elke ladende afbeelding, elk vervangen lettertype en elke schermdraai, dus meet die niet eenmalig. Zonder JavaScript zou de balk voor eeuwig op nul staan; een meter die liegt is erger dan geen meter, daarom is hij achter html:not(.js) verborgen. In deze catalogus hangt hij aan een eigen scrollkader in plaats van aan het venster: een vaste balk bovenaan het scherm zou van alle families tegelijk zijn. Het kader is met de tab-toets bereikbaar en heeft role="region" met een label, anders kan een toetsenbordgebruiker er niet in.

Voorbeeldartikel

Dit kader scrolt zelf. Kijk naar het balkje in de kop hierboven: het vult zich terwijl je zakt en het blijft altijd in zicht, omdat de kop vastgeplakt staat aan de bovenkant van het kader.

Waarom hier en niet bovenaan het scherm

Op een gewone artikelpagina zet je zo'n balk vast bovenaan het venster. In deze catalogus zou dat een balk voor alle families worden, terwijl het effect maar bij dit ene blok hoort. De rekensom blijft dezelfde: de afstand die je al gescrold hebt, gedeeld door de afstand die er te scrollen valt.

Precies daar zit ook de valkuil. Die tweede waarde verandert zodra afbeeldingen laden, lettertypen wisselen of iemand het venster kleiner maakt. Meet je dat maar één keer, dan komt de balk nooit op honderd procent uit of staat hij al vol terwijl er nog tekst onder zit.

Voorbeeldtekst

Yufka is dun uitgerold deeg dat kort op een hete plaat gaat en daarna wordt gestapeld. De alinea's hieronder staan er alleen om dit kader vol te maken, zodat er iets te scrollen valt.

Een tweede regel demotekst, met genoeg woorden erin om een paar regels te vullen. Zo zie je onderweg dat het balkje gelijkmatig meeloopt en niet met sprongen vooruit schiet.

En nog een derde. Wie met het toetsenbord werkt kan dit kader met de tab-toets bereiken en daarna met de pijltjes of Page Down verder lezen. De balk loopt dan net zo goed mee.

Einde van het voorbeeldartikel. De balk staat nu op honderd procent en de teller ernaast laat hetzelfde zien.

03

Binnenkomen met vertraging

Een rij kaarten die pas opkomt als hij in beeld schuift, elk kaartje een tikje later dan zijn buurman. Goed voor een reeks gelijkwaardige items die je anders in één klap op de bezoeker afvuurt.

Kost: Eén IntersectionObserver, en per element precies één klasse. Zodra een kaart binnen is stopt de waarneming, dus de kosten lopen niet op met de lengte van de pagina.
Let op: De vertraging hoort in transition-delay te zitten en niet in een reeks setTimeouts, anders klopt de volgorde niet meer als iemand halverwege de rij binnenscrolt of snel terugscrolt. De beginstand staat achter html.js: zonder script staat de rij er gewoon, want anders maakt één mislukte scriptlading de pagina leeg. Bij prefers-reduced-motion wordt de klasse meteen op alles gezet en de overgang uitgezet, zodat er niets in een halve stand blijft hangen.

Vier kaarten, elk 110 ms later

  • Komt als eerste op

  • Dan deze

  • Daarna deze

  • En als laatste deze

04

Fotostrook die zijwaarts schuift

Een rij productfoto’s die naar links schuift terwijl jij naar beneden scrolt, met de sectie eromheen vastgeplakt. Sterk voor een assortiment of een reeks beelden die je niet in een raster wilt proppen.

Kost: De duurste van de zes: 260vh extra pagina, oftewel ongeveer anderhalf scherm aan scrollafstand dat verder niets doet. Verder één transform per frame en een ResizeObserver die de baanbreedte bijhoudt.
Let op: De pagina zelf mag nooit zijwaarts gaan, dus al het te brede zit in .sc-strook-kijk. Stuur je een tweede scroller aan met scrollLeft, dan gaat die met de gebruiker vechten zodra die zelf veegt; daarom draait dit op transform met het venster op overflow:hidden. Zonder JavaScript en bij prefers-reduced-motion valt hij terug op overflow-x:auto, verdwijnt de extra hoogte en verschuif je hem zelf, met de pijltjestoetsen of met een veeg. De tabindex hoort alleen bij die tweede stand, dus in de aangestuurde stand haalt de JS hem weg: een tabstop naar iets dat niet scrollt is een lege stop.

Voorbeeldkaart

De strook schuift zijwaarts terwijl je naar beneden scrolt

  • Stapel ronde vellen
  • Stapel vierkante vellen
  • Opgerolde vellen
  • Rond vel, licht van kleur
  • Rond vel, aan één kant gebakken
  • Rond vel, met bruine blaasjes
  • Rond vel, gelijkmatig gespikkeld

Het brede deel zit binnen de strook zelf, dus de pagina gaat nooit zijwaarts. Staat bewegen uit, dan verschuif je hem gewoon met de hand of met de pijltjestoetsen.

05

Paneel dat blijft staan terwijl de inhoud wisselt

Het beeld links blijft op zijn plek terwijl de stappen ernaast doorscrollen, en wisselt telkens als een volgende stap het midden van het scherm raakt. Bedoeld voor uitleg in stappen, een werkwijze of een productverhaal.

Kost: Drie afbeeldingen die alle drie geladen worden, ook al zie je er één tegelijk. Verder één IntersectionObserver en een klassenwissel. De stappen zijn samen ongeveer anderhalf scherm hoog, dat is de prijs van het vasthouden.
Let op: Dit blok kan niet in .doek staan: die heeft overflow:hidden en daarmee werkt position:sticky niet meer. Dim de niet-actieve stappen niet met opacity, want dan zakt de tekst onder de contrasteis; hier verschuift alleen het randaccent. De waarnemer werkt met een smalle band in het midden van het scherm, en bij twee tegelijk zichtbare stappen wint de bovenste, anders bepaalt de volgorde van de callbacks wie actief is en verschilt dat per browser. Bij prefers-reduced-motion blijft de wissel werken maar zonder overgang: het beeld hoort bij de stap die je leest, dus stilzetten zou de inhoud onjuist maken.

  1. Stap 1 van 3

    Het vel

    Het beeld blijft staan zolang deze stap in beeld is. Alleen de tekst schuift door, het paneel ernaast verroert zich niet.

  2. Stap 2 van 3

    De plaat

    Zodra deze stap het midden van het scherm raakt, wisselt het beeld. Er beweegt niets, er wordt alleen overgevloeid.

  3. Stap 3 van 3

    De stapel

    En bij de derde stap wisselt het nog een keer. De knoppen boven het beeld springen rechtstreeks naar een stap toe, ook met het toetsenbord.

06

Scroll-gestuurde CSS-animatie

Kaarten die opkomen terwijl ze in beeld schuiven, aangestuurd door animation-timeline: view() en dus volledig zonder JavaScript. De moderne opvolger van de waarnemer hierboven, met een terugval voor browsers die het nog niet kennen.

Kost: Nul bytes JavaScript en geen enkele meting in de hoofdthread; de browser rekent dit op de compositor uit. De prijs is dat je twee versies moet onderhouden en beide moet testen.
Let op: view() zoekt de dichtstbijzijnde scroller. Zet je dit in .doek, dan is dat .doek zelf vanwege overflow:hidden, en die scrollt nooit: de kaarten blijven dan op hun beginstand staan. Vandaar een eigen paneel. Alles staat in @supports (animation-timeline: view()), zodat de standaardtoestand de zichtbare terugval is en niet andersom. Het meldingsregeltje bovenin wisselt met dezelfde @supports mee, dus wat er staat klopt altijd met wat je ziet. Bij prefers-reduced-motion gaat de animatie uit en staat alles meteen op de eindstand.

Deze browser kent scroll-gestuurde CSS-animaties. De kaarten hieronder komen op zonder dat er ook maar één regel JavaScript aan te pas komt. Deze browser kent scroll-gestuurde CSS-animaties nog niet. Je ziet de terugval: de kaarten staan er gewoon, volledig leesbaar.

  • Geen script

    De browser koppelt de animatie zelf aan de scrollpositie, op de compositor.

  • Geen tijd

    De volgorde zit in het bereik, niet in een vertraging. Afstand vervangt hier de klok.

  • Nette terugval

    Kent de browser het niet, dan staat alles er meteen. Nooit een blok dat onzichtbaar blijft.

6 effecten

Tekst

Deze familie laat de typografie zelf het werk doen: letters die op hun beurt komen, dikte die met je meebeweegt, een woord dat zich vult en een foto die door de letters heen schijnt. Zet je in op plekken waar de tekst de hoofdrol speelt en een foto de aandacht juist zou wegtrekken, zoals een openingsscherm, een tussenkop of een korte kaartregel.

07

Letters die op hun beurt komen

De zin komt letter voor letter omhoog in plaats van in één keer. Fijn voor een openingsregel of een tussenkop die je even wilt laten landen, en met de knop speel je hem opnieuw af.

Kost: Geen extra bestanden en geen rekenwerk tijdens het scrollen: de trap zit in transition-delay, de browser regelt de rest. Wel wordt elke letter een eigen element, dus een lange alinea kost onnodig veel DOM. Houd het bij regels tot ongeveer veertig tekens.
Let op: Losse letters breken de zin voor een schermlezer aan stukken en halen ook de woordafbreking in de war. Daarom staan de letters op aria-hidden, zit elk woord in een eigen blokje dat niet mag afbreken, en staat de hele zin er nog een keer onzichtbaar bij. Zonder JavaScript of bij minder beweging verschijnt gewoon de hele zin, want de beginstand hangt aan een klasse die het script pas zelf zet.

Dun uitgerold, vers gebakken

08

Letterdikte die met je meebeweegt

Een golf van gewicht loopt door het woord: met de scroll van links naar rechts, en met een muis volgt hij je aanwijzer. Geeft een korte kop leven zonder dat er iets beweegt of verspringt.

Kost: Per frame wordt voor elke letter een gewicht berekend en weggeschreven. Dat is licht bij een korte regel en zwaar bij een alinea. De dikte verandert alleen de vorm van de letter, niet de regelval, dus er verspringt niets. Geen extra bestanden zolang je het font toch al laadt.
Let op: Niet elk font heeft een echte gewichts-as, en of het variabele bestand binnenkomt kun je niet aan de browser vragen. Het script meet het daarom: dezelfde proeftekst op wght 100 en op wght 900, en als de breedte niet verandert is er geen as. Dan valt het terug op stappen van 100 in font-weight, aangevuld met een haarfijne omtrek in dezelfde kleur zodat de overgang niet hakkelt. Op een touchscreen is er geen aanwijzer om te volgen; daar loopt de golf alleen met de scroll mee.

Van deeg tot vel

Scrol de pagina. Met een muis volgt de dikte je aanwijzer.

09

Omtrekwoord dat zich vult

Het woord staat er eerst als lijntekening en loopt van links naar rechts vol terwijl je scrollt. Werkt als opening van een blok waar de merknaam de blikvanger is.

Kost: Het woord staat er twee keer in de HTML, één keer als omtrek en één keer als vulling erbovenop. Verder alleen een clip-path die met de scrollpositie meeschuift, wat de browser op de grafische kaart afhandelt. Geen extra bestanden.
Let op: Een woord dat alleen uit dunne lijnen bestaat leest slecht, dus de omtrek is 2px in goud (7,7:1 op het paneel) en de vulling is lichtgoud (12:1). Kent de browser -webkit-text-stroke niet, dan blijft de vulling verborgen en staat er gewoon een massief goudkleurig woord in plaats van twee woorden over elkaar. Zonder JavaScript en bij minder beweging staat het woord meteen volledig gevuld. In hoog-contrastmodus wint de systeemkleur, anders zou het woord onzichtbaar worden.

Ensar

Vers gebakken

10

Doorlopende band

Een rij korte regels schuift onafgebroken van rechts naar links langs het paneel. Handig voor losse kernwoorden die geen eigen alinea verdienen.

Kost: De inhoud staat er dubbel in en het script plakt er op een breed scherm nog kopieën bij tot één helft breder is dan het paneel. Dat is eenmalig rekenwerk bij het laden en bij het verslepen van het venster, daarna beweegt alleen een transform. De duur wordt op de breedte berekend, zodat de snelheid op een telefoon en op een breed scherm gelijk is.
Let op: Bewegende tekst is lastig te lezen en te raken, dus er is een pauzeknop, en de band stopt ook vanzelf als je er met de muis overheen gaat of er met het toetsenbord in komt. De dubbele helft staat op aria-hidden, anders leest een schermlezer alles twee keer. Bij minder beweging schuift er niets: de band valt dan uiteen in gewone regels die netjes afbreken, zodat elk woord leesbaar in beeld staat in plaats van half buiten het paneel. Het paneel knipt de band af, dus de pagina kan hier nooit horizontaal van gaan schuiven.

Vers gebakken Dun uitgerold Yufka voor börek Yufka voor dürüm Yufka voor köy Voorbeeldtekst Ensar Yufka
11

Zin die zichzelf typt

Een vaste aanhef met daarachter een woordgroep die zich uittypt, even blijft staan, weer wist en verdergaat met de volgende. Geschikt voor één regel waarin je drie dingen wilt noemen zonder een opsomming te maken.

Kost: Een timer die per letter een stukje tekst wegschrijft, meeliftend op dezelfde animatielus als de rest. Staat het blok niet in beeld of ligt het tabblad op de achtergrond, dan stopt de lus vanzelf. De regel heeft een vaste minimumhoogte van twee regels, anders springt het paneel bij elke wisseling.
Let op: De getypte tekst wisselt continu en is voor een schermlezer waardeloos, dus die staat op aria-hidden en alle drie de woordgroepen staan er onzichtbaar als één zin bij. Een knipperende cursor moet te stoppen zijn (WCAG 2.2.2), vandaar de pauzeknop: die maakt de lopende zin eerst af en zet daarna ook het knipperen stil. Zonder JavaScript en bij minder beweging staat de eerste zin er compleet, met een cursor die stilstaat.

Vers gebakken yufka voor börek, yufka voor dürüm en yufka voor köy.

12

Foto door de letters heen

Een groot woord waarin een foto van de yufkavellen zichtbaar is, die tijdens het scrollen zachtjes tegen de richting in schuift. Bedoeld als openingsbeeld waar tekst en foto één ding worden.

Kost: Eén foto die je waarschijnlijk toch al laadt, en verder alleen een achtergrondpositie die met de scroll meeschuift. Let op de bestandsgrootte: de foto wordt over de volle breedte van het woord geschaald, dus een te kleine bron wordt zichtbaar wazig.
Let op: De kleuren in een foto liggen niet vast, dus het contrast van de letters ook niet. Daarom ligt er een lichte sluier over de foto: nagerekend haalt zelfs een zwarte pixel daarmee nog 4,86:1 op het paneel, terwijl het zonder die sluier naar 2,7:1 zakt en het woord onleesbaar wordt. De foto komt er pas in als de browser een achtergrond op tekstvorm kan knippen; kan hij dat niet, dan staat er een gewoon lichtkleurig woord in plaats van niets. In hoog-contrastmodus verdwijnt de foto en wint de systeemkleur. Het woord zelf staat op aria-hidden met de tekst er onzichtbaar naast, zodat een schermlezer geen losse regels voorleest.

Vers yufka

Voorbeeld, geen echte gegevens

6 effecten

Beeld

Deze familie laat een foto meer doen dan stilhangen: langzaam bewegen, opengeveegd worden, vergelijkbaar zijn en van kleur wisselen. Zet hem in waar het beeld zelf het verhaal draagt, en houd hem weg bij foto’s waar belangrijke tekst overheen moet.

13

Langzaam inzoomen op een foto

De foto zoomt heel traag in en schuift een klein stukje op, waardoor een stilstaand beeld toch leeft. Goed voor een kopbeeld waar verder weinig gebeurt.

Kost: Geen extra bestanden en vrijwel geen rekenwerk voor de processor, want alleen de laag zelf verschuift. Wel doorlopend tekenwerk op de videokaart, dus iets meer accugebruik. De foto moet groter zijn dan het kader, anders valt hij bij het inzoomen uit elkaar.
Let op: Zoom je verder dan ongeveer 1.2, dan ziet de bezoeker de foto zacht worden. Beweegt het te snel, dan wordt tekst erboven onrustig. Bewegend beeld dat vanzelf start hoort een stopknop te hebben, anders werk je mensen tegen die daar niet tegen kunnen; die knop zit hier onder de foto en verdwijnt zodra de bezoeker beweging heeft uitgezet.

Een bakker tilt een dun vel yufka op van een stapel op een houten werkbank. Vers gebakken

De uitsnede schuift langzaam op en zoomt heel licht in. Het etiket beweegt niet mee, zodat de tekst leesbaar blijft.

14

Onthullen met een veeg

De foto komt schuin open geveegd tevoorschijn zodra het blok in beeld schuift, met een gouden randje dat vooruit loopt. Geeft een reeks foto’s ritme zonder dat het druk wordt.

Kost: Eenmalig een clip-path die verschuift, dus verwaarloosbaar rekenwerk. Wel JavaScript nodig om te weten wanneer het blok in beeld komt, en dat gebeurt hier met een waarnemer in plaats van met meeluisteren op scrollen.
Let op: Zet nooit belangrijke tekst achter zo’n veeg. Gaat er iets mis met het script, dan blijft die tekst onzichtbaar. De beginstand staat daarom achter html.js: zonder JavaScript staat de foto er gewoon. Bij een andere beeldverhouding dan 3/2 moet de schuinte van het gouden randje mee veranderen, anders loopt het niet meer gelijk.

Een rond vel yufka bakt op een hete zwarte bakplaat boven een open vlam.

Zodra het blok in beeld komt, veegt de foto schuin open van links naar rechts. Een gouden randje loopt precies met de snijlijn mee.

15

Voor en na met een schuif

Twee foto’s over elkaar, met een greep waarmee je de bovenste opzij schuift. Handig om een verschil te tonen dat je in woorden lastig uitlegt.

Kost: Twee foto’s van hetzelfde formaat laden in plaats van een, dus ongeveer dubbele laadtijd voor dit blok. Het schuiven zelf verschuift alleen de snijlijn en wordt per beeldje samengevoegd, dus dat blijft soepel.
Let op: De twee foto’s moeten precies even groot zijn en hetzelfde uitgesneden, anders springt het beeld bij het schuiven. De grootste valkuil is een schuif die alleen met de muis werkt; deze is een gewone schuifregelaar, dus slepen, tikken, pijltjestoetsen en een schermlezer werken allemaal. Verticaal scrollen op een telefoon blijft mogelijk doordat alleen horizontaal slepen naar de schuif gaat.

Rond yufkavel na het bakken, met goudbruine blaasjes over het hele vel.
Rond yufkavel voor het bakken, egaal licht van kleur.
Voor Na

Sleep over de foto, tik op een plek, of zet de focus op de greep en gebruik de pijltjestoetsen links en rechts.

16

Tweekleur die kleur krijgt bij aanwijzen

De foto ligt in twee merkkleuren en springt naar de echte kleuren zodra je hem aanwijst of aanraakt. Houdt een raster met foto’s rustig en beloont wie erop reageert.

Kost: Een filter plus een kleurlaag per foto. Filters worden op de videokaart berekend; bij grote vlakken op een oudere telefoon kan de overgang zichtbaar haperen. Geen extra bestanden.
Let op: Op een aanraakscherm bestaat aanwijzen niet. Daarom is elke kaart een knop: aanraken houdt de kleur vast en met het toetsenbord kan het ook. Het aanwijzen zelf staat achter een media-vraag voor apparaten met een echte aanwijzer. Zonder die vraag blijft :hover op een telefoon na een tik plakken, en dan staat de foto in kleur terwijl de knop meldt dat hij niet is ingedrukt. Een mengstand kun je niet vloeiend laten overlopen, dus beweegt hier alleen de dekking van de kleurlaag. Zet nooit informatie alleen in het kleurverschil.

17

Korrel over de foto

Een fijne laag ruis en een zacht donker randje halen het vlakke, digitale gevoel van een foto af. Vooral zichtbaar op egale vlakken zoals een lichte muur.

Kost: De ruis is een SVG in het stijlbestand zelf: geen extra verzoek, ongeveer een halve kilobyte. De laag wordt wel over de hele foto getekend, dus houd het vlak niet groter dan nodig.
Let op: Te veel korrel maakt een foto vies en kan bij het comprimeren van de pagina lelijk uitpakken. Leg ruis nooit over leestekst. Het patroon schaalt niet mee met de foto, dus op een heel groot scherm oogt de korrel fijner dan op een telefoon.

Zacht licht in een bakkerij, met een houten werkbank en bloem op de voorgrond.

Een fijne laag korrel haalt het vlakke, digitale randje van een foto af. Zet hem uit en weer aan om het verschil te zien.

18

Foto die scherp wordt bij het laden

De foto begint wazig en iets kleiner en wordt scherp zodra hij binnen is. Daarmee voelt een pagina sneller, ook als de foto er even over doet.

Kost: Een blur over een grote foto kost tijdens het afspelen even rekenkracht op de videokaart. De tegels hebben een vaste verhouding en een eigen ondergrond, dus er verspringt niets terwijl er geladen wordt.
Let op: Op een snelle verbinding is de foto al binnen voordat je hem ziet en merk je van het effect niets; dat hoort zo. Laat een foto nooit onzichtbaar wachten op JavaScript, en laat een mislukte foto de rest niet blokkeren. Bij een echte site zet je hier een piepklein voorbeeldje onder in plaats van een blur op de foto zelf.

Gebakken yufkavel met gelijkmatig verdeelde goudbruine blaasjes. Rond yufkavel voor het bakken, egaal licht van kleur. Yufkavel dat aan een zijde gebakken is, de andere helft nog licht.

De foto’s beginnen wazig en iets kleiner en worden scherp zodra ze binnen zijn. Ze komen kort na elkaar, niet alle drie tegelijk.

6 effecten

Aanwijzer

Zes effecten die reageren op waar de aanwijzer is: kantelen, oplichten, rimpelen, volgen, glanzen en uitwijken. Zet ze spaarzaam in, want de aanwijzer kan maar op één ding tegelijk letten, en geef elk effect een variant voor schermen zonder muis, anders staat de helft van je bezoekers naar iets doods te kijken.

19

Kaart die kantelt onder de muis

De kaart draait mee met de aanwijzer alsof je hem in je hand houdt, en er loopt een lichtvlek over de foto op de plek waar de muis staat. Bruikbaar voor één uitgelicht product of één aanbeveling, niet voor een hele rij.

Kost: Twee draaiingen en een verloop, allemaal op de grafische kaart, dus vrijwel geen rekenwerk. Geen extra bestanden en geen extra hoogte. Wel een eigen compositielaag zolang de muis erboven staat, en dat vraagt wat geheugen op zwakkere machines.
Let op: Kantel je te ver, dan gaat de tekst zichtbaar scheef staan en leest de kaart slechter dan hij mooi is; hier is het 13 graden van de ene rand naar de andere. Hang de muisbeweging nooit aan de kaart zelf, want die schuift dan onder de aanwijzer vandaan, valt eronderuit, springt terug en gaat trillen. Het effect luistert daarom naar de wikkel eromheen, die zelf stil blijft staan. Op een aanraakscherm bestaat de beweging niet, dus staat daar een vaste lichtval in plaats van een dode kaart.

Bakker tilt een vel yufka op

Voorbeeldkaart

Vers gebakken

Beweeg de muis over de kaart. Op een aanraakscherm staat hij recht, met een vaste lichtval.

20

Rand die oplicht waar de muis is

Alleen de omlijning van de kaart licht op, en precies op het stuk dat het dichtst bij de aanwijzer ligt. Handig om in een rij kaarten te laten zien waar je bent zonder de kaart zelf te laten bewegen.

Kost: Eén extra laag per kaart, uitgehold met twee maskers over elkaar. Bij drie kaarten worden er per beeldje drie afstanden herrekend; dat merkt niemand. Oudere browsers kunnen twee maskers niet samenvoegen, dus er hoort een terugval bij.
Let op: De verleiding is groot om de gloed achter de tekst te laten schijnen. Dan zakt het contrast op het lichtste punt onder de norm en wordt de kaart precies op het verkeerde moment slecht leesbaar; daarom licht hier alleen de lijn op. Zonder muis is er geen plek om naartoe te lichten, dus krijgt elke kaart dan een vaste gloed aan de bovenrand. Wie tabt in plaats van wijst, ziet dezelfde kaart oplichten.

Kaart een

De rand licht op waar de aanwijzer is.

Kaart twee

De rand licht op waar de aanwijzer is.

Kaart drie

De rand licht op waar de aanwijzer is.

21

Rimpel vanaf de plek van de klik

Een ring die uitdijt vanaf het punt waar je klikt of tikt en tegelijk vervaagt. Het is de goedkoopste manier om te bevestigen dat een klik is aangekomen, vooral als er daarna even niets zichtbaars gebeurt.

Kost: Per klik één element erbij dat zichzelf na 0,6 seconde opruimt, plus een vangnet voor als de animatie nooit afmeldt. Geen extra bestanden. De knop moet zijn inhoud afsnijden, dus die krijgt een eigen laag.
Let op: Als pseudo-laag kan er maar één rimpel tegelijk aan, en dan slikt de knop je tweede klik; daarom is het een echt element. Vergeet het toetsenbord niet: enter en spatie hebben geen aanwijspositie, dus daar begint de rimpel in het midden. En bij minder beweging wisselt de knop alleen kort van kleur, want ook dan wil iemand antwoord op zijn klik.

Klik of tik ergens op een knop: de rimpel begint op de plek die je raakt. Met enter of de spatiebalk begint hij in het midden.

22

Stip die de muis met vertraging volgt

Een open ring die achter de aanwijzer aan loopt en groter wordt zodra hij boven een knop of link komt. Werkt als sfeer op een portfolio of landingspagina, en zelden ergens waar mensen moeten werken.

Kost: Een lus die draait zolang de muis beweegt en stopt zodra de ring is bijgetrokken; daarna kost een stilstaande muis niets. Drie waarden per beeldje, geen extra bestanden, geen extra hoogte.
Let op: Verberg de echte muisaanwijzer niet. Zodra iemand iets kleins moet raken kost de vertraging precisie, en dat merkt hij pas als hij misklikt; daarom is dit een open ring waar de pijl gewoon doorheen te zien is. De ring blijft ook binnen dit ene vlak in plaats van over de hele pagina te zwerven. Op een aanraakscherm, zonder JavaScript en bij minder beweging staat er een regel die uitlegt waarom er niets volgt, in plaats van een leeg vlak waarvan je denkt dat het stuk is.

Beweeg de muis over dit vlak

De ring loopt iets achter op de aanwijzer en wordt groter zodra hij boven een knop komt. De echte muisaanwijzer blijft staan; je ziet hem dwars door de ring heen.

Dit scherm heeft geen muisaanwijzer, dus is de ring uitgeschakeld. De knoppen hierboven werken gewoon.

Je systeem vraagt om minder beweging, dus volgt er geen ring.

Zonder JavaScript is er geen ring; dan blijft alleen de gewone muisaanwijzer over.

23

Glansstreep die over de knop trekt

Een schuine lichtstreep die één keer over een knop of kaart trekt zodra je erover gaat. Genoeg om een knop als de belangrijkste van de pagina aan te wijzen, zonder hem te laten springen.

Kost: Volledig CSS, geen regel JavaScript. Eén schuine laag met een verloop en een animatie van 0,85 seconde. Het vlak moet zijn inhoud afsnijden, dus de knop krijgt een eigen laag.
Let op: Laat de streep onder de tekst door lopen en niet eroverheen, anders is het opschrift een halve seconde slecht leesbaar. Gebruik een animatie en geen overgang, want een overgang draait bij het weghalen van de muis terug en dan trekt de streep achterstevoren over de knop. Op een aanraakscherm blijft hover na het tikken hangen, dus daar hangt de streep aan het indrukken zelf. Bij minder beweging blijft alleen een lichtere knop over.

24

Rij die uitwijkt voor de aanwijzer

De tegel onder de muis komt omhoog en wordt groter, en zijn buren wijken opzij en doen een beetje mee. Goed voor een korte rij gelijkwaardige dingen, zoals smaken of categorieën.

Kost: Vijf tegels doorrekenen per beeldje, alles met transform. Extra hoogte: ongeveer 3 rem boven de rij, want de tegels groeien omhoog, plus de regel bijschrift eronder. Geen extra bestanden.
Let op: Doe dit nooit met breedte of marge, want dan herberekent de browser bij elke muisbeweging de hele rij en gaat de pagina schokken. Met transform verandert de opmaak niet, dus er komt ook nooit een horizontale schuifbalk bij. Op een smal scherm breekt de rij af in twee regels; daarom weegt de afstand naar boven en beneden zwaarder, anders beweegt de onderste regel mee met een muis op de bovenste. Het bijschrift onder elke tegel staat er altijd en is meteen de naam van de knop; een naam die alleen bij hover verschijnt is op een aanraakscherm nergens te vinden. Met de tab-toets gebeurt precies hetzelfde als met de muis.

  • Voorbeeld 1
  • Voorbeeld 2
  • Voorbeeld 3
  • Voorbeeld 4
  • Voorbeeld 5

De tegel onder de aanwijzer komt op, de buren wijken uit. Met de tab-toets gebeurt precies hetzelfde.

5 effecten

Diepte en 3D

Deze familie geeft platte blokken een echte ruimte mee: vlakken die kantelen, lagen die achter elkaar liggen en panelen die opengaan. Zet hem in waar je iets wilt tonen dat twee kanten of meerdere lagen heeft, en houd hem weg bij lange leesteksten, want daar kost de diepte alleen maar leesgemak.

25

Kaart die omdraait

Een kaart met een voorkant en een achterkant die om zijn as draait zodra je op de knop eronder drukt. Handig voor een prijs, een korte toelichting of een tweede foto die je niet meteen in beeld wilt hebben.

Kost: Vrijwel niets aan rekenwerk: de browser doet de draai op de grafische kaart. Geen extra bestanden, geen extra hoogte, en de kaart houdt in beide standen precies dezelfde plek op de pagina.
Let op: Zet je backface-visibility niet op hidden, dan schemert de achterkant spiegelbeeldig door de voorkant heen en lijkt de tekst dubbel. Verder is de verborgen kant nog steeds gewoon aanwezig in de pagina: zonder aria-hidden leest een schermlezer beide kanten achter elkaar voor en klinkt de kaart als onzin. Zet aria-hidden dan wel alleen op de kant die echt uit beeld is, want in de platte terugval staan beide kanten onder elkaar en zou je zichtbare tekst wegnemen. En stop de kaart nooit in een button: alles binnen een knop geldt als versiering, dus de koppen en de tekst op de kaart verdwijnen uit de voorleesboom en er blijft alleen het label van de knop over. De kaart is hier gewone inhoud en de losse knop eronder draait hem om, met aria-expanded en aria-controls naar de achterkant.

Voorbeeldkaart Vers gebakken Achterkant Ruimte voor uitleg, een korte omschrijving of een verwijzing. Draai de kaart nog een keer om terug te gaan.

Druk op de knop om de kaart om te draaien. De kant die niet in beeld staat wordt ook niet voorgelezen.

26

Lagen die uit elkaar schuiven

Vier vellen liggen precies op elkaar en waaieren tijdens het scrollen naar voren en naar achteren uit elkaar. Goed om te laten zien dat iets uit meerdere lagen bestaat, bijvoorbeeld een opbouw of een pakket.

Kost: Kost ongeveer twee schermhoogtes extra pagina, want die ruimte is de speelruimte waarover de lagen bewegen. Per frame wordt er eenmaal gemeten en wordt er een getal weggeschreven; de vier verschuivingen zelf doet de CSS. Geen extra bestanden.
Let op: Deze demo staat bewust niet in het standaard paneel: dat heeft overflow hidden en daarmee werkt position sticky er niet meer, want een clippende voorouder wordt zelf de scrollcontainer. Verder is de valkuil de beginstand. Staat die op ingeklapt en gaat er iets mis met het script of staat minder beweging aan, dan zie je drie van de vier lagen nooit. Daarom is uit elkaar de basis en is op elkaar de uitzondering.

Vier lagen, een stapel

Scrol verder en de vier lagen schuiven uit elkaar.

27

Fotorij in perspectief

Een rij foto's waarbij de middelste recht naar je toe staat en de buren weggedraaid en naar achteren staan. Prettig voor een reeks beelden waarin er telkens een de hoofdrol heeft.

Kost: Bij elk frame tijdens het schuiven worden de posities van alle kaarten opgemeten. Bij vijf tot een stuk of tien kaarten is dat te verwaarlozen; bij vijftig zou je de rij moeten opdelen. De rij scrolt in zijn eigen vak, dus de pagina zelf gaat nooit opzij.
Let op: Perspectief op de scrollcontainer zelf laat het verdwijnpunt met de scrollpositie meelopen, waardoor de rij scheef gaat staan; daarom krijgt elke kaart zijn eigen perspectief. De randvulling staat op de rij en niet op de scroller, omdat een scrollcontainer zijn eindpadding in meerdere browsers weglaat en de laatste foto dan nooit in het midden komt. Wordt de hele kaart doorzichtiger gemaakt om hem naar achteren te laten lijken, dan zakt ook het contrast van het bijschrift onder de norm; hier ligt de sluier daarom alleen over de foto.

28

Paneel dat openvouwt

Twee helften die om hun gedeelde middenrand scharnieren: dicht ligt de kaft op de onderste helft, open klapt hij weg en lees je beide binnenkanten. Bruikbaar voor een aankondiging, een pakket of een uitnodiging die zich openvouwt.

Kost: Eén overgang van acht tienden van een seconde, verder niets. Het paneel heeft wel een vaste hoogte nodig, want de twee helften moeten exact even hoog zijn. Geen extra bestanden.
Let op: Zijn de helften niet precies even hoog, dan valt de kaft er net naast en zie je een randje van de laag eronder. Twee gelijke rijen in een raster met een vaste hoogte lost dat definitief op; met automatische hoogte of aspect ratio klopt het net niet. De kaft ligt daarnaast een pixel voor de onderste helft, anders liggen twee vlakken op exact dezelfde diepte en gaan ze flikkeren zodra je scrolt. En bedenk dat de inhoud dicht wel in de pagina staat maar niet zichtbaar is: zonder aria-hidden leest een schermlezer tekst voor die niemand ziet. Draai die regel niet blind om: in de platte terugval valt de kaft weg en staan beide binnenkanten gewoon in beeld, dus daar hoort er niets verborgen te worden.

Binnenkant boven Deze kant lag tegen de onderste helft aan en komt pas tevoorschijn als het paneel opengaat. Bakker tilt een vel yufka op Voorbeeldpakket Gesloten paneel

Binnenkant onder

Ruimte voor een korte omschrijving of een oproep.

29

Draaiend prisma met foto's

Vier foto's op de zijkanten van een blok dat langzaam om zijn as draait en stilstaat zodra je er met de muis over gaat of ergens binnen focus zet. Leuk als rustige blikvanger met een handvol beelden.

Kost: De draaiing is een gewone CSS-animatie en loopt buiten de hoofddraad om, dus die is bijna gratis. Vier foto's wel altijd laden, ook de twee die je op dat moment niet ziet. Reken op ongeveer anderhalf keer de zijdebreedte aan ruimte, want op zijn breedst steekt het blok verder uit dan een zijde.
Let op: Hover bestaat niet op een aanraakscherm, dus zonder pauzeknop kan een deel van je bezoekers het ding nooit stilzetten. Laat de toestand door één ding dragen: het opschrift wisselt tussen pauzeren en hervatten, en dan hoort er geen aria-pressed bij, anders klinkt het als "Draaien hervatten, knop, ingedrukt" en spreekt de knop zichzelf tegen. De tweede valkuil zit in de bediening: als de knoppen aan dezelfde transform trekken als de animatie, springt het blok terug naar nul zodra je stapt. Hier houdt een buitenste laag de automaat vast en een binnenste de handmatige stand, en bij het overstappen wordt de stand van de animatie eerst uitgelezen en overgenomen. Bijschriften op de vlakken worden door het perspectief iets uitvergroot; met een ruime perspectiefwaarde blijft die vergroting onder een tiende en blijft de tekst scherp.

Zijde 1
Zijde 2
Zijde 3
Zijde 4
7 effecten

Micro-interacties

Deze familie bevat de kleine reacties waarmee een pagina laat merken dat hij je gehoord heeft: een knop die van toestand verandert, een schakelaar die omgaat, een veld dat meteen zegt wat er mis is. Je zet ze overal in waar iemand iets doet en op antwoord wacht, want zonder die reactie klikt een bezoeker twee keer of hij haakt af.

30

Knop met alle toestanden

Dezelfde knop naast elkaar in zeven standen: rust, hover, ingedrukt, focus, bezig, gelukt en uitgeschakeld. Je gebruikt dit overzicht om af te spreken hoe elke knop op de site zich hoort te gedragen, voordat er honderd losse varianten ontstaan.

Kost: Geen rekenwerk en geen extra bestanden; het is puur CSS plus ongeveer veertig regels JavaScript voor de volgorde bezig naar gelukt. Wel extra hoogte: vanaf ongeveer 1180px staan alle zeven naast elkaar, op 360px vallen ze in twee kolommen en is het paneel rond de 510 pixels hoog, zo'n twee derde telefoonscherm.
Let op: De klassieke fout is de uitgeschakelde knop op opacity 0.4 zetten; goud op donker zakt dan naar ongeveer 2:1 en niemand kan meer lezen waar hij niet op mag klikken. Hier is de uitgeschakelde stand een eigen kleur die 5,28:1 haalt. Tweede valkuil: tijdens bezig het echte disabled-attribuut zetten. De browser haalt dan de focus van de knop af en wie met het toetsenbord werkt staat opeens weer bovenaan de pagina, daarom staat er aria-disabled.

  • Rust, knop Bestellen zoals hij standaard staat
  • Hover, knop Bestellen met de muis erboven
  • Ingedrukt, knop Bestellen op het moment van de klik
  • Focus, knop Bestellen met de toetsenbordring eromheen
  • Bezig, knop wacht op antwoord
  • Gelukt, knop bevestigt dat het is verwerkt
  • Uitgeschakeld
Probeer zelf

31

Schakelaar die echt een vinkvakje is

Een schuifje dat van links naar rechts loopt, maar onderhuids gewoon een input type checkbox is. Je gebruikt het voor instellingen die meteen gelden, en niet voor iets dat pas na een knop Opslaan gebeurt.

Kost: Nul JavaScript en nul extra bestanden. Twee CSS-regels voor de knop en de kleur van het spoor; verder doet de browser het werk.
Let op: Een schakelaar die met een div en een klikluisteraar is nagebouwd, kent geen spatiebalk, geeft zijn stand niet door aan een schermlezer en verdwijnt uit een formulier. Let ook op de rand van het spoor: met de standaard lijnkleur van .14 haalt die maar 2,4:1 op de donkere achtergrond en zie je het uit-standje bijna niet, daarom staat hier een eigen rand van 4,0:1. De stand staat er bovendien in woorden bij, want alleen kleur en positie is te weinig.

Te bedienen met de muis, met een tik, en met Tab plus de spatiebalk. De stand staat er ook in woorden bij, niet alleen in kleur en positie.

32

Skelet dat overgaat in inhoud

Grijze blokken in de vorm van de kaart die eraan komt, die na het laden door de echte kaart worden vervangen. Je zet dit in bij inhoud die betrouwbaar binnen een paar seconden binnen is; duurt het langer, dan is een tekstregel met uitleg eerlijker.

Kost: Vrijwel niets aan rekenwerk. De glans is één verschuivende gradient. Wel let op: het skelet is extra markup die op elke pagina meelaadt, en de foto is 620 bij 620 en heeft daarom width en height nodig zodat de ruimte al klaarstaat.
Let op: Hier gaat het bijna altijd mis met de sprong: bones die je met de hand op maat brengt kloppen precies bij één schermbreedte en nergens anders, want de tekst eronder wisselt van twee naar drie regels. Daarom wisselen skelet en kaart elkaar niet af maar liggen ze op elkaar; de hoogte komt altijd van de echte kaart en de kaart wordt tijdelijk op visibility hidden gezet in plaats van weggehaald. Tweede punt: een skelet is geen mededeling. Daarom staat er ook een regel in een aria-live gebied die zegt dat er geladen wordt en dat het klaar is, en staat aria-busy op de kaart. Zonder JavaScript wordt het skelet nooit getoond en staat de echte kaart er meteen.

Voorbeeldkaart

Stapel dunne vellen yufka

Vers gebakken vellen

Voorbeeldkaart met demotekst.

Voorbeeld, geen echte gegevens.

33

Melding die vanzelf verdwijnt

Een kort bericht dat rechtsonder binnenschuift, een balkje aftelt en dan weggaat. Bedoeld voor bevestigingen die je mag missen, nooit voor iets dat de bezoeker echt moet lezen.

Kost: Licht. De afteller is een CSS-animatie in plaats van een tweede klok in JavaScript, dus pauzeren bij hover kost geen extra regel. Geen extra bestanden. Er staan maximaal drie meldingen tegelijk, anders duwen ze de knoppen eronder weg.
Let op: Vijf seconden is voor veel mensen te kort om te lezen, zeker met een schermvergroter. Daarom pauzeert de afteller bij hover en bij focus binnen de melding, en zit er altijd een sluitknop op. Het live-gebied is polite en niet assertive: assertive onderbreekt de schermlezer midden in een zin. Staat de rustige stand aan, dan verdwijnt de aftelbalk helemaal, want een stilstaande balk liegt over de resterende tijd. Sluit iemand een melding waar de focus in zat, dan gaat de focus terug naar de knop die hem opriep.

  • Voorbeeldmelding Deze blijft staan, ook zonder JavaScript.
34

Uitklapbaar blok met vloeiende hoogte

Een vraag die je openklapt, waarbij het antwoord van nul naar zijn eigen hoogte groeit. Handig voor veelgestelde vragen en voor details die niet iedereen hoeft te zien.

Kost: Geen rekenwerk: de hoogte komt uit grid-template-rows die van 0fr naar 1fr loopt, dus er wordt nergens een pixelhoogte gemeten. Ongeveer dertig regels JavaScript, en die zijn alleen nodig om het dichtklappen ook vloeiend te maken.
Let op: De browser haalt de inhoud er bij het sluiten meteen uit, dus zonder ingreep animeert alleen het openen en klapt het dicht met een schok. Hier houdt JavaScript het sluiten kort tegen. Er zit een vangnet op van 600 ms: draait de overgang niet, bijvoorbeeld in een achtergrondtabblad, dan klapt het blok alsnog dicht in plaats van halverwege te blijven staan. Kan een browser 0fr niet animeren, dan valt hij via @supports terug op direct open en dicht: lelijker, nooit onleesbaar.

Waarom groeit dit blok vloeiend?

Voorbeeldtekst. Het blok gaat van nul naar precies de hoogte die de inhoud nodig heeft, zonder dat die hoogte vooraf in JavaScript is uitgerekend. Daardoor blijft het kloppen als de tekst langer wordt of als iemand een grotere letter instelt.

Werkt dit zonder JavaScript?

Voorbeeldtekst. Ja. Dit is een details met een summary, dus openen en sluiten doet de browser zelf, inclusief de aankondiging aan hulpsoftware. JavaScript voegt alleen de vloeiende beweging bij het dichtklappen toe.

En als animaties uit staan?

Voorbeeldtekst. Dan klapt het blok direct open en dicht. De inhoud blijft volledig leesbaar; er is geen enkele stand waarin de tekst onzichtbaar blijft hangen.

35

Veld dat meteen meekijkt

Een invoerveld dat tijdens het typen laat zien of het goed gaat, met de standen bezig, goed en fout. Zet het in bij velden waar mensen vaak iets verkeerd invullen, zodat ze het weten voordat ze op verzenden drukken.

Kost: Nauwelijks iets. Een controle die pas 450 ms na de laatste toetsaanslag start, geen extra bestanden, geen netwerkverkeer in deze demo. De hoogte van de meldingsregel staat vast, dus het toevoegen kost geen extra sprong.
Let op: Bij elke aanslag oordelen betekent dat iemand bij het typen van de eerste 1 al te horen krijgt dat het fout is; daarom wacht de controle tot het typen stilvalt en oordeelt hij bij het verlaten van het veld direct. De fout staat voluit in woorden met het juiste formaat erin, want een rode rand vertelt niet wat er moet gebeuren en voor wie rood niet onderscheidt vertelt hij helemaal niets. De melding zit via aria-describedby aan het veld vast en aria-invalid gaat mee, anders hoort een schermlezergebruiker de fout alleen als hij toevallig langs de regel scrollt.

Vier cijfers en twee letters. Typ 1234 AB voor de goede stand, of 12 voor de foutstand.

36

Kopieerknop die het bevestigt

Een knop naast een stukje tekst die de tekst naar het klembord zet en daarna kort Gekopieerd toont. Gebruik het bij alles wat mensen anders met de muis moeten selecteren.

Kost: Zeer licht. Geen extra bestanden, de iconen zijn inline SVG van een paar regels. De terugval met een tijdelijk tekstvak wordt alleen gebouwd als de Clipboard API ontbreekt.
Let op: De Clipboard API werkt alleen op https en kan door de gebruiker geweigerd worden; slikt de knop die weigering stil door, dan denkt iemand dat hij de tekst heeft en plakt hij iets ouds. Hier selecteert de mislukking de tekst en vraagt hij om Ctrl+C of Cmd+C. Een tweede punt: het vinkje op de knop is stil voor een schermlezer, dus de bevestiging staat ook als tekst in een aria-live gebied. De knop keert na 2,2 seconden terug naar Kopieer, zodat je hem opnieuw kunt gebruiken.

Voorbeeldreferentie VOORBEELD-1234
Voorbeeldbestelling 4 pakken yufka, ophalen om 12:00

6 effecten

SVG en lijnen

Deze familie tekent met vectoren in plaats van met plaatjes: paden die zichzelf trekken, vormen die in elkaar overlopen, lijnen waar licht doorheen glijdt en ringen die een getal laten zien. Zet hem in waar een foto te zwaar of te letterlijk is, en waar een lijn precies scherp moet blijven op elk scherm.

37

Lijn die zichzelf tekent tijdens het scrollen

Een tekening van een deegroller en een vel yufka verschijnt streek voor streek terwijl je naar beneden scrolt. Sterk als opening van een pagina of boven een verhaal over het ambacht, omdat het oog de lijn vanzelf volgt.

Kost: Rekenwerk is laag: de padlengte wordt eenmalig gemeten met getTotalLength(), daarna verandert er per frame alleen een stroke-dashoffset. Dat is een eigenschap die de browser op de compositor afhandelt, dus geen layout. Geen extra bestanden, geen extra hoogte, geen laadtijd. De SVG zelf is ongeveer 1 kB.
Let op: De lengte moet gemeten worden, nooit geschat: zit de dasharray er twintig eenheden naast, dan blijft er een stukje lijn onafgetekend of springt de tekening aan het eind. Gebruik hier ook geen vector-effect:non-scaling-stroke, want dan rekent de browser de streeplengte in schermpixels terwijl het pad wel meekrimpt, en op een telefoon tekent de lijn dan nooit vol. Staat dit blok helemaal onderaan een pagina, dan is er te weinig scrollruimte over om af te maken; daarom zet het script alles op 100% zodra de bezoeker de onderkant van de pagina bereikt.

Lijntekening van een deegroller boven een rond vel yufka

Padlengte, opgemeten door de browser: nog niet gemeten. Getekend: 100%

38

Vorm die overgaat in een andere vorm

Een rond vel wordt een gevouwen driehoek en daarna een opgerolde rol, in een vloeiende beweging. Handig om drie producten of drie stappen te laten zien zonder dat er drie plaatjes voor nodig zijn.

Kost: Kan de browser d: path(), dan kost het niets: de overgang loopt volledig in CSS. Kan hij dat niet, dan schrijft het script 26 getallen per frame in het d-attribuut, wat neerkomt op een paar tienden van een milliseconde. Geen extra bestanden. Wel drie keer hetzelfde pad in de opmaak: ongeveer 400 bytes extra.
Let op: De twee vormen moeten exact dezelfde opbouw hebben, hier steeds een M, vier keer een C en een Z, dus 26 getallen. Verschilt dat aantal, dan is er niets te interpoleren en klapt de vorm om in plaats van dat hij overloopt. Het script controleert dat en doet liever niets dan iets lelijks. Sturing loopt via echte radioknoppen, dus de demo werkt ook zonder JavaScript en is met de pijltjestoetsen te bedienen.

Vorm die overgaat van een rond vel naar een gevouwen driehoek en naar een opgerolde rol

Alle drie de vormen hebben evenveel punten, daarom loopt de overgang vloeiend en niet met een sprong.

39

Pictogrammen die kort tot leven komen

Een pijl, een klok en een doos die een korte beweging maken zodra je erover gaat, erop tikt of er met de tabtoets langs loopt. Bedoeld voor rijtjes met verzenden, openingstijden en bezorging, waar een klein teken van leven de aandacht op de juiste tegel legt.

Kost: Alleen CSS-animaties op transform en stroke-dashoffset, dus geen layout en geen herteken-werk buiten de tegel. Elk pictogram is een handvol lijnen, samen ongeveer 1 kB inline. Het script voegt alleen een klasse toe na een tik en verder niets.
Let op: Op een aanraakscherm blijft :hover na een tik hangen, waardoor het pictogram in de aan-stand blijft staan. Daarom zit hover achter (hover:hover) and (pointer:fine) en krijgt een tik zijn eigen klasse. Bij het opnieuw starten van dezelfde animatie moet de klasse eerst weg en moet de layout even geforceerd worden uitgelezen, anders ziet de browser geen verandering en gebeurt er bij de tweede tik niets. Draaiende onderdelen hebben een expliciete transform-origin nodig, anders draaien ze om het midden van de viewBox in plaats van om hun eigen scharnier.

Beweeg er met de muis overheen, tik erop, of loop er met de tabtoets langs.

40

Gestippelde route met een stip die eroverheen loopt

Een gestippelde lijn van de bakkerij naar de deur, met een stip die de weg aflegt en een gouden lijn die precies gelijk meeloopt. Geschikt voor een bezorgpagina of een stappenplan waar je wilt laten zien dat er beweging in zit.

Kost: Volledig CSS, dus het draait ook door als het script niet laadt. Twee oneindige animaties op stroke-dashoffset, wat de browser op de compositor afhandelt. De SVG is ongeveer 1 kB. Wel drie keer hetzelfde pad in de opmaak: ondergrond, gouden vullijn en stip.
Let op: Alles hangt aan één getal, de lengte van het pad. Die is hier vooraf numeriek uitgerekend (641,84 eenheden) zodat de animatie ook zonder JavaScript klopt, en het script meet hem daarna nog eens op omdat elke engine bezierlengtes net iets anders afrondt. Zit dat getal ernaast, dan komt de stip te vroeg aan of blijft er een stuk lijn ongevuld. De valkuil die je pas ziet als je goed kijkt: laat de stip eindigen op 99,8 procent van de lengte en niet op 100 procent, want bij precies -1 begint de streep exact op het eindpunt en valt hij er nog nét buiten, waardoor de stip de laatste vijfde van elke ronde spoorloos is. Laat de gouden lijn en de stip aan het eind ook even uitdoven, anders springt de lus met een harde knip terug naar leeg. De route blijft rondlopen, dus er hoort een pauzeknop bij: die zet de vullijn en de stip in dezelfde tel stil, zodat ze bij het hervatten nog steeds gelijk lopen.

Gestippelde route waarover een stip van de bakkerij naar de voordeur loopt
  • Bakkerij
  • Bij jou aan de deur

Voorbeeldroute. De stip legt de hele lijn af en de gouden lijn loopt precies gelijk mee.

41

Lijn met een kleurverloop dat erlangs beweegt

Drie scheidingslijnen waar een gouden glans doorheen trekt, alsof er licht overheen strijkt. Mooi onder een kop of tussen twee blokken, waar een gewone streep te vlak zou zijn.

Kost: Eén CSS-animatie op transform, de goedkoopste soort die er is. Het masker kost de browser een extra tekenlaag, wat op een oud toestel merkbaar kan zijn als je er tien op één pagina zet; bij een handvol is het niets. Geen script, geen extra bestanden, ongeveer 1,2 kB inline.
Let op: Het verloop zelf beweegt niet, de baan eronder schuift; het masker zit daarom op een groep zonder eigen transform, want een masker verschuift mee met de transform van het element waar het op staat en dan zou de hele lijn wegglijden. De verschuiving is exact één periode van 300 eenheden en het verloop staat op spreadMethod repeat, anders zie je bij elke ronde een sprong. Onder het masker ligt een doffe kopie van dezelfde lijnen, zodat er ook een nette streep staat als een engine het masker niet tekent. Ook deze glans loopt in een lus door, dus er staat een pauzeknop onder om hem stil te zetten.

Vers gebakken

Het verloop staat stil, de baan eronder schuift. Precies één periode per ronde, dus de lus is naadloos.

42

Cirkel die een percentage vult

Drie ringen die zich vullen zodra ze in beeld komen, met het getal groot in het midden. Bruikbaar voor voortgang, een verdeling of een score, overal waar een balk te saai is en een taartdiagram te veel.

Kost: Eén korte animatie van ruim een seconde per set ringen, daarna staat alles stil. Het script schrijft per frame een stroke-dashoffset en een getal: verwaarloosbaar. Geen extra bestanden. Elke ring is ongeveer 350 bytes inline.
Let op: De omtrek moet uit de straal komen (2 x pi x r, hier 339,292 bij r=54) en niet uit een rond getal, anders sluit de ring net niet of schiet hij er net overheen. De cirkel moet 90 graden gedraaid staan, want zonder die draai begint hij rechts in plaats van bovenaan. Zet het getal als echte tekst in de SVG en geef de SVG een title, anders leest een schermlezer alleen een plaatje zonder waarde. Zonder JavaScript staan de eindwaarden al in de attributen, dus dan zie je meteen de goede ring en het goede getal.

  • Voorbeeld A: 80 procent. 80%

    Voorbeeld A

  • Voorbeeld B: 55 procent. 55%

    Voorbeeld B

  • Voorbeeld C: 30 procent. 30%

    Voorbeeld C

Voorbeeldwaarden, alleen om het effect te laten zien.

6 effecten

Overgangen en layout

Deze familie gaat over de weg tussen twee toestanden: hoe een lijst van weergave wisselt, hoe een raster zich opbouwt en hoe een kaart uitgroeit tot een paneel. Zet hem in waar de gebruiker anders zou moeten raden wat er zojuist veranderde, en laat hem weg waar een sprong sneller en duidelijker is.

43

Wisselen tussen raster en lijst

Met twee knoppen springt dezelfde reeks kaarten van een raster naar een lijst, waarbij elke kaart en elke foto naar zijn nieuwe plek schuift in plaats van te verspringen. Handig bij een overzicht waar mensen zelf mogen kiezen hoe compact ze het willen zien.

Kost: Geen extra bestanden en geen eigen rekenwerk: de browser maakt de tussenbeelden. Wel maakt hij daarvoor kort een schermafdruk van de hele pagina, dus tijdens die 340 ms staat al het andere op de pagina stil. Ongeveer 145 regels CSS, waarvan de helft de namen voor de overgang, en 60 regels JavaScript, commentaar meegerekend.
Let op: Kent de browser View Transitions niet, dan valt het terug op een korte fade over de lijst; de wissel werkt dan nog steeds, alleen zonder het schuiven. Twee elementen mogen nooit dezelfde view-transition-name hebben, anders breekt de hele overgang af en ziet de gebruiker een harde sprong. De knoppen staan achter html.js, want zonder scripting zouden het dode knoppen zijn.

Rasterweergave

  • Stapel yufka vellen

    Breed vel

    Voorbeeldkaart

  • Stapel yufka vellen van dichtbij

    Dun vel

    Voorbeeldkaart

  • Opgestapelde vellen yufka

    Rond vel

    Voorbeeldkaart

  • Stapel yufka vellen op een werkblad

    Klein vel

    Voorbeeldkaart

  • Bakker tilt een vel yufka op

    Vers gebakken

    Voorbeeldkaart

44

Volgorde wisselen met vloeiend schuiven

De lijst wordt op naam of omgekeerd gesorteerd en de regels glijden naar hun nieuwe plek, zodat u kunt volgen welk item waarheen ging. Bruikbaar bij sorteren en filteren, waar een instant herschikking altijd verwarrend blijft.

Kost: Twee metingen van alle regels per klik, plus een animatie per verplaatste regel. Bij enkele tientallen regels is dat niets; bij honderden merkt u de meting. Geen extra bestanden, ongeveer 75 regels CSS en 105 regels JavaScript, commentaar meegerekend.
Let op: Meet u terwijl een vorige animatie nog loopt, dan zit die verschuiving in de meting en schieten de regels langs hun doel; daarom worden lopende animaties eerst afgebroken. Het positienummer is voor schermlezers verborgen, want een nummer dat verspringt terwijl de naam gelijk blijft levert alleen ruis op. De nieuwe volgorde wordt in een verborgen meldingsregel aangekondigd.

Standaardvolgorde

  • Rond vel

    Voorbeeldkaart

  • Dun vel

    Voorbeeldkaart

  • Vierkant vel

    Voorbeeldkaart

  • Breed vel

    Voorbeeldkaart

45

Ongelijk raster dat zich opbouwt

Tegels van verschillende maten schuiven kort na elkaar omhoog in beeld zodra het raster in zicht komt, met een groot vlak, een paar kleine en twee tekstblokken. Geschikt als opening van een overzichtspagina waar drie gelijke kolommen te braaf zouden aanvoelen.

Kost: Alleen CSS-transities plus een IntersectionObserver die één keer per raster afgaat. De vertraging staat als variabele in de markup, dus er is geen script nodig dat per tegel een timer zet. Ongeveer 120 regels CSS en 45 regels JavaScript, commentaar meegerekend.
Let op: De valkuil is een raster dat leeg blijft als de observer nooit afgaat of het script niet laadt; daarom staat de beginstand achter html.js en wordt bij minder beweging of een ontbrekende observer alles meteen getoond. Meer dan ongeveer 75 ms per tegel gaat aanvoelen als traag laden in plaats van als opbouw. Op 360 px blijven het twee kolommen, anders wordt elke tegel een streepje.

  • Bakker tilt een vel yufka op

    Vers gebakken

  • Voorbeeld

    Elke tegel komt op zijn beurt binnen

  • Stapel yufka vellen

    Vel voor vel

  • Yufka vellen van dichtbij

    Stapel

  • Opgestapelde vellen yufka

    Gestapeld

  • Voorbeeld

    Klaar voor verzending

46

Zijnavigatie die meeloopt

Een lijstje met de blokken van de pagina blijft in beeld en markeert het blok waar u nu leest. Zinvol bij lange pagina’s met vier of meer blokken, zoals een dienstenpagina of een veelgestelde vragen.

Kost: Vooral hoogte: het effect is pas zichtbaar als er echt iets te scrollen valt, dus de pagina moet lang genoeg zijn. Verder één meting per frame tijdens het scrollen, gedeeld met de andere effecten. Ongeveer 145 regels CSS en 55 regels JavaScript, commentaar meegerekend.
Let op: Deze demo staat bewust niet in .doek: die staat op overflow:hidden en daarmee werkt position:sticky niet meer. Eén ouder met overflow hidden of auto in de keten en de kolom blijft gewoon staan zonder foutmelding, wat de lastigste bug van dit effect is. Op smalle schermen wordt het een balk die u opzij schuift binnen zijn eigen kader, zodat de pagina zelf nooit horizontaal gaat scrollen.

Voorbeeld

Vers gebakken

Dit is voorbeeldtekst voor een lange pagina. De navigatie blijft in beeld terwijl u leest en geeft aan waar u bent. Zodra de volgende kop de leeslijn passeert, verspringt de markering mee.

Op een breed scherm staat de navigatie links naast de tekst. Op een telefoon wordt het een balk boven de tekst die u opzij kunt schuiven.

Voorbeeld

Bestellen

Voorbeeldtekst voor een bestelblok. Deze navigatie is bedoeld voor pagina's met vier of meer blokken; bij twee korte blokken voegt hij niets toe en kost hij alleen ruimte.

Klikt u op een naam in de lijst, dan schuift de pagina naar dat blok en gaat de focus mee. Wie met het toetsenbord werkt staat daarna dus in de tekst, niet nog boven in de navigatie.

Voorbeeld

Afhalen

Voorbeeldtekst. De markering is niet alleen een kleurverschil: er staat ook een gouden streep naast en het lettergewicht is zwaarder. Zo blijft het zichtbaar voor wie kleuren anders ziet. De markering staat niet in de html, maar wordt bij het eerste frame gezet; zonder scripting zou hij anders altijd op het eerste blok blijven hangen.

Elke blokkop staat in de code als kop, niet als vetgedrukte regel. Daarmee kan een schermlezer de pagina in blokken doorlopen, ook zonder deze navigatie.

Voorbeeld

Vragen

Voorbeeldtekst als afsluiting. Het meelopen zelf komt van CSS, niet van JavaScript. Valt de scripting weg, dan blijft de navigatie staan en werken de links als gewone sprongen naar het juiste blok.

Terug naar het begin
47

Gordijn dat wegtrekt

Bij het openen schuiven twee helften uit elkaar en laten de inhoud eronder zien. Alleen inzetten op een openingsscherm waar de eerste indruk telt, en nooit dieper in een bestelroute.

Kost: Twee vlakken en twee keyframes, samen ongeveer 90 regels CSS en 75 regels JavaScript, commentaar meegerekend. Geen extra bestanden. De echte kost is de 380 ms die de bezoeker wacht voordat het beeld vrij is, en die tijd is er maar één keer.
Let op: Een gordijn dat blijft hangen kost bezoekers, dus er zitten drie grendels op: de laag heeft altijd pointer-events:none, een harde timer haalt hem na 420 ms weg wat de animatie ook doet, en de eerste klik of toetsaanslag ruimt hem meteen op. De inhoud eronder staat er vanaf het eerste frame en is nooit op opacity 0 gezet. Staat de voorkeur op minder beweging, dan verschijnt het gordijn helemaal niet en verdwijnt de herhaalknop. In deze proeftuin speelt hij af zodra het paneel in beeld komt; op een echte pagina is dat het moment van laden.

Bakker tilt een vel yufka op

Voorbeeld

Vers gebakken

Het gordijn ligt er alleen even overheen. De tekst en de foto staan er vanaf het eerste moment, en klikken kan tijdens de beweging gewoon door.

48

Kaart die uitgroeit tot paneel

Een kaart klapt open tot een groot paneel dat precies vanuit die kaart lijkt te groeien, met de foto en de tekst erin. Bruikbaar voor een dienst, een product of een teamlid, waar een aparte pagina te veel is en een tooltip te weinig.

Kost: Eén meting per opening en één animatie van clip-path. Het veld krijgt met JavaScript een vaste minimumhoogte omdat het paneel er absoluut overheen ligt. Ongeveer 185 regels CSS en 150 regels JavaScript, commentaar meegerekend.
Let op: Zonder JavaScript is de kaart een gewone link naar het paneel dat dan onder de kaarten staat, dus er raakt geen inhoud zoek. Escape sluit en de focus keert terug naar de kaart waar u vandaan kwam. Er zit bewust geen Tab-val op en geen aria-modal: het paneel ligt binnen een veld van hooguit 46vh en dekt de rest van de pagina niet af, dus muis, toetsenbord en schermlezer houden alle drie dezelfde pagina. Alleen het raster eronder gaat inert, want dat ligt letterlijk onder het paneel. De rol dialog wordt pas door JavaScript gezet, want zonder scripting is het geen dialoog maar gewoon een blok tekst. Kan de browser clip-path met afgeronde hoeken niet aan, dan vervaagt het paneel netjes in beeld in plaats van half te morphen.

Stapel yufka vellen

Voorbeeld

Breed vel

Het paneel groeit uit de kaart waar u op klikte en vult daarna het hele vlak. Sluiten kan met de knop of met Escape; de focus gaat dan terug naar precies die kaart.

Zolang het paneel open staat blijven de kaarten eronder buiten bereik van muis en toetsenbord.

Stapel yufka vellen van dichtbij

Voorbeeld

Dun vel

De uitsnede loopt van de rand van de kaart naar de rand van het paneel. Daardoor lijkt het één vlak dat opent, in plaats van een venster dat over de pagina valt.

Staat de voorkeur op minder beweging, dan opent het paneel direct zonder animatie.

Opgestapelde vellen yufka

Voorbeeld

Rond vel

Zonder JavaScript is de kaart een gewone link naar dit blok, dat dan onder de kaarten staat. Er gaat dus geen inhoud verloren als de scripting wegvalt.

Met Tab loopt u door het paneel en daarna verder de pagina op; Escape brengt u terug naar de kaart.

Hoe je hieruit kiest

Niet op wat het mooist beweegt, maar op wat de bezoeker helpt. Een effect verdient zijn plek als het iets duidelijk maakt: volgorde, voortgang, verband, of dat er iets gebeurd is. Alles daarbuiten kost laadtijd en aandacht zonder er iets voor terug te geven.

Zeg welke nummers je wilt en waarvoor, dan bouw ik ze in de echte site. Hoe een ontwerp verder tot stand komt staat op de aanpak-pagina.