6 augustus 2026
Automatisch groeiende textarea

Twintig jaar lang moest je Javascript gebruiken om een textarea mee te laten groeien met de inhoud: je moest de inhoud meten, de hoogte opslaan en een event handler schrijven voor elk geval waarin dat misgaat/onvoldoende is. Maar het internet evolueert… en vandaag de dag is er slechts één CSS-eigenschap nodig.

Op deze pagina werken beide versies (JavaScript en CSS). Ga je gang en probeer ze uit.

De JavaScript-manier

<textarea id="message" oninput="grow(this)"></textarea>
<style>
textarea {
    min-height: 2lh; 
    max-height: 12lh;
    resize: vertical;
}
</style>
<script>
    var message = document.getElementById('message');

    function grow(el) {
        if (el.dataset.resized) return;
        var style = getComputedStyle(el);
        var extra = style.boxSizing === 'border-box'
            ? parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth)
            : -(parseFloat(style.paddingTop) + parseFloat(style.paddingBottom));
        el.style.height = 'auto';
        el.style.height = el.scrollHeight + extra + 'px';
        el.dataset.height = el.style.height;
    }

    new ResizeObserver(function () {
        if (message.style.height !== (message.dataset.height || '')) {
            message.dataset.resized = 'yes';
        }
    }).observe(message);

    addEventListener('pageshow', function () { grow(message); });
    addEventListener('resize', function () { grow(message); });
</script>

Dit is een goed stukje code. Geen afhankelijkheden, geen bouwstap, en het werkt in elke browser die sinds 2020 is uitgebracht. Een relatief moderne versie van de ouderwetse JavaScript-aanpak. Deze code is tot op de pixel nauwkeurig, omdat hij de echte border en padding afleest via de berekende stijl in plaats van een berekening via regelhoogte. Hij begint op de juiste maat, houdt rekening met het gebruik van de terugknop en blijft werken als je je telefoon draait.

Het geeft je ook de ruimte om de ‘resizing’ over te nemen. Door de rechteronderhoek te slepen wordt de nieuwe hoogte opgeslagen als een inline hoogte - precies de eigenschap waarnaar het script ook wegschrijft. Het script onthoudt dus elke hoogte in het attribuut, en de observer vergelijkt deze. Een hoogte die het script niet heeft weggeschreven, moet die van de bezoeker zijn. Zodra dit wordt gedetecteert stopt het meegroeien voorgoed. Zeer gebruiksvriendelijk.

Een goed stukje code, maar er is een betere oplossing.

De CSS-manier

textarea {
    field-sizing: content;
    min-height: 2lh;
    max-height: 12lh;
    resize: vertical;
}

Your browser supports 'field-sizing: content', so the box above grows.

Your browser does not support 'field-sizing: content' yet, so the box above stays a plain textarea with a scrollbar. That is the fallback, and nothing is broken.

Dit is de moderne manier, en het is beter. Niet alleen omdat het korter is.

De JavaScript-versie kan gemakkelijk kapot gaan. De reden kan een fout zijn die wordt gegenereerd door een niet-gerelateerd script op de pagina, een verzoek dat nooit aankomt, een Content Security Policy zonder ‘unsafe-inline’, een extensie, of gewoon een gebruiker die JavaScript heeft uitgeschakeld. Op die manier kan de CSS-versie niet falen: een eigenschap is van toepassing of niet, en als dat niet het geval is, blijft er nog steeds een werkende textarea over.

De JavaScript-versie kan ook lay-outverschuivingen veroorzaken. De CSS-versie wordt tijdens het opmaken door de browser op maat gemaakt, waardoor deze op elk moment al klopt: first paint, een waarde hersteld door de terugknop, een waarde ingesteld door je eigen code of door een wachtwoordbeheerder, een geroteerde telefoon, een gesleept venster en elke andere denkbare situatie. Als het script te laat actief wordt, kun je een vervelende lay-outverschuiving of een verandering in de lay-out krijgen, zelfs terwijl je al in het tekstgebied aan het typen bent. Een zeer onprettige ervaring. Misshchien zie JIJ de vertraging niet in de JavaScript-versie, maar dat betekent niet dat deze er niet is bij een trage verbinding of een druk apparaat of een apparaat met te weinig vermogen.

Enkele opmerkingen:

  1. Een textarea met ‘field-sizing: content’ breidt zich horizontaal uit totdat het een breedtebeperking bereikt, en begint dan pas met het toevoegen van rijen. In een gewone vorm biedt de container deze beperking al, maar als de jouwe dat niet doet, stel dan ‘width: 100%’ in - anders kan een leeg veld onzichtbaar worden.
  2. De ondersteuning is goed, maar niet uitstekend. Chrome en Edge ondersteunen dit sinds maart 2024, Safari sinds 26.2 in december 2025 en Firefox sinds 152 in juni 2026 – de release waardoor het Baseline Newly Available is. “Newly Available” betekent dat sommige bezoekers nog steeds oudere browsers gebruiken en dat voor hen de textarea niet meegroeit. In plaats daarvan wordt een schuifbalk weergegeven, precies zoals textareas sinds 1995 werken - en omdat ‘resize: vertical’ nog steeds is ingeschakeld, kunnen bezoekers het vak zelf groter maken.
  3. Merk op dat ‘rows’ en ‘cols’ niet meer werken. Zodra ‘field-sizing: content’ is ingesteld, hebben deze attributen helemaal geen effect meer. Gebruik ‘min-height’ in plaats van ‘rows’.
  4. De compatibiliteit valt gunstig uit voor de CSS-aanpak. In een oude browser groeit de CSS-versie simpelweg niet mee: een kleine teleurstelling. De JavaScript-versie kan helemaal kapot gaan. En zelfs als dat niet het geval is, kan een langzaam apparaat of een trage verbinding ervoor zorgen dat de lay-out verandert terwijl iemand al aan het typen is… in de nieuwste browser. De ‘graceful degredation’ die CSS biedt is duidelijk superieur.

Conclusie

De JavaScript-oplossing is een mooi stukje techniek. Het heeft twintig jaar lang zijn werk gedaan, in veel verschillende versies en vormen, maar er is geen reden meer om het te gebruiken. Vervang het door de (veel eenvoudigere) CSS-oplossing.

Happy coding!

()  Joost van der Schee