Textarea Auto-grow
La zone de texte s'allonge ligne après ligne jusqu'à 200 px puis défile ; un compteur « n / 200 » passe à l'ambre à 150 et au rouge à la limite.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Formulaires comprend 20 effets, dont 2 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
À chaque événement input, le script remet la hauteur à auto, lit scrollHeight, y ajoute l'épaisseur des bordures et applique le résultat, plafonné par le max-height calculé du champ (200 px par défaut). Tant que le texte tient, aucune barre de défilement ; au-delà du plafond, overflow-y passe à auto et la zone défile. Un ResizeObserver refait le calcul quand la largeur change (rotation d'un téléphone, colonne qui se resserre).
Le compteur affiche la longueur de la valeur sur le maximum lu dans l'attribut maxlength (200 livré) ; le chiffre après la barre oblique est réécrit par le script, il suit donc votre attribut. À 75 % (150 sur 200) il prend la classe is-warning, ambre ; à la limite, is-limit, rouge.
La balise <textarea> est vide dans le HTML livré : le placeholder s'affiche et le compteur part de 0. Le script est enfermé dans une fonction : collé deux fois ou à côté d'une variable textarea existante, il ne provoque pas d'erreur, et une racine déjà prête (data-agrw-ready) n'est pas rebranchée.
Accessibilité
- Étiquette : « Message » dans un
<label>masqué visuellement ; renommez-le selon votre formulaire (« Votre réponse », « Description »). - Compteur relié : la zone pointe vers le compteur par
aria-describedby, lu quand on y entre au clavier. - Seuils annoncés, pas chaque touche : une zone
aria-live="polite"dit « Plus que 50 caractères » en entrant dans l'ambre, puis « Limite de 200 caractères atteinte » ; rien n'est lu entre deux seuils. - Mouvement : la hauteur change sans animation, rien à couper sous
prefers-reduced-motion. - Limite : au-delà de 200 px la zone défile ; pour un très long texte, une hauteur fixe annoncée dès le départ reste plus confortable.
Compatibilité navigateur
2,7 Ko de JavaScript, CSS à variables. Mesuré le 08/11/2026 dans Chromium, Firefox et WebKit (Playwright) : valeur initiale vide, placeholder visible, « 1 / 200 » après une touche, hauteur qui suit les lignes puis s'arrête à 200 px avec défilement, collage tronqué à 200, deux copies indépendantes, reset du formulaire, aucune erreur. ResizeObserver est la fonction la plus récente (Chrome 64, Firefox 69, Safari 13.1, d'après @mdn/browser-compat-data).
Sans ResizeObserver (Chrome 51-63, Safari 10-13), la zone grandit à la frappe mais ne se recalcule pas quand seule sa largeur change. Sans JavaScript : zone de 2 lignes à hauteur fixe, compteur figé à 0, maxlength toujours appliqué par le navigateur.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0289-root">
<div class="agrw-group">
<label class="agrw-field">
<span class="agrw-sr">Message</span>
<textarea class="agrw-input" name="message" placeholder="Tapez votre message..." maxlength="200"></textarea>
</label>
<div class="agrw-count"><span class="agrw-current">0</span> / <span class="agrw-max">200</span></div>
<span class="agrw-sr agrw-status" aria-live="polite"></span>
<span class="agrw-words" hidden>
<span data-msg="warning">Plus que {n} caractères</span>
<span data-msg="limit">Limite de {max} caractères atteinte</span>
</span>
</div>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Limite de caractères (HTML — maxlength sur la zone) |
200 | Le compteur et ses seuils suivent : avec 500, l'ambre arrive à 375. Le chiffre affiché après la barre est réécrit par le script. |
Hauteurs (CSS — --agrw-min-height, --agrw-max-height sur .fx-0289-root) |
60px · 200px | Hauteur de départ et plafond avant défilement. Le script lit le plafond calculé, rien à changer dans le JS. |
Seuil d'alerte (JS — Math.ceil(max * 0.75)) |
75 % du maximum | Passez à 0.9 pour ne prévenir qu'à l'approche de la limite. |
Couleurs du compteur (CSS — --agrw-muted, --agrw-warning, --agrw-limit) |
#8b8b93 · #f59e0b · #ef4444 | Sur fond clair, préférez #c2410c et #dc2626 pour un contraste suffisant. |
Champ (CSS — --agrw-field, --agrw-border, --agrw-focus, --agrw-focus-field, --agrw-text) |
blanc à 5 % · blanc à 10 % · #6366f1 · indigo à 5 % · #fff | Fond, bordure, couleur et fond au focus, texte saisi. |
Largeur et cadre (CSS — --agrw-width, --agrw-bg, --agrw-root-min-height) |
280px · #0a0a0f · 300px | Dans une vraie page : --agrw-width:100%; --agrw-bg:transparent; --agrw-root-min-height:0. |
Messages annoncés (HTML — .agrw-words) |
« Plus que {n} caractères » · « Limite de {max} caractères atteinte » | {n} devient le nombre restant, {max} la limite. Traduisez-les ici. |
FAQ
reset du formulaire. Si vous changez la valeur par script, déclenchez ensuite textarea.dispatchEvent(new Event('input', {bubbles: true})).<textarea> et </textarea> (retour à la ligne, espaces) : il devient la valeur de départ, cache le placeholder et compte dans la limite. Gardez les deux balises collées quand vous retouchez le HTML..agrw-count du HTML empêche le script de s'initialiser, car il en a besoin. Pour ne garder que l'agrandissement, laissez l'élément et masquez-le en CSS (.fx-0289-root .agrw-count{display:none}) : le champ y renvoie toujours par aria-describedby, les lecteurs d'écran continuent d'entendre le nombre de caractères, ce qui reste utile.