Атрибут hidden в HTML: как скрыть элемент

Атрибут hidden убирает элемент со страницы целиком: он не занимает места, не попадает на экран и недоступен скринридеру. Использовать его можно с любым HTML-элементом. Указывать значение не нужно - достаточно добавить hidden в открывающий тег.

HTML
<p>Этот текст виден всем</p>
<p hidden>А этот не рендерится вообще</p>

Атрибут hidden в HTML: что это и как работает

У hidden три способа записи, и все они дают один результат - скрытое состояние: пустой атрибут <p hidden>, явное значение hidden="hidden" и даже случайная опечатка вроде hidden="bananas". Любое значение, кроме специального until-found (о нём ниже), браузер трактует одинаково - элемент не рендерится, то есть у него в буквальном смысле нет коробки на странице: он не влияет на расположение соседних элементов, как будто его вообще не существует в разметке.

Это отличает hidden от display: none по происхождению, хотя эффект похож: hidden - это HTML-атрибут, он применяется даже если CSS сайта вообще не загрузился, например в режиме чтения браузера.

Как CSS переопределяет hidden

Скрытое состояние - не железное правило, а обычное поведение браузера по умолчанию, и CSS его перебивает. Если явно задать display элементу с hidden, он снова станет видимым, хотя атрибут hidden из разметки никуда не денется.

Пример: правило CSS побеждает hidden

HTML + CSS
<div hidden>Текст внутри элемента с hidden</div>
<div hidden id="over">Тот же hidden, но со своим правилом display</div>
 
div[hidden]#over {
  display: block;
}
Результат

У второго блока добавлено правило div[hidden]{display:block} - оно побеждает hidden, хотя атрибут в разметке остался.

Отсюда практическая ловушка: достаточно случайного правила с подходящей специфичностью - например, селектора по классу, который задаёт элементу display: flex или display: block - и hidden перестаёт прятать элемент, хотя в разметке он на месте. Чтобы hidden всегда побеждал, в сбросе стилей иногда специально поднимают его приоритет: [hidden] { display: none !important; }.

hidden="until-found": скрыто, но находится через поиск на странице

У hidden есть специальное значение - hidden="until-found". Элемент с ним скрыт визуально, но не выпадает из поиска по странице (Ctrl+F) и из перехода по якорной ссылке на его id. Когда браузер находит внутри такого элемента совпадение или переходит по якорю, он сам снимает атрибут hidden, показывает содержимое и прокручивает страницу к нему - без единой строчки JavaScript для самого раскрытия. Если нужно среагировать на этот момент из кода - например, подгрузить контент лениво - перед самым снятием атрибута на элементе срабатывает событие beforematch.

Пример: hidden="until-found" раскрывается переходом по ссылке

HTML + JavaScript
<a href="#payload">Перейти к блоку</a>
<div id="payload" hidden="until-found">Текст, скрытый до перехода</div>
 
document.getElementById("payload")
  .addEventListener("beforematch", () => {
    // сработает перед тем, как браузер снимет hidden
  });
Результат

До перехода по ссылке блок пуст - виден только его тонкий контур, текста нет. После перехода срабатывает beforematch, hidden снимается сам, текст появляется.

Контур блока в демо виден ещё до раскрытия - это не баг. У until-found, в отличие от обычного hidden, элемент не теряет коробку целиком: браузер использует content-visibility: hidden, при котором поля, рамка и фон элемента всё ещё участвуют в раскладке страницы, пропускается только содержимое. Обычный hidden такой коробки не оставляет вовсе.

input type="hidden" - это не атрибут hidden

Атрибут hidden и <input type="hidden"> - разные механизмы, несмотря на общее слово в названии. Атрибут hidden можно указать на любом теге, и он прячет этот тег со страницы. <input type="hidden"> - это отдельный тип поля формы: он и так никогда не показывается на экране сам по себе, его задача - незаметно для пользователя хранить и отправлять значение вместе с формой, например id записи или csrf-токен. У такого поля hidden-атрибут не нужен: тип уже делает его невидимым, а задача у них разная - скрыть тег вообще или хранить служебное значение формы.

