Textarea в HTML: многострочное поле ввода без типичных ошибок

HTML / Доступность

Textarea в HTML: многострочное поле ввода без типичных ошибок

Как создать доступное textarea, настроить ограничения и стили, отличить readonly от disabled и добавить автоподстройку высоты.

Опубликовано 04.09.2026 5 минут чтения
Содержание статьи

<textarea> — элемент формы для многострочного текста: комментария, сообщения или описания. В отличие от <input>, начальное значение записывается между открывающим и закрывающим тегами.

HTML
<label for="message">Сообщение</label><textarea id="message" name="message" rows="6"></textarea>​

Атрибут name нужен для отправки значения на сервер. Связанный <label> даёт полю доступное имя и увеличивает область, по которой можно нажать для установки фокуса.

Поле в составе формы

HTML
<form action="/feedback" method="post">  <div class="form-field">    <label for="feedback">Ваш отзыв</label>    <textarea      id="feedback"      name="feedback"      rows="6"      minlength="10"      maxlength="1000"      aria-describedby="feedback-hint"      required    ></textarea>    <p id="feedback-hint">От 10 до 1000 символов.</p>  </div>​  <button type="submit">Отправить отзыв</button></form>​

Браузер проверит required, minlength и maxlength перед обычной отправкой. Эта проверка улучшает интерфейс, но сервер всё равно обязан валидировать данные: HTTP-запрос можно отправить в обход HTML.

rows, cols и размеры через CSS

rows задаёт начальную высоту в строках, cols — ожидаемую ширину в символах. Для адаптивного интерфейса ширину удобнее контролировать CSS, сохранив rows как полезную исходную высоту.

CSS
.form-field textarea {  box-sizing: border-box;  display: block;  inline-size: 100%;  min-block-size: 8rem;  padding: 0.75rem;  font: inherit;  line-height: 1.5;  color: inherit;  background-color: #ffffff;  border: 1px solid #8b93a1;  border-radius: 0.5rem;  resize: vertical;}​.form-field textarea:focus-visible {  outline: 3px solid #6d5dfc;  outline-offset: 2px;}​

resize: vertical позволяет менять высоту, не ломая горизонтальную сетку. Полностью запрещать изменение размера без необходимости не стоит.

Placeholder не заменяет label

placeholder исчезает после ввода и часто имеет низкий контраст. Используйте его только как пример формата, а постоянное название оставляйте в <label>.

HTML
<label for="project-description">Описание проекта</label><textarea  id="project-description"  name="description"  rows="8"  placeholder="Например: лендинг для онлайн-курса"></textarea>​

Не добавляйте пробелы и переносы между тегами, если поле должно быть пустым: они становятся начальным значением.

HTML
<!-- Пустое значение --><textarea name="note"></textarea>​<!-- Значение содержит пробелы и перенос --><textarea name="note">​</textarea>​

readonly и disabled — разные состояния

HTML
<textarea name="terms" readonly>Текст можно выделить и скопировать.</textarea>​<textarea name="archived-note" disabled>Поле полностью недоступно.</textarea>​

  • readonly запрещает редактирование, но поле доступно для фокуса и его значение отправляется с формой;
  • disabled исключает элемент из фокуса и отправки формы.

Поэтому disabled нельзя описывать как универсальный режим «только чтение».

Полезные атрибуты

  • autocomplete подсказывает браузеру назначение данных, когда для поля есть подходящее значение;
  • spellcheck="true" включает проверку орфографии там, где она полезна;
  • wrap="soft" управляет переносом при отображении, не добавляя переносы в отправляемое значение;
  • dirname позволяет передать направление введённого текста, что важно для многоязычных интерфейсов;
  • form связывает поле с формой по id, даже если элемент находится вне неё.

Поддержка и поведение некоторых подсказок зависят от браузера, поэтому критические требования должны проверяться на сервере.

Счётчик символов

HTML ограничит длину, а небольшой скрипт покажет остаток:

HTML
<label for="bio">О себе</label><textarea id="bio" name="bio" rows="5" maxlength="300" aria-describedby="bio-count"></textarea><p id="bio-count" aria-live="polite">Осталось 300 символов</p>​

JavaScript
const textarea = document.querySelector('#bio');const counter = document.querySelector('#bio-count');​if (textarea && counter) {  const updateCounter = () => {    const remaining = textarea.maxLength - textarea.value.length;    counter.textContent = `Осталось ${remaining} символов`;  };​  textarea.addEventListener('input', updateCounter);  updateCounter();}​

Автоматическая высота

Inline-обработчик oninput смешивает разметку и поведение. Лучше подключить модуль и подписаться на событие:

HTML
<label for="autosize-message">Сообщение</label><textarea id="autosize-message" data-autosize name="message" rows="3"></textarea><script type="module" src="/assets/js/autosize.js"></script>​

JavaScript
const fields = document.querySelectorAll('[data-autosize]');​function resizeField(field) {  field.style.height = 'auto';  field.style.height = `${field.scrollHeight}px`;}​for (const field of fields) {  field.addEventListener('input', () => resizeField(field));  resizeField(field);}​

Не задавайте одновременно жёсткую высоту и автоподстройку. Проверьте вставку длинного текста, изменение ширины окна и увеличение масштаба.

Безопасный вывод сохранённого значения

Если сервер возвращает текст пользователя в форму, значение необходимо экранировать. В PHP:

PHP
<textarea name="message"><?= htmlspecialchars($message, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?></textarea>​

Нельзя вставлять недоверенный текст как HTML. Клиентские ограничения длины также не отменяют серверную валидацию.

Что запомнить

У <textarea> должны быть постоянный <label> и name. Начальную высоту задавайте через rows, адаптивную ширину — через CSS. Различайте readonly и disabled, не заменяйте подпись placeholder-текстом и всегда повторяйте валидацию на сервере.

Сообщить об ошибке в статье

Рекомендации редакции

Другие публикации из этого раздела.

Новые материалы

Получайте практические разборы без информационного шума

Одна общая рассылка о новых статьях и инструментах. Адрес будет активироваться только после подтверждения.

Подписка появится после подключения сервиса рассылок и Yandex SmartCaptcha.