Par défaut, les commandes de formulaire telles que <input>, <textarea> et <select> ont des dimensions fixes. Leur taille reste constante, quelle que soit la quantité de contenu saisie ou sélectionnée par l'utilisateur.
Pour permettre à ces commandes de se réduire ou de s'agrandir automatiquement en fonction de leur contenu (y compris les espaces réservés), utilisez la propriété CSS field-sizing: content.
Commandes de formulaire à dimensionnement automatique
La définition de field-sizing: content sur les entrées, les sélections ou les zones de texte permet de les redimensionner de manière dynamique lorsque l'utilisateur saisit ou sélectionne des options. Toutefois, vous devez tenir compte du style hérité, des valeurs par défaut de la mise en page et des contraintes minimales/maximales pour garantir une expérience utilisateur robuste.
Pour éviter les problèmes de mise en page, nous vous recommandons de définir à la fois min-inline-size (ou min-width) et max-inline-size (ou max-width) avec field-sizing: content sur les entrées de texte. Une taille minimale empêche le champ de saisie de se réduire à une largeur nulle lorsqu'il est vide (ce qui le rendrait incliquable), et une taille maximale garantit qu'il ne s'agrandit pas indéfiniment et ne perturbe pas la mise en page.
Pour les zones de texte, autoriser le redimensionnement automatique horizontal peut entraîner une expérience utilisateur déroutante (par exemple, une zone de texte avec un long espace réservé se rétrécit brusquement horizontalement lorsque l'utilisateur saisit un seul caractère). Pour éviter cela, appliquez une largeur explicite (comme width: 100%) à la zone de texte. Cela force la zone de texte à conserver une largeur horizontale stable tout en s'ajustant automatiquement à la verticale à mesure que le contenu s'enroule.
Il est recommandé de définir un max-inline-size (ou max-width) sur les éléments <select> à l'aide de field-sizing: content pour s'assurer que les options sélectionnées extrêmement longues ne perturbent pas la mise en page.
/* Applies horizontal auto-sizing to inputs */
input {
/* Instructs the element to size itself to fit its content */
field-sizing: content;
/* Reset explicit width if inherited from global styles */
width: auto;
/* Prevents the input from collapsing and disappearing when empty */
min-inline-size: 15ch;
/* Prevents infinite horizontal growth */
max-inline-size: 50ch;
}
textarea {
/* Instructs the element to size itself to fit its content */
field-sizing: content;
/* Reset explicit height if inherited from global styles */
height: auto;
/* Use a fixed width to prevent jarring horizontal shifts when replacing a long placeholder */
width: 50ch; /* or 100% depending on your layout */
/* Sets a reasonable minimum height (e.g., 3 lines) for empty textareas */
min-block-size: 3lh;
/* Prevents infinite vertical growth. Once a textarea hits this */
/* height, it will stop growing and show a vertical scrollbar. */
max-block-size: 10lh;
}
select {
/* Sizes the select element to fit the active option only */
field-sizing: content;
/* Prevents the dropdown from expanding infinitely and breaking the layout */
max-inline-size: 50ch;
}
IMPORTANT : Les propriétés explicites width et height remplacent field-sizing: content sur toutes les commandes de formulaire. Si le CSS global de votre projet définit les entrées, les sélections ou les zones de texte sur width: 100%, vous devez explicitement les réinitialiser sur width: auto (ou width: fit-content) sur les éléments utilisant field-sizing: content pour que le redimensionnement automatique fonctionne. À l'inverse, vous devez définir explicitement height: auto sur les zones de texte si une hauteur fixe a déjà été définie de manière globale.
IMPORTANT : Les mises en page Grid et Flexbox étirent souvent implicitement leurs enfants pour remplir l'espace disponible. Si un contrôle de formulaire utilisant field-sizing: content refuse de se réduire, vérifiez les propriétés d'alignement de son conteneur et appliquez align-self: start ou justify-self: start au contrôle de formulaire pour remplacer l'étirement.
Stratégies de remplacement
field-sizing doit être traité comme une amélioration progressive. Dans les navigateurs qui ne sont pas compatibles avec la propriété, les commandes de formulaire reviennent progressivement à leur comportement de dimensionnement fixe par défaut. Les utilisateurs bénéficieront simplement d'un défilement standard pour le contenu qui dépasse dans les entrées et les zones de texte de taille fixe.
Si les champs à croissance dynamique sont absolument nécessaires pour les anciens navigateurs, vous devez utiliser la détection de fonctionnalités et une solution de contournement complexe. La solution de remplacement la plus robuste pour les zones de texte utilise une astuce de grille CSS, où un pseudo-élément masqué reflète l'entrée de l'utilisateur en temps réel, forçant le conteneur de grille (et la zone de texte qu'il contient) à s'agrandir.
<!-- The textarea is wrapped in a container that will mirror its value -->
<div class="growable-textarea" data-replicated-value="">
<textarea></textarea>
</div>
// Only attach the fallback event listeners if field-sizing is unsupported
if (!CSS.supports('field-sizing', 'content')) {
document.querySelectorAll('.growable-textarea > textarea').forEach(textarea => {
textarea.addEventListener('input', () => {
textarea.parentNode.dataset.replicatedValue = textarea.value;
});
});
}
/* Only apply the fallback if field-sizing is NOT supported */
@supports not (field-sizing: content) {
.growable-textarea {
display: grid;
}
/* The pseudo-element and textarea must share the exact same cell, font, and padding */
.growable-textarea::after,
.growable-textarea > textarea {
grid-area: 1 / 1 / 2 / 2;
font: inherit;
padding: 0.5rem;
border: 1px solid #999;
}
/* The pseudo-element renders the copied text invisibly to stretch the grid */
.growable-textarea::after {
/* The space is necessary for trailing empty lines to be rendered */
content: attr(data-replicated-value) " ";
white-space: pre-wrap;
visibility: hidden;
}
.growable-textarea > textarea {
resize: none;
overflow: hidden;
}
}
Étant donné la complexité de la duplication des styles et de la synchronisation de l'état entre les nœuds DOM pour chaque commande de formulaire, il est recommandé d'utiliser le comportement de remplacement par défaut des entrées fixes pour la plupart des applications, sauf si le dimensionnement dynamique est essentiel pour l'expérience utilisateur.