Er is een reden waarom JavaScript-parallax er altijd lichtjes verkeerd uitziet — een beetje losstaand, alsof de lagen een halve frame achter de pagina zwemmen. Het is geen slordig code. Het is dat scroll-evenementen uw JavaScript bereiken nadat de browser het scrollen al heeft getekend. De browser heeft dit al eens opgelost, toen hij plakkerige headers in position: sticky omzette. Scroll-driven animations zijn dezelfde stap, tegelijk toegepast op alle scroll-gebonden effecten.
Tien jaar lang betekende het animeren van een miniatuur naar een hero-afbeelding één techniek: het element voor meten, erna meten, het verschil met een transform simuleren en afspelen. FLIP. Elke animatiebibliotheek doet het zo, en elke betaalt ervoor met JavaScript op de hoofdthread op het slechtst mogelijke moment. De View Transitions API verplaatst die hele truc naar de browser — en sinds React 19.2 en Next.js 16 bestaat het hele contract uit één prop genaamd name.
Een lijst van duizend reacties rendert traag, dus grijp je naar react-window – en in ruil voor soepel scrollen verlies je Ctrl+F, het afdrukken van de pagina en gedeeltelijk de navigatie van schermlezers, omdat elementen buiten het venster fysiek ophouden te bestaan in de DOM. content-visibility lost hetzelfde probleem anders op: de elementen blijven in de DOM, de browser slaat alleen het kostbare layout- en paintwerk ervoor over totdat ze dicht bij het zichtbare gebied komen – en, verrassend genoeg, kan ze tijdelijk weer tonen zodra je er tekst in zoekt.
In het artikel over toegankelijkheid was een modal met display:none, die nog steeds in de accessibility-boom stond, een voorbeeld van een fout die ontstaat door een modal van nul op te bouwen met divs. De echte vraag is: waarom moest hij überhaupt van nul worden opgebouwd? Ik zoek uit wat de native <dialog> en het popover-attribuut gratis bieden – top layer, focus trap, light dismiss – en waar deze twee mechanismen zo sterk verschillen dat ze door elkaar halen zo naar een ontoegankelijke interface leidt.
De utility-klasse .mt-4 verliest het van de regel .card .card__header .card__title, ondanks dat ze logisch zou moeten winnen omdat ze later is toegevoegd. Dat is geen toeval – dat is specificiteit die precies doet waarvoor ze is ontworpen. @layer introduceert een compleet nieuwe as voor het oplossen van conflicten, die vóór specificiteit werkt, niet ernaast – met één valkuil zo contra-intuïtief dat zelfs een deel van de documentatie op het web hem verkeerd beschrijft.
Een formulierveld moet rood oplichten zodra de input erbinnen ongeldig is. Simpel genoeg – behalve dat CSS 25 jaar lang niet in staat was om een element te vragen wat er in zijn binnenste gebeurt, alleen andersom. Ik zoek uit hoe :has() die richting omdraait, hoe het verschilt van gewone combinators, en waar deze nieuwe kracht echt performance kost.