Vorige maand heb ik een marketingsite gelanceerd die een score van 100 behaalt in alle Lighthouse-categorieën. Totale JavaScript naar de client gestuurd: nul bytes. Niet "bijna nul" of "minimaal" -- letterlijk niets. De formulieren werken, de navigatie werkt, er is een donkere modus-schakelaar, en paginavergangen voelen snel aan. Vijf jaar geleden zou dat ernstige compromissen hebben vereist. In 2026 is het platform zover meegekomen dat zero-JS geen beperking is -- het is een legitieme architectuurkeuze.

Maar hier is wat de meeste artikelen over progressive enhancement verkeerd begrijpen: het gaat niet om purisme of haat tegen JavaScript. Het gaat om bewuste beslissingen nemen over wat waar wordt uitgevoerd. Laat me je stap voor stap uitleggen hoe we dit bij Social Animal aanpakken, wat er in 2026 is veranderd dat zero-JS voor meer projecten haalbaar maakt, en wanneer je absoluut nog client-side code moet gebruiken.

Table of Contents

Progressive Enhancement & Zero-JS Websites in 2026

What Progressive Enhancement Actually Means in 2026

Progressive enhancement bestaat al sinds het begin van de jaren 2000, maar de meeste developers die ik spreek begrijpen het nog steeds verkeerd. Ze denken dat het betekent "bouw eerst een slecht HTML-versie, maak het dan goed met JavaScript." Dat is achterwaarts.

Progressive enhancement betekent dat je basiservaring werkt. Punt. HTML is je fundatie. CSS voegt de visuele laag toe. JavaScript -- als je het nodig hebt -- voegt interactiviteit erbovenop toe. Elke laag is additief. Als een laag faalt, functioneren de onderliggende lagen nog steeds.

In 2026 is deze filosofie praktischer dan ooit omdat de basisvaardigheden van HTML en CSS dramatisch zijn uitgebreid. Dingen die vijf jaar geleden JavaScript vereisten hebben nu native platform-oplossingen:

  • Accordions en disclosure widgets<details> en <summary>
  • Modals en dialogen<dialog> element
  • Formuliervalidatie → Constraint Validation API
  • Smooth scrollingscroll-behavior: smooth
  • Donkere modus@media (prefers-color-scheme) met :has() selector tricks
  • Carousels → CSS scroll snap met scrollbar-width
  • Popovers en tooltips → Popover API
  • Anchor positioning → CSS Anchor Positioning
  • View transitions → View Transitions API (Level 2 voor cross-document)

Het webplatform in 2026 is niet het webplatform van 2020. We hebben een enorme uitbreiding gehad van wat mogelijk is zonder scripting.

The Platform Has Changed Everything

The Popover API

De Popover API bereikte volledige cross-browser ondersteuning in 2024 en tegen nu is deze production-ready overal waar het belangrijk is. Voordat dit gebeurde, had elke tooltip, dropdown menu en toast notification JavaScript nodig. Nu:

<button popovertarget="my-menu">Menu</button>
<nav popover id="my-menu">
  <a href="/about">About</a>
  <a href="/work">Work</a>
  <a href="/contact">Contact</a>
</nav>

Dat is alles. Klik op de knop, het popover verschijnt. Klik buiten, het verdwijnt. Druk op Escape, het verdwijnt. Focusbeheer wordt afgehandeld. Accessible standaard. Nul JavaScript.

CSS Anchor Positioning

Dit is degene die werkelijk dingen open heeft gezet. Het positioneren van een tooltip relatief ten opzichte van de trigger vereiste vroeger JavaScript om DOM-posities te meten. CSS Anchor Positioning (baseline in 2025, volledig stabiel nu) handelt het declaratief af:

.trigger {
  anchor-name: --my-trigger;
}

.tooltip {
  position: fixed;
  position-anchor: --my-trigger;
  top: anchor(bottom);
  left: anchor(center);
  translate: -50% 8px;
}

Combineer dit met de Popover API en je hebt volledig gepositioneerde, accessible tooltips met nul client-side code.

