Атрибут readonly в HTML: что это и для чего нужен

Атрибут readonly (по-русски «только для чтения») запрещает посетителю менять значение поля, но поле остаётся рабочим: в него можно встать курсором, выделить текст и скопировать его, а при отправке формы значение уйдёт на сервер. Прописывают readonly в тегах <input> и <textarea>. Он булевый: достаточно самого слова в открывающем теге.

Атрибут readonly в HTML: что это и для чего нужен

Слово readonly складывается из read («читать») и only («только»). Атрибут нужен там, где значение поля важно показать, но менять его посетителю нельзя: номер заказа, цена, адрес, сформированный скриптом, или условия, с которыми человек соглашается.

HTML
<input value="Одесса" readonly>
<textarea readonly>Текст, который нельзя изменить</textarea>
Результат

Введите букву в оба поля: первое меняется, второе нет. В нижней строке видно, что поле readonly совпадает с селектором :read-only.

Поле readonly не выглядит особенным: рамка и цвет текста такие же, как у обычного. Отличить его можно только по поведению, поэтому обычно такие поля оформляют отдельно, как показано в разделе про стили.

Как записать атрибут readonly: какие у него бывают значения

Любая из записей ниже включает режим «только для чтения». Если слово readonly есть в теге, браузер не смотрит на значение: в стандарте для булевых атрибутов важно только присутствие.

HTML
<input value="Одесса" readonly>
<input value="Одесса" readonly="readonly">
<input value="Одесса" readonly="false">
<input value="Одесса">
Результат

У первых трёх полей свойство readOnly равно true, включая запись readonly="false". Выключает режим только полное отсутствие атрибута.

Запись readonly="false" ничего не отключает, это частая ошибка. Чтобы разрешить ввод, атрибут нужно убрать из тега целиком. Запись readonly="readonly" нужна для XHTML и в обычной верстке избыточна.

Для каких тегов и типов input работает readonly

По стандарту readonly работает у <input> с текстовыми типами и датами, а также у <textarea>. Для остальных значений type атрибут не предусмотрен: браузер его не отвергает, но защиты от изменения не даёт. Выберите тип в демонстрации и попробуйте изменить поле.

HTML
<input type="text" value="Odesa" readonly>
<input type="checkbox" checked readonly>
Результат

У text, search, url, tel, email, password, number, date, time и month поле не меняется. У range и checkbox значение меняется, хотя селектор :read-only совпадает.

Где прописан readonlyЗащищает от измененияЧто делать, если нужна защита
text, search, url, tel, email, passwordДаНичего, атрибут работает
number, date, time, month, week, datetime-localДаНичего, атрибут работает
<textarea>ДаНичего, атрибут работает
checkbox, radio, rangeНет, значение меняетсяdisabled и скрытое поле, или блокировка клика скриптом
color, file, hidden, кнопкиНе предусмотрено стандартомdisabled
<select>Нет, у списка такого атрибута нетdisabled и скрытое поле, либо вывести значение текстом

Подробнее о значениях type рассказано на странице атрибута type, а об устройстве полей в уроке «Поля ввода: input и его типы ».

Чем readonly отличается от disabled: фокус, отправка и вид

Оба атрибута мешают посетителю менять значение, но поведение у них разное. Поле readonly остаётся частью формы: оно получает фокус и отправляется. Поле disabled полностью выключено: фокус его обходит, а на сервер оно не попадает.

HTML
<form>
  <input name="a" value="A">
  <input name="b" value="B" readonly>
  <input name="c" value="C" disabled>
  <button type="submit">Отправить</button>
</form>
Результат

Нажмите кнопку: на сервер ушли a и b, поле c отсутствует. Нажимайте Tab: в журнале фокуса есть поле b и нет поля c.

Признакreadonlydisabled
Фокус по клику и по клавише TabЕстьНет
Выделить и скопировать текстМожноЗависит от браузера
Уходит на серверДаНет
Проверка required и patternНе проверяетсяНе проверяется
Вид по умолчаниюКак у обычного поляСерый текст и фон, курсор-стрелка
Совпадает с :read-onlyДаДа

Выбирайте по задаче. Если значение должно дойти до сервера, берите readonly. Если поле нужно временно выключить, например пока не выбран другой вариант, берите disabled.

Как readonly влияет на проверку полей: required и pattern

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

HTML и JavaScript
<input id="e" required readonly>
<input id="g" pattern="[0-9]+" value="abc" readonly>

<script>
console.log(e.willValidate);   // false
console.log(e.checkValidity()); // true
</script>
Результат

Нажмите кнопку: у readonly-полей willValidate равно false, а checkValidity() даёт true, хотя они пустые или не подходят под шаблон. Обычное поле с required не проходит.

Отсюда практический вывод: required вместе с readonly бессмысленно. Если пустое значение недопустимо, заполните поле на сервере или скриптом ещё до показа. О проверке полей подробно рассказано в уроке «Встроенная валидация форм ».

Стиль readonly: селекторы [readonly], :read-only и :read-write

Для оформления есть три способа. Селектор input[readonly] выбирает поля, у которых атрибут есть. Псевдокласс :read-only совпадает с полями, которые посетитель не может изменить, а :read-write с теми, которые может.

CSS
input:read-only {
  background: #ece7dd;
  border-style: dashed;
}

input:read-write:focus {
  outline: 2px solid #2f6fde;
}
Результат

Серую пунктирную рамку получили и поле readonly, и поле disabled. В нижней строке видно, как совпадают оба псевдокласса.

У :read-only есть подвох: :read-only совпадает и с полями disabled, и с обычными блоками вроде <div> без редактирования. Чтобы выбрать только поля readonly, пишите input[readonly] или input:read-only:not(:disabled). Селектор [readonly="readonly"] с полным значением не совпадёт с записью без значения.

