Per impostazione predefinita, i controlli dei moduli come <input>, <textarea> e <select> hanno dimensioni fisse. Le loro dimensioni rimangono costanti, indipendentemente dalla quantità di contenuti inseriti o selezionati dall'utente.
Per consentire a questi controlli di ridursi o espandersi automaticamente in base ai contenuti (inclusi i segnaposto), utilizza la proprietà CSS field-sizing: content.
Controlli dei moduli con ridimensionamento automatico
L'impostazione di field-sizing: content su input, selezioni o aree di testo consente di ridimensionarli in modo dinamico man mano che l'utente digita o seleziona le opzioni. Tuttavia, per garantire un'esperienza utente efficace, devi tenere conto dello stile ereditato, dei valori predefiniti del layout e dei vincoli minimi/massimi.
Per evitare problemi di layout, ti consigliamo di impostare sia min-inline-size (o min-width) sia max-inline-size (o max-width) insieme a field-sizing: content sugli input di testo. Una dimensione minima impedisce che l'input si riduca a una larghezza pari a zero quando è vuoto (rendendolo non selezionabile), mentre una dimensione massima garantisce che non si espanda indefinitamente e non alteri il layout della pagina.
Per le aree di testo, consentire il ridimensionamento automatico orizzontale può causare un'esperienza utente sgradevole (ad esempio, un'area di testo con un segnaposto lungo si ridurrà bruscamente in orizzontale quando l'utente digita un singolo carattere). Per evitare questo problema, applica una larghezza esplicita (ad esempio width: 100%) all'area di testo. In questo modo, l'area di testo mantiene una larghezza orizzontale stabile, mentre il ridimensionamento verticale avviene automaticamente quando il contenuto va a capo.
Ti consigliamo di impostare un max-inline-size (o max-width) sugli elementi <select> utilizzando field-sizing: content per assicurarti che le opzioni selezionate estremamente lunghe non interrompano il layout della pagina.
/* 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;
}
IMPORTANTE: le proprietà esplicite width e height sostituiscono field-sizing: content su tutti i controlli dei moduli. Se il CSS globale del tuo progetto imposta input, selezioni o aree di testo su width: 100%, devi reimpostarli esplicitamente su width: auto (o width: fit-content) sugli elementi utilizzando field-sizing: content per il funzionamento del ridimensionamento automatico. Al contrario, devi impostare esplicitamente height: auto sulle textarea se in precedenza è stata impostata un'altezza fissa a livello globale.
IMPORTANTE: i layout Grid e Flexbox spesso estendono implicitamente i relativi elementi secondari per riempire lo spazio disponibile. Se un controllo del modulo che utilizza field-sizing: content non si riduce, controlla le proprietà di allineamento del relativo container e applica align-self: start o justify-self: start al controllo del modulo per eseguire l'override dell'allungamento.
Strategie di riserva
field-sizing deve essere considerato un potenziamento progressivo. Nei browser che non supportano la proprietà, i controlli dei moduli tornano al comportamento di ridimensionamento fisso predefinito. Gli utenti sperimenteranno semplicemente lo scorrimento standard per i contenuti in overflow all'interno di input e aree di testo di dimensioni fisse.
Se i campi a crescita dinamica sono assolutamente necessari per i browser meno recenti, devi utilizzare il rilevamento delle funzionalità e una soluzione alternativa complessa. Il fallback più efficace per le aree di testo utilizza un trucco di CSS Grid in cui uno pseudo-elemento nascosto rispecchia l'input dell'utente in tempo reale, forzando l'espansione del container della griglia (e dell'area di testo al suo interno).
<!-- 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;
}
}
Data la complessità della duplicazione degli stili e della sincronizzazione dello stato tra i nodi DOM per ogni controllo del modulo, l'approccio consigliato per la maggior parte delle applicazioni è affidarsi al comportamento di riserva predefinito degli input fissi, a meno che il dimensionamento dinamico non sia fondamentale per l'esperienza utente.