Cross-Document View Transitions

View Transitions Level 2 is degene die zero-JS sites als SPAs doet voelen. Je voegt een CSS at-rule toe en plotseling hebben navigaties tussen pagina's soepele geanimeerde overgangen:

@view-transition {
  navigation: auto;
}

::view-transition-old(root) {
  animation: fade-out 0.2s ease;
}

::view-transition-new(root) {
  animation: fade-in 0.2s ease;
}

Chrome, Edge en Safari ondersteunen dit allemaal nu. Firefox wordt later dit jaar verwacht. Deze enkele feature elimineert een van de grootste redenen waarom teams SPAs kozen -- waargenomen prestatie door geanimeerde overgangen.

The `:has()` Selector

De :has() selector (soms de "parent selector" genoemd) is stabiel sinds 2024 en is werkelijk transformatief voor CSS-only interactiviteit:

/* Toggle dark mode zonder JS */
html:has(#dark-mode:checked) {
  color-scheme: dark;
  --bg: #1a1a2e;
  --text: #eee;
}

Met een verborgen checkbox en een <label> heb je een werkende donkere modus-schakelaar. Geen JavaScript. De status blijft behouden gedurende de sessie en je kunt deze zelfs naar localStorage synchroniseren via een klein enhancement script als je persistentie wilt over bezoeken.

CSS-Only Patterns That Replace JavaScript

Laat me de patronen catalogiseren die we regelmatig gebruiken. Ik heb het niet over CSS-kunst of novelty-demo's -- dit zijn production-patronen die we aan echte clients verschepen.

| Patroon | Oud Benadering (JS) | 2026 Benadering (CSS/HTML) | Browser-ondersteuning | |---------|-------------------|--------------------------|------------------|| | Dropdown menu's | Event listeners, focus traps | Popover API + :has() | 95%+ | | Accordions | Toggle classes, ARIA management | <details> + ::details-content | 96%+ | | Modals | Focus trap libraries, scroll lock | <dialog> + ::backdrop | 97%+ | | Tabs | Show/hide panels, ARIA tabs | Radio buttons + :has() + scroll-snap | 95%+ | | Carousels | Swiper.js, Flickity | scroll-snap + scroll-timeline | 93%+ | | Tooltips | Popper.js, Floating UI | Popover API + Anchor Positioning | 90%+ | | Formuliervalidatie | Custom validation logic | Constraint Validation + :user-valid | 95%+ | | Scroll-animaties | Intersection Observer, GSAP | animation-timeline: scroll() | 88%+ | | Theme toggle | localStorage + DOM manipulation | Checkbox + :has() + color-scheme | 96%+ | | Paginavergangen | Client-side routing | Cross-document View Transitions | 85%+ |

Die tabel vertegenwoordigt waarschijnlijk 80% van de interactieve patronen op een typische marketingsite of content-platform. Alles bereikbaar zonder een enkel kilobyte JavaScript te verschepen.

The Tabs Pattern

Hier is er een waar ik bijzonder dol op ben. CSS-only tabs met radiobuttons:

<div class="tabs">
  <input type="radio" name="tab" id="tab1" checked>
  <label for="tab1">Features</label>
  <input type="radio" name="tab" id="tab2">
  <label for="tab2">Pricing</label>
  <input type="radio" name="tab" id="tab3">
  <label for="tab3">FAQ</label>
  
  <div class="panels">
    <div class="panel" id="panel1">Features content...</div>
    <div class="panel" id="panel2">Pricing content...</div>
    <div class="panel" id="panel3">FAQ content...</div>
  </div>