Как установить readonly через JavaScript и jQuery

Включить и выключить readonly скрипт может через свойство readOnly. Название пишется с заглавной буквой в середине: свойство с маленькой буквы не работает и просто создаёт лишнее поле объекта. Ещё можно управлять атрибутом: setAttribute('readonly', ''), removeAttribute('readonly') и toggleAttribute('readonly').

JavaScript
const input = document.querySelector('input');

input.readOnly = true;    // включить
input.readOnly = false;   // выключить

input.toggleAttribute('readonly');

input.setAttribute('readonly', 'false'); // всё равно включено
input.readonly = true;    // ошибка: ничего не изменится
Результат

Нажмите вторую кнопку, чтобы выключить режим. Затем нажмите четвёртую: свойство с маленькой буквы ничего не меняет. А третья кнопка включает режим, хотя в значении написано false.

Если на сайте подключён jQuery, привычнее писать через методы. Для булевых значений с версии 1.6 рекомендуют prop(), потому что он работает со свойством, а attr() со строкой атрибута.

jQuery
$('#city').prop('readonly', true);   // включить
$('#city').prop('readonly', false);  // выключить

$('#city').attr('readonly', 'readonly'); // включить через атрибут
$('#city').removeAttr('readonly');       // выключить

Результат у обоих вариантов одинаковый. Если задача решается без библиотеки, достаточно input.readOnly = true.

Что делать, если readonly не работает: checkbox, radio, file и select

У флажков, переключателей и списков readonly не защищает значение, потому что для них стандарт этот атрибут не предусматривает. Флажок с readonly переключается как обычно. Для поля type="file" атрибут тоже не работает: файл выбирают через отдельный диалог, и запретить выбор можно только через disabled.

Если значение флажка должно уйти на сервер, но менять его нельзя, есть два способа. Первый: добавить disabled и продублировать значение скрытым полем. Второй: взять обычный флажок и отменить клик скриптом.

HTML и JavaScript
<input type="checkbox" checked disabled>
<input type="hidden" name="agree" value="on">

<input type="checkbox" name="agree" value="on" checked id="lock">
<script>
lock.addEventListener('click', e => e.preventDefault());
</script>
Результат

Щёлкните по каждому флажку и нажмите кнопку. Флажок readonly снялся, а в отправку не попал. Disabled не отправляется вообще. Заблокированный остался отмеченным и ушёл.

Для списка <select> действует та же схема: disabled и скрытое поле с выбранным значением. Если выбор вообще не нужен, значение проще вывести обычным текстом.

Readonly не защищает данные: проверка на сервере

Атрибут работает только в браузере посетителя, а управлять этим браузером вы не можете. Любой человек может открыть инструменты разработчика, удалить readonly и ввести другое значение. Для сервера такая форма неотличима от настоящей.

HTML и JavaScript
<form>
  <input name="price" value="100" readonly>
</form>

<script>
// то же самое делает посетитель в консоли
price.removeAttribute('readonly');
</script>
Результат

Нажмите первую кнопку, измените число и отправьте форму: на сервер уходит уже изменённая цена.

Поэтому поля, которые нельзя менять, нужно проверять на сервере: цену, номер заказа и другие значения брать из своей базы, а присланным полям не доверять. Атрибут readonly удобен для посетителя, а не для безопасности.

Частые ошибки с атрибутом readonly

Почти все ошибки с readonly сводятся к ожиданию, что атрибут блокирует поле целиком или защищает данные. В таблице собраны такие записи и то, к чему они приводят.

ЗаписьЧто получитсяКак правильно
<input type="checkbox" readonly>Флажок переключается как обычноdisabled и скрытое поле или блокировка клика
<select readonly>Список меняется, атрибут не работаетdisabled и скрытое поле
readonly="false"Поле остаётся только для чтенияУбрать атрибут целиком
input.readonly = trueНичего не происходит, свойство пишется с заглавной буквойinput.readOnly = true
<input disabled>, когда значение нужно серверуПоле на сервер не попадаетИспользовать readonly
<input required readonly>Проверка required не срабатываетЗадать значение заранее, не полагаться на required
readonly как защита цены или номера заказаПосетитель убирает атрибут в консоли и отправляет своёПроверять значение на сервере
setAttribute('readonly', 'false')Режим остаётся включённымremoveAttribute('readonly') или readOnly = false
[readonly="readonly"] в CSSНе совпадает с записью readonly без значения[readonly] или :read-only
input:read-only только для readonly-полейСовпадает ещё с полями disabledinput[readonly]
<input type="file" readonly>Атрибут не предусмотрен для filedisabled
Пустое поле readonly с placeholderПодсказка видна, а ввести ничего нельзяВыводить в value текст вроде «Нет данных»

Шпаргалка по атрибуту readonly

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

Что нужноЧто прописатьТег
Запретить менять текст в поле<input value="Одесса" readonly><input>
Запретить менять многострочный текст<textarea readonly>Текст</textarea><textarea>
Чтобы значение ушло на серверreadonly<input>
Выключить поле совсем<input disabled><input>
Включить из JavaScriptinput.readOnly = true<input>
Выключить из JavaScriptinput.readOnly = false<input>
Включить через jQuery$('#a').prop('readonly', true)<input>
Оформить поля readonlyinput[readonly] { ... }<input>
Защитить флажок<input type="checkbox" checked disabled><input>
Категория
Поделиться в социальных сетях

Отправить комментарий

0 Комментарии

Отправить комментарий (0)

#buttons=(Хорошо) #days=(20)

Мы используем файлы cookie для улучшения работы сайта. Подробнее
Хорошо
×