Авторазмер textarea по содержимому с помощью CSS
Быстрый ответ
Настройка автоматического изменения размеров элемента <textarea>
в соответствии с его содержимым, используя только CSS, невыполнима. Но вместо этого, применение простого JavaScript-скрипта в связке с приёмом использования вспомогательного скрытого <div>
можно считать изящным и ненавязчивым решением данной задачи.
<div style="position:relative;">
<textarea class="auto-expand" style="min-height:40px; height:auto; overflow:hidden; resize:none;"></textarea>
<!-- Невидимый помощник зеркальный div всегда с вами -->
<div class="mirror-text" style="white-space:pre-wrap; visibility:hidden; position:absolute; z-index:-1;"></div>
</div>
// Зеркальный div функционирует как отражение для мяча — всегда готов поддержать
document.querySelector('.auto-expand').addEventListener('input', function() {
document.querySelector('.mirror-text').textContent = this.value;
this.style.height = 'auto';
this.style.height = this.scrollHeight + 'px';
});
<div class="mirror-text">
незримо повторяет поведение textarea
и точно копирует его размеры.
Почему только на CSS не получится
Реализация динамического изменения размеров textarea
только при помощи CSS невозможна, так как, в отличие от JavaScript, CSS не предусматривает функционал для адаптации под содержимое блока. Известные обходные пути, например, overflow:auto
или resize:vertical
, не решают проблему, ибо или требуют активности со стороны пользователя, или остаются статичными.
Атрибут 'contenteditable' — наше туз в рукаве
Если использование JavaScript не вызывает отторжения, атрибут contenteditable
может с успехом заменить <textarea>
. Он позволяет делать любой элемент редактируемым и автоматически подгонять его размеры под содержимое. Однако, помните об обязательности очистки введённых данных для предотвращения HTML-инъекций.
<div contenteditable="true" style="min-height:40px; max-height:200px; overflow:auto;">
Разместите редактируемый текст здесь
</div>
Такой блок будет расширяться пропорционально его содержимому, однако для получения данных из div при отправке формы не обойтись без JavaScript.
Повышаем удобство использования
Несмотря на присущие чистому CSS ограничения, настройка размеров textarea
при помощи атрибута resize:vertical
делает этот элемент более удобным в использовании.
.auto-expand {
min-height: 40px;
max-height: 200px;
resize: vertical;
/* Знакомы ли вы с регулируемыми по высоте сидениями в машине? Удобно, не так ли? */
}
Атрибут rows
определяет минимальную высоту поля ввода:
<textarea rows="3"></textarea>
Атрибут maxLength
, хотя и не влияет напрямую на размеры, ограничивает количество текста и способствует его оптимальному размещению.
Визуализация
Воспринимайте ваш textarea как контейнер, который гибко подстраивается под свое содержимое:
До: После:
+---------+ +-----------------+
| Текст | | Текст точно |
| здесь | | укладывается, |
+---------+ | лишнего нет. |
+-----------------+
Будь то текст или абзац, содержимое эффективно заполняет контейнер.
📦 <-(Текст) | 📦<----(Больше текста)-----> | 📦<---------(Ещё больше текста)--------->
Маленький объём Средний объём – как раз то, что нужно! Большой объём, вмещающий всё необходимое
Идеальная подгонка означает, что textarea своим размером идеально соответствует объёму содержимого, устраняя нежелательное пустое пространство.
На практике: Применение в реальных условиях
Решение для динамического изменения размеров textarea
на основе исключительно CSS остается недостижимой целью, тем не менее минимальный объём JavaScript, необходимый для этой задачи, представляет собой допустимый и разумный компромисс.
Эффективный JavaScript
Здесь используемый JavaScript выступает в роли однократно установленного прослушивателя событий, который обеспечивает изменение размеров textarea
по мере того, как пользователь вводит текст.
Обработка отправления форм
При использовании атрибута contenteditable
следует помнить, что для сохранения данных на сервере потребуется создать скрытый элемент <input>
:
<form>
<div contenteditable="true" id="editable"></div>
<input type="hidden" name="textareaContent" id="hiddenInput">
</form>
Затем потребуется применить JavaScript для синхронизации содержимого редактируемого блока с значением скрытого поля ввода в момент отправки формы.
Стилизация с помощью CSS
При помощи CSS-переменных упрощается и становится более управляемым процесс стилизации textarea
и вспомогательного div
:
:root {
--textarea-font-size: 16px;
--textarea-line-height: 1.5;
--textarea-padding: 10px;
}
.auto-expand,
.mirror-text {
font-size: var(--textarea-font-size);
line-height: var(--textarea-line-height);
padding: var(--textarea-padding);
/* В стиле "Copy-paste"? CSS-переменные говорят "нет". */
}
Полезные материалы
- Полное руководство по Flexbox | CSS-Tricks — Всё, что нужно знать для изучения flexbox.
- resize | CSS-Tricks — Подробное описание свойства
resize
, позволяющего изменять размеры элементов. - <textarea>: элемент текстового поля — MDN — Документация MDN по элементу
<textarea>
. - Использование пользовательских свойств CSS — MDN — Введение в применение CSS-переменных для создания гибкого дизайна.
- Создание авторазмерного текстового поля — Stack Overflow — Обсуждение в сообществе о текстовых полях с автоматической регулировкой размера.
- Can I use... Support tables for HTML5, CSS3, etc — Удобный ресурс для проверки поддержки браузерами функций CSS.