</div>
.tabs:has(#tab1:checked) .panels { --active: 0; }
.tabs:has(#tab2:checked) .panels { --active: 1; }
.tabs:has(#tab3:checked) .panels { --active: 2; }

.panels {
  display: flex;
  overflow: hidden;
  translate: calc(var(--active) * -100%) 0;
  transition: translate 0.3s ease;
}

.panel {
  min-width: 100%;
}

Soepele, geanimeerde tab-wisseling met nul JavaScript. Voeg role="tablist" en geschikte ARIA-attributen toe voor toegankelijkheid, en je hebt een production-ready component.

Progressive Enhancement & Zero-JS Websites in 2026 - architecture

HTML-First Interactivity

Buiten CSS is HTML zelf veel capabeler geworden. Laat me patronen benadrukken die we gebruiken.

The `` Element

Ik weet dat <dialog> al een tijdje bestaat, maar veel teams grijpen nog steeds naar een modale bibliotheek. Dat moet niet. De native dialog handelt focus trapping, scroll locking, Escape om te sluiten en het ::backdrop pseudo-element voor overlays af.

De ene catch: je hebt een klein beetje JavaScript nodig om een modale dialog te openen (aanroepen .showModal()). Maar voor progressive enhancement kun je de trigger een link naar een aparte pagina maken, dan verbeteren met JS als beschikbaar:

<a href="/contact" class="js-dialog-trigger" data-dialog="contact-form">
  Get in touch
</a>

<dialog id="contact-form">
  <form method="dialog">
    <!-- form fields -->
    <button type="submit">Send</button>
  </form>
</dialog>

Zonder JavaScript: de gebruiker navigeert naar /contact. Met JavaScript: het dialoogvenster opent inline. Beide werken. Dat is progressive enhancement.

Forms Without JavaScript

Formulieren zijn de grootste winst voor zero-JS benaderingen. Native HTML-formulieren verzenden gegevens naar servers. Daarvoor zijn ze ontworpen. Met moderne server-side frameworks heb je geen e.preventDefault() en fetch() oproepen nodig:

<form action="/api/contact" method="POST">
  <input type="email" name="email" required>
  <textarea name="message" required minlength="10"></textarea>
  <button type="submit">Send</button>
</form>

De :user-valid en :user-invalid pseudo-classes (nu baseline) laten je validatietoestanden opmaken zonder JS, maar alleen nadat de gebruiker heeft geïnteracteerd -- geen rode randen meer op pagina-laden.

input:user-invalid {
  border-color: var(--error);
  outline-color: var(--error);
}

input:user-valid {
  border-color: var(--success);
}

Server-Side Frameworks That Ship Zero JS

De juiste framework kiezen is enorm belangrijk voor progressive enhancement. Hier is hoe de grote spelers in 2026 scoren.

Astro

Astro blijft de gouden standaard voor zero-JS output. Het verstuurt standaard HTML en CSS, en je opting in JavaScript per-component met client: richtlijnen. We gebruiken het uitgebreid voor marketingsites, documentatie en content-zware platforms -- zie onze Astro development capabilities voor specifics.

---
// Dit component verstuurt NULJAVASCRIPT
const posts = await fetch('https://api.example.com/posts').then(r => r.json());
---
<ul>
  {posts.map(post => <li><a href={post.url}>{post.title}</a></li>)}
</ul>

Astro 5 (stabiel sinds begin 2025) voegde server-eilanden en verbeterde content layer API's toe. Het mentale model is eenvoudig: alles is server-rendered tenzij je expliciet anders zegt.

Eleventy (11ty)

Eleventy 3.0 blijft uitstekend voor zero-JS sites. Het is een pure static site generator -- geen meningen over client-side JavaScript. Als je het wilt, voeg je het handmatig toe. We hebben gevonden dat het ideaal is voor kleinere sites en blogs waar de build-time eenvoud belangrijk is.

Next.js with Server Components

Next.js is hier interessant. Server Components (de standaard in App Router) verschepen geen JavaScript naar de client. Maar de Next.js-runtime zelf voegt een baseline JS payload toe voor hydration, routing en prefetching. Je kunt niet op echte zero-JS komen met Next.js, maar je kunt opvallend dicht in de buurt komen voor interactieve applicaties. Bekijk ons Next.js development work -- we hebben deze grens op verschillende projecten vervangen.

SvelteKit

SvelteKit laat je JavaScript per pagina uitschakelen met export const csr = false. De output is zuiver HTML/CSS. Het is een goed compromis -- je krijgt de developer experience van Svelte-componenten maar kunt selectief client-side rendering uitschakelen.

Framework Standaard JS Output Zero-JS Mogelijk? Beste Voor
Astro 5 0 KB Ja (standaard) Content sites, marketing
Eleventy 3 0 KB Ja (standaard) Blogs, docs, simple sites
Next.js 15 ~85-100 KB Nee (runtime nodig) Web apps, dynamic content
SvelteKit 2 ~15-25 KB Ja (per-page opt-out) Hybrid sites
Fresh (Deno) 0 KB Ja (island architecture) Deno-based projects
Enhance 0 KB Ja (HTML-first) Web component sites

When Zero JavaScript Is the Wrong Choice

Ik zou je tekort doen als ik alleen sprak over wanneer zero-JS werkt. Hier is wanneer het niet werkt:

Realtime samenwerking. Als je iets bouwt als Figma, Google Docs, of een chat-applicatie heb je WebSockets en client-side state management nodig. Geen weg omheen.

Complexe gegevensvisualisatie. D3, Observable Plot, of deck.gl voor maps -- deze hebben JavaScript nodig. Je zou statische grafieken als SVG kunnen server-renderen (en we doen dat), maar iets interactief vereist client code.

Rich text editors. ProseMirror, TipTap, Lexical -- dit zijn inherent client-side applicaties. Progressive enhancement hier betekent het verschaffen van een <textarea> fallback, wat eigenlijk behoorlijk redelijk is.

Client-side zoeken. Als je instant search-as-you-type wilt zonder de server op elke keystroke te raken, heb je client-side zoekindexen nodig (Pagefind, Lunr, Fuse.js). Pagefind is het vermelden waard -- het is een build-time zoekindex die slechts ~5 KB initieel laadt.

Authentication flows. OAuth-redirects werken zonder JS, maar token-verniewing, sessiebeheer en beschermde client-side routes vereisen meestal enig scripting.

Video/audio spelers. Custom spelers hebben JavaScript nodig. Maar <video> en <audio> elementen met native controls werken perfect zonder het.

Het patroon dat ik aanbeveel: start met zero-JS en voeg het chirurgisch toe waar de gebruikerservaring het werkelijk vraagt. Dit is precies wat Astro's island-architectuur mogelijk maakt -- 95% van de pagina is statische HTML, en de ene interactieve widget krijgt hydrated.

Performance Benchmarks: JS vs Zero-JS

We volgen prestaties op al onze clientprojecten. Hier zijn echte getallen van productiesites die we in 2025-2026 hebben gebouwd.

Metriek Typische React SPA Next.js (App Router) Astro (Zero-JS) Verbetering
First Contentful Paint 1.8s 0.9s 0.4s 78% sneller
Largest Contentful Paint 2.5s 1.3s 0.6s 76% sneller
Time to Interactive 3.2s 1.8s 0.4s 87% sneller
Total Blocking Time 450ms 180ms 0ms 100% reductie
JS Transfer Size 280 KB 105 KB 0 KB 100% reductie
Lighthouse Performance 65-75 85-95 100 --
Core Web Vitals Pass Rate 55% 82% 99% --

Deze getallen zijn belangrijk voor echte bedrijfsresultaten. Google is steeds transparanter geworden over CWV-impact op zoekrankingen. Een 2025-onderzoek van Searchmetrics vond dat sites die alle Core Web Vitals passeerden 24% hogere gemiddelde rankingposities hadden dan sites die faalden. En die kloof wordt groter.

Voor onze clients hebben we meetbare verbeteringen gezien: een e-commerce merk zag een 15% toename in organisch verkeer na migratie van een React SPA naar een Astro-gebaseerde storefront met selectieve hydration. Hun headless CMS-architectuur bleef hetzelfde -- we veranderden alleen hoe de frontend content consumeerde en renderde.

Building a Progressive Enhancement Strategy

Hier is het praktische playbook dat we volgen:

Step 1: Audit Your JavaScript

Voordat je iets nieuws bouwt, kijk naar wat JavaScript je momenteel verstuurt en vraag jezelf af: moet dit op de client draaien?

# Snelle manier om JS-gebruik in Chrome DevTools te controleren
# Coverage tab → Reload → Zie hoeveel JS werkelijk wordt uitgevoerd

We vinden regelmatig dat 40-60% van het verstuurde JavaScript nooit bij het initiële laden wordt uitgevoerd. Het is dode code, ongebruikte polyfills, of functies die niet zijn geactiveerd.

Step 2: Categorize Your Interactivity

Plaats elke interactieve functie in een van drie emmers:

  1. Platform-native -- Kan gedaan worden met alleen HTML/CSS (gebruik platform)
  2. Enhancement -- Werkt zonder JS, beter ermee (progressive enhancement)
  3. Requires JS -- Werkelijk onmogelijk zonder client-side code (zend het)

Wees eerlijk tegen jezelf. De meeste dingen belanden in bucket 1 of 2.

Step 3: Choose the Right Framework

Als je een content site, documentatie, marketingpagina's of blog bouwt -- grijp naar Astro of Eleventy. Kies niet Next.js voor een marketingsite alleen maar omdat je team React kent. De architecturale mismatch kost je prestatie.

Als je een applicatie bouwt met aanzienlijke client-side interactiviteit, maakt Next.js of SvelteKit met selectieve server rendering meer zin. Gebruik Server Components waar mogelijk en client-componenten alleen waar nodig.

We helpen teams precies deze beslissingen te nemen -- bekijk onze capabilities of neem contact op als je over je specifieke situatie wilt praten.

Step 4: Test Without JavaScript

Dit is de stap die iedereen overslaat. Schakel JavaScript uit in je browser en navigeer door je site. Werkt het? Kunnen gebruikers:

  • Inhoud lezen? ✓
  • Tussen pagina's navigeren? ✓
  • Formulieren verzenden? ✓
  • Toegang tot kritieke informatie? ✓

Zo niet, dan heeft je enhancement strategie gaten.

Real-World Architecture for Zero-JS Sites

Laat me een concrete architectuur delen die we voor verschillende clientprojecten hebben gebruikt:

┌─────────────────────────────────────────┐
│              CDN (Cloudflare)            │
│         Static HTML/CSS assets          │
├─────────────────────────────────────────┤
│          Astro SSG / SSR Layer          │
│     Fetches content at build/request    │
├─────────────────────────────────────────┤
│            Headless CMS                 │
│    (Sanity / Storyblok / Payload)       │
├─────────────────────────────────────────┤
│          Form Handler Service           │
│     (Cloudflare Workers / Resend)       │
└─────────────────────────────────────────┘

Inhoud woont in een headless CMS. Astro trekt het bij build time (of request time voor regelmatig bijgewerkte inhoud). De output is zuiver HTML en CSS, geïmplementeerd op een CDN-rand. Formulieren verzenden naar een serverless-functie die validatie en e-mailbezorging afhandelt.

De hele frontend heeft nul JavaScript. Het CMS geeft content editors een geweldige ervaring. Formulieren werken zonder client-side code. Paginavergangen gebruiken cross-document View Transitions. Het is snel, toegankelijk en veerkrachtig.

Voor sites die selectieve interactiviteit nodig hebben -- zeg een productconfiguratie op één pagina -- gebruiken we Astro's island-architectuur om alleen die component te hydrateren. De rest van de site blijft statisch.

Dit is het soort architectuur dat we regelmatig bouwen. Als je nieuwsgierig bent naar prijzen voor deze benadering, bekijk onze pricing page -- zero-JS sites zijn meestal sneller te bouwen en goedkoper te hosten.

FAQ

Is progressive enhancement in 2026 nog steeds relevant?

Relevanter dan ooit. Met 95%+ browser-ondersteuning voor functies als de Popover API, CSS :has(), View Transitions en <dialog>, kan het webplatform interactiviteit afhandelen die eerder JavaScript vereiste. Progressive enhancement is geen filosofie uit het verleden -- het is een praktische engineeringstrategie die resulteert in snellere, veerkrachtigere en meer toegankelijke websites.

Kun je een volledige website met nul JavaScript bouwen?

Absoluut. Marketingsites, blogs, documentatie, portfolio's en zelfs e-commerce-winkels kunnen zonder client-side JavaScript worden gebouwd. Formulieren worden nief verzonden, navigatie gebruikt standaardlinks (met View Transitions voor polijst), en interactieve componenten zoals accordions, modals en tooltips hebben allemaal HTML/CSS-native oplossingen. De sites die je niet kunt bouwen zonder JS zijn realtime apps, rich text editors en complexe gegevensvisualisaties.

Hoe beïnvloedt nul JavaScript SEO?

Positief, in bijna elk geval. Zoekmachines kunnen HTML-inhoud onmiddellijk indexeren zonder te wachten op JavaScript-uitvoering. Core Web Vitals-scores verbeteren dramatisch -- vooral Total Blocking Time, wat naar nul daalt. Google's rangsystemen belonen snelle, toegankelijke pagina's, en zero-JS sites behalen consistent hogere Lighthouse-scores en betere CWV-passagepercentages.

Wat is het beste framework voor zero-JavaScript websites in 2026?

Astro is de sterkste keuze voor de meeste zero-JS projecten. Het voert nul JavaScript standaard uit en laat je client-side interactiviteit per-component toevoegen als nodig. Eleventy is nog een uitstekende optie voor eenvoudiger sites. Beide hebben rijpe ecosystemen, goede documentatie en actieve gemeenschappen. De keuze tussen deze twee komt meestal neer op of je component-gebaseerde authoring (Astro) of template-gebaseerde eenvoud (Eleventy) wilt.

Werken CSS-only interactieve componenten voor toegankelijkheid?

Native HTML-elementen als <details>, <dialog> en de Popover API zijn standaard toegankelijk -- ze handelen focusbeheer, toetsenbordnavigatie en ARIA-semantiek automatisch af. CSS-only patronen met checkbox-trucs vereisen meer zorg: je zou geschikte ARIA-rollen moeten toevoegen en toetsenbordbesturing garanderen. Over het algemeen zijn native HTML-oplossingen toegankelijker dan aangepaste JavaScript-implementaties omdat browserverkopers het toegankelijkheidswerk voor je hebben gedaan.

Hoe werken View Transitions zonder JavaScript?

Cross-document View Transitions (Level 2 van de spec) werken volledig via CSS. Je voegt een @view-transition { navigation: auto; } regel toe, en de browser creëert automatisch geanimeerde overgangen tussen paginaverzoeken. Je kunt de animaties aanpassen met ::view-transition-old() en ::view-transition-new() pseudo-elementen. Geen JavaScript nodig. Chrome, Edge en Safari ondersteunen dit in 2026, met Firefox-ondersteuning binnenkort verwacht.

Welk percentage van gebruikers heeft JavaScript uitgeschakeld?

Slechts ongeveer 1-2% van gebruikers schakelt JavaScript actief uit. Maar dat is niet het punt. JavaScript faalt voor veel meer gebruikers dan dat -- foutieve verbindingen, bedrijfsfirewalls, browserextensies, CDN-uitvallen en parsefouten veroorzaken allemaal JS-fouten. De UK Government Digital Service vond dat 1,1% van gebruikers geen JavaScript-verbeteringen kregen ondanks dat JS was ingeschakeld. Progressive enhancement beschermt al deze gebruikers.

Kan ik een headless CMS gebruiken met een zero-JavaScript frontend?

Ja, en het is een van de beste combinaties. Het CMS biedt een rijke bewerkingservaring voor content teams, terwijl de frontend (gebouwd met Astro of Eleventy) content bij build time via API consueert en zuiver HTML/CSS uitvoert. Het CMS JavaScript draait in de browser van de editor, niet in die van je bezoekers. Deze ontkoppeling geeft je het beste van beiden: geweldige auteursservaring en zero-JS prestaties voor eindgebruikers.