W3docs

Атрибут HTML contenteditable

Атрибут contenteditable определяет, можно ли редактировать содержимое элемента. Значения, работа с JavaScript и советы по доступности.

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

Поскольку атрибут работает практически с любым элементом, contenteditable может превратить <div>, <p> или целый раздел в область редактирования. Он входит в состав глобальных атрибутов и доступен для любого HTML-элемента.

Когда использовать contenteditable

contenteditable — это основа встроенного редактирования. Вы встретите его в:

  • Редакторах форматированного текста (блоки «WYSIWYG» в CMS, почтовых клиентах и формах комментариев). В отличие от <textarea>, редактируемый элемент может содержать настоящий HTML — жирный текст, ссылки, списки и изображения — и пользователь видит форматированный результат прямо в процессе набора.
  • Встроенном редактировании — когда пользователь кликает на заголовок или ячейку таблицы, чтобы переименовать её на месте, не открывая отдельную форму.
  • Интерфейсах предварительного просмотра и заметок, где область редактирования является отображаемым результатом.

Используйте <textarea> или <input>, если вам нужен только простой текст, который отправляется с формой: это настоящие поля формы, они поддерживают валидацию и автоматически передают своё значение. Прибегайте к contenteditable, когда нужен форматированный (HTML) контент или когда редактирование должно происходить внутри существующей разметки страницы.

Синтаксис

<tag contenteditable="true">...</tag>

Атрибут принимает следующие значения:

ЗначениеОписание
true (или "")Элемент доступен для редактирования. Пустая строка работает так же, как true.
falseЭлемент недоступен для редактирования.
inheritЭлемент наследует состояние редактирования от ближайшего родителя. Это также значение по умолчанию, если атрибут не указан.
plaintext-onlyЭлемент доступен для редактирования, но форматирование отключено — принимается только простой текст. Поддерживается современными браузерами, но перед использованием проверьте поддержку.

Пример

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <p contenteditable="false">
      This is a paragraph. It is not editable.
    </p>
    <p contenteditable="true">
      This is a paragraph. It is editable. Try to change this text.
    </p>
  </body>
</html>

Наследование со значением inherit

Если contenteditable не задан для дочернего элемента, он наследует состояние редактирования от родителя. Можно сделать всю область редактируемой на уровне родителя, а затем отдельный дочерний элемент отключить с помощью contenteditable="false":

<!DOCTYPE html>
<html>
  <head>
    <title>contenteditable inherit example</title>
  </head>
  <body>
    <div contenteditable="true">
      <p>This paragraph inherits editing from the div, so you can change it.</p>
      <p contenteditable="false">
        This paragraph opts out — it is locked and cannot be edited.
      </p>
      <p contenteditable="inherit">
        This one explicitly inherits, so it is editable again.
      </p>
    </div>
  </body>
</html>

Чтение и сохранение отредактированного содержимого с помощью JavaScript

Элемент с contenteditable — это не поле формы, поэтому его значение не отправляется вместе с формой и у него нет свойства value. Вместо этого содержимое читается непосредственно из элемента:

  • element.innerHTML — отредактированное содержимое в виде HTML (сохраняет жирный текст, ссылки, списки).
  • element.textContent — отредактированное содержимое в виде простого текста (форматирование убирается).

Чтобы реагировать на правки в реальном времени, следует прослушивать событие input, которое срабатывает при каждом изменении:

<!DOCTYPE html>
<html>
  <head>
    <title>Save editable content</title>
  </head>
  <body>
    <div id="editor" contenteditable="true">
      Edit me, then reload the page.
    </div>

    <script>
      const editor = document.getElementById("editor");

      // Restore any previously saved content.
      const saved = localStorage.getItem("note");
      if (saved !== null) {
        editor.innerHTML = saved;
      }

      // Save on every edit.
      editor.addEventListener("input", () => {
        localStorage.setItem("note", editor.innerHTML);
        // In a real app you would debounce this and POST it to a server, e.g.
        // fetch("/api/save", { method: "POST", body: editor.innerHTML });
      });
    </script>
  </body>
</html>
Внимание

Сохранение innerHTML напрямую на сервер означает хранение сырого HTML. Всегда санируйте ненадёжный HTML на сервере (или с помощью проверенной клиентской библиотеки) перед сохранением или повторным отображением, чтобы предотвратить межсайтовый скриптинг (XSS).

Доступность

Обычный элемент с contenteditable выглядит редактируемым, но, в отличие от настоящего поля формы, он не предоставляет никакой семантики поля для вспомогательных технологий — экранные читалки могут не объявить его как элемент, в который можно вводить текст. При создании пользовательского редактора помогите им:

  • Добавьте role="textbox", чтобы элемент объявлялся как редактируемое текстовое поле. Добавьте aria-multiline="true", если поле принимает несколько строк.
  • Добавьте aria-label (или свяжите видимый <label> через aria-labelledby), чтобы у поля было доступное имя.
  • Добавьте tabindex="0", если элемент не получает фокус по умолчанию, чтобы пользователи клавиатуры могли до него добраться.
<div
  contenteditable="true"
  role="textbox"
  aria-multiline="true"
  aria-label="Comment"
  tabindex="0"
>
  Type your comment…
</div>

Несоответствия между браузерами

contenteditable — мощный инструмент, однако его поведение не одинаково в разных браузерах. Именно поэтому в продакшн-приложениях обычно используют библиотеку (или значение plaintext-only), а не сырой contenteditable:

  • Поведение клавиши Enter различается. Нажатие Enter может обернуть новую строку в <div>, <p> или вставить <br>, в зависимости от браузера. Не рассчитывайте на конкретную структуру сгенерированного HTML.
  • Вставка зачастую привносит стили и теги из источника; возможно, потребуется перехватить событие paste и очистить содержимое.
  • plaintext-only отключает форматирование, но поддерживается не везде — перед использованием проверяйте поддержку методом обнаружения функциональности.

Связанные атрибуты

  • spellcheck — включает или отключает проверку орфографии в браузере внутри редактируемой области.
  • draggable — управляет возможностью перетаскивания элемента.
  • Глобальные атрибуты — полный набор атрибутов, применимых к любому элементу.

Практика

Практика
Какие из следующих утверждений верны относительно атрибута HTML contenteditable?
Какие из следующих утверждений верны относительно атрибута HTML contenteditable?
Was this page helpful?