Domyślnie elementy sterujące formularza, takie jak <input>, <textarea> i <select>, mają stałe wymiary. Ich rozmiary pozostają stałe, niezależnie od ilości treści wprowadzanych lub wybieranych przez użytkownika.
Aby umożliwić automatyczne zmniejszanie lub powiększanie tych elementów sterujących w celu dopasowania ich do zawartości (w tym do obiektów zastępczych), użyj właściwości CSS field-sizing: content.
Automatyczne zmienianie rozmiaru elementów sterujących formularza
Ustawienie field-sizing: content w polach wejściowych, polach wyboru lub obszarach tekstowych umożliwia dynamiczną zmianę ich rozmiaru, gdy użytkownik wpisuje tekst lub wybiera opcje. Aby zapewnić użytkownikom dobre wrażenia, musisz jednak uwzględnić odziedziczone style, domyślne układy i ograniczenia minimalne/maksymalne.
Aby uniknąć problemów z układem, zalecamy ustawienie zarówno min-inline-size (lub min-width), jak i max-inline-size (lub max-width) obok field-sizing: content w przypadku pól tekstowych. Minimalny rozmiar zapobiega zmniejszeniu szerokości pustego pola do zera (co uniemożliwia kliknięcie), a maksymalny rozmiar zapobiega nieograniczonemu rozszerzaniu się pola i zakłócaniu układu strony.
W przypadku pól tekstowych zezwolenie na automatyczne dopasowywanie rozmiaru w poziomie może powodować problemy z wygodą użytkowników (np. pole tekstowe z długim obiektem zastępczym gwałtownie zmniejszy się w poziomie, gdy użytkownik wpisze pojedynczy znak). Aby temu zapobiec, zastosuj do pola tekstowego konkretną szerokość (np. width: 100%). Dzięki temu pole tekstowe zachowuje stałą szerokość w poziomie, a jednocześnie automatycznie dostosowuje rozmiar w pionie, gdy tekst jest zawijany.
Zalecamy ustawienie max-inline-size (lub max-width) w elementach <select> za pomocą field-sizing: content, aby bardzo długie wybrane opcje nie psuły układu strony.
/* 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;
}
WAŻNE: jawne właściwości width i height zastępują field-sizing: content we wszystkich elementach sterujących formularza. Jeśli globalny arkusz CSS projektu ustawia pola wejściowe, pola wyboru lub pola tekstowe na width: 100%, musisz wyraźnie zresetować je do wartości width: auto (lub width: fit-content) w elementach za pomocą field-sizing: content, aby automatyczne dopasowywanie rozmiaru działało. Z drugiej strony, jeśli wcześniej ustawiono stałą wysokość globalnie, należy wyraźnie ustawić height: auto w polach tekstowych.
WAŻNE: układy Grid i Flexbox często domyślnie rozciągają elementy podrzędne, aby wypełnić dostępną przestrzeń. Jeśli którykolwiek element sterujący formularza korzystający z field-sizing: content nie chce się zmniejszyć, sprawdź właściwości wyrównania jego kontenera i zastosuj align-self: start lub justify-self: start do elementu sterującego formularza, aby zastąpić rozciąganie.
Strategie zastępcze
field-sizing należy traktować jako progresywne ulepszanie. W przeglądarkach, które nie obsługują tej właściwości, elementy sterujące formularza płynnie powracają do domyślnego, stałego rozmiaru. Użytkownicy będą po prostu korzystać ze standardowego przewijania w przypadku treści, które nie mieszczą się w polach tekstowych o stałym rozmiarze.
Jeśli dynamicznie powiększające się pola są absolutnie wymagane w starszych przeglądarkach, musisz użyć wykrywania funkcji i złożonego obejścia. Najbardziej niezawodna kreacja zastępcza dla pól tekstowych wykorzystuje sztuczkę z siatką CSS, w której ukryty pseudoelement odzwierciedla dane wejściowe użytkownika w czasie rzeczywistym, wymuszając rozszerzenie kontenera siatki (i pola tekstowego wewnątrz niego).
<!-- 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;
}
}
Ze względu na złożoność powielania stylów i synchronizowania stanu między węzłami DOM w przypadku każdego elementu sterującego formularza zalecanym podejściem w większości aplikacji jest poleganie na domyślnym zachowaniu zastępczym stałych danych wejściowych, chyba że dynamiczne określanie rozmiaru ma kluczowe znaczenie dla wygody użytkowników.