hidden и aria-hidden: разные задачи

hidden и aria-hidden="true" прячут элемент по-разному. hidden убирает его отовсюду разом - и с экрана, и из того, что считывает скринридер. aria-hidden="true" трогает только восприятие скринридером: элемент остаётся виден на экране, просто скринридер его пропускает. Это разные задачи - hidden для содержимого, которое не нужно вообще никому, aria-hidden для декоративных или дублирующих вещей, которые зрячему пользователю видеть нормально, а скринридеру незачем озвучивать - например, иконка рядом с текстом той же ссылки.

Важная тонкость: aria-hidden не убирает фокусируемость. Если внутри элемента с aria-hidden="true" остаётся ссылка или кнопка, она всё ещё получает фокус по Tab, хотя скринридер её не объявляет - это несоответствие важно учитывать при скрытии интерактивных блоков.

Переключение hidden через JavaScript

Переключить hidden из скрипта можно двумя способами с одинаковым результатом: через свойство element.hidden, которое отражает тот же атрибут, или через универсальный toggleAttribute.

Пример: два способа переключить hidden

JavaScript
const box = document.getElementById("box");
 
// способ 1
box.hidden = !box.hidden;
 
// способ 2
box.toggleAttribute("hidden");
Результат

Оба способа управляют одним и тем же атрибутом hidden в разметке - результат не отличается.

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

Часть ошибок с hidden связана не с синтаксисом, а с тем, что скрытие не такое полное, как кажется на первый взгляд.

ОшибкаЧто происходитКак исправить
Скрипты и формы внутри hidden-блока считают неактивнымиДочерний <script> внутри элемента с hidden всё равно выполняется, а поле формы продолжает участвовать в отправке данных - hidden скрывает только отображениеНе полагаться на hidden как на способ отключить логику - для этого нужны отдельные проверки в коде
hidden используют, чтобы спрятать что-то только визуально, оставив доступным скринридеруhidden убирает элемент целиком и от скринридера тоже - исключения для него нетДля «спрятано только от глаз» нужны другие приёмы, а не hidden
CSS-правило с display случайно перебивает hiddenИз-за специфичности или более позднего порядка правило вроде .card{display:flex} включает отображение, хотя hidden в разметке осталсяПроверять, не конфликтует ли hidden с существующими display-правилами, или усиливать hidden через !important в сбросе стилей
hidden путают с input type="hidden"Это разные механизмы: один прячет любой тег целиком, другой - тип поля формы для служебных данныхИспользовать hidden для скрытия элементов, а type="hidden" - для данных формы
hidden="until-found" ожидают раскрыть обычным кликом, без ссылки или поискаСнятие атрибута у until-found происходит только через переход по якорю на id элемента или через поиск по странице - кнопкой без привязки к id или якорной ссылке это не сработаетИспользовать якорную ссылку на id элемента или полагаться на поиск по странице (Ctrl+F)

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

ПравилоЧто запомнить
Где работаетНа любом теге (глобальный атрибут), значение не обязательно
Допустимые значенияПусто, hidden, любое другое (кроме until-found) - все дают одинаковое скрытое состояние
Эффект по умолчаниюЭлемент не занимает места на странице и недоступен скринридеру
Переопределение из CSSdisplay в стилях побеждает hidden, атрибут при этом остаётся в разметке
hidden="until-found"Скрыт визуально, но находится через Ctrl+F или переход по якорной ссылке; коробка (поля, рамка, фон) остаётся
Событие при раскрытии until-foundbeforematch - срабатывает перед тем, как браузер сам снимет атрибут
Скрипты/формы внутри hiddenПродолжают выполняться и участвовать в отправке данных
input type="hidden"Другой механизм - служебное поле формы, не связано с атрибутом hidden
aria-hidden="true"Прячет только от скринридера, элемент остаётся виден на экране
Переключение из JSelement.hidden или toggleAttribute("hidden")
Категория
Поделиться в социальных сетях

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

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

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

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

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