По умолчанию элементы управления формой, такие как <input>, <textarea> и <select>, имеют фиксированные размеры. Их размеры остаются постоянными, независимо от объема контента, который пользователь вводит или выбирает.
Чтобы эти элементы управления автоматически уменьшались или увеличивались в соответствии с их содержимым (включая плейсхолдеры), используйте свойство CSS field-sizing: content.
Автоматическое изменение размера элементов управления формой
Если задать для полей ввода, меню выбора или текстовых областей значение field-sizing: content, их размер будет динамически меняться, когда пользователь вводит текст или выбирает варианты. Однако, чтобы обеспечить удобство для пользователей, необходимо учитывать унаследованные стили, макеты по умолчанию и минимальные/максимальные ограничения.
Чтобы избежать проблем с макетом, рекомендуется задать min-inline-size (или min-width) и max-inline-size (или max-width) вместе с field-sizing: content для текстовых полей. Минимальный размер не позволяет полю ввода уменьшиться до нулевой ширины, когда оно пустое (что делает его некликабельным), а максимальный размер гарантирует, что оно не будет расширяться до бесконечности и нарушать макет страницы.
Для текстовых областей автоматическое изменение размера по горизонтали может привести к ухудшению UX (например, текстовая область с длинным плейсхолдером резко уменьшится по горизонтали, когда пользователь введет один символ). Чтобы этого не происходило, задайте для текстовой области явную ширину (например, width: 100%). Это заставляет текстовую область сохранять стабильную горизонтальную ширину, в то же время автоматически изменяя размер по вертикали по мере переноса содержимого.
Рекомендуется задать max-inline-size (или max-width) для элементов <select> с помощью field-sizing: content, чтобы слишком длинные выбранные варианты не нарушали макет страницы.
/* 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;
}
ВАЖНО! Явные свойства width и height переопределяют field-sizing: content для всех элементов управления формой. Если в глобальном CSS-коде вашего проекта для полей ввода, выбора или текстовых областей задано значение width: 100%, вам нужно явно сбросить его до width: auto (или width: fit-content) для элементов, использующих field-sizing: content, чтобы автоматическое изменение размера работало. И наоборот, если фиксированная высота ранее была задана глобально, вы должны явно задать height: auto для текстовых областей.
ВАЖНО! Макеты Grid и Flexbox часто неявно растягивают дочерние элементы, чтобы заполнить доступное пространство. Если какой-либо элемент управления формы, использующий field-sizing: content, не уменьшается, проверьте свойства выравнивания его контейнера и примените align-self: start или justify-self: start к элементу управления формы, чтобы переопределить растяжение.
Резервные стратегии
field-sizing следует рассматривать как прогрессивное улучшение. В браузерах, которые не поддерживают это свойство, элементы управления формами постепенно возвращаются к своему стандартному фиксированному размеру. Пользователи смогут прокручивать контент, который не помещается в полях ввода и текстовых областях фиксированного размера.
Если динамически расширяющиеся поля абсолютно необходимы для старых браузеров, вам нужно использовать обнаружение функций и сложный обходной путь. Самый надежный резервный вариант для текстовых областей использует трюк с сеткой CSS, когда скрытый псевдоэлемент отражает вводимые пользователем данные в реальном времени, заставляя контейнер сетки (и текстовую область внутри него) расширяться.
<!-- 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;
}
}
Учитывая сложность дублирования стилей и синхронизации состояния между узлами DOM для каждого элемента управления формой, для большинства приложений рекомендуется использовать резервное поведение по умолчанию для фиксированных входных данных, за исключением случаев, когда динамический размер имеет решающее значение для удобства пользователей.