Подробности и резюме

Узнайте, как работают очень полезные детали и элементы сводки и где их использовать.

Виджет раскрытия — это элемент управления пользовательского интерфейса, который скрывает и показывает контент. Если вы читаете это на web.dev и ширина вашего окна просмотра меньше 106 em, нажатие на «На этой странице» над этим абзацем откроет оглавление этого раздела. Если вы его не видите, уменьшите браузер, чтобы просмотреть навигацию по оглавлению на этой странице в виде виджета раскрытия.

Графический пользовательский интерфейс «аккордеон» представляет собой серию вертикально расположенных виджетов раскрытия информации. Распространенным вариантом использования пользовательского интерфейса аккордеона является страница часто задаваемых вопросов (FAQ) на многих сайтах. FAQ по аккордеону содержит список видимых вопросов; нажатие на вопрос расширяет или «раскрывает» ответ на этот вопрос.

jQuery включает в себя шаблон пользовательского интерфейса «аккордеон», по крайней мере, с 2009 года. Исходное решение «аккордеон» без JavaScript включало создание для каждого вопроса часто задаваемых вопросов <label> , за которым следовала помеченная им галочка, а затем отображался ответ <div> , когда галочка была отмечена. CSS выглядел примерно так:

#FAQ [type="checkbox"] + div.answer {
  /* all the answer styles */
  display: none;
}
#FAQ [type="checkbox"]:checked + div.answer {
  display: block;
}

Почему история? Виджеты раскрытия информации, такие как аккордеоны, без JavaScript или хаков управления формами, появились сравнительно недавно; элементы <details> и <summary> полностью поддерживаются во всех современных браузерах только с января 2020 года. Теперь вы можете создавать функциональные, хотя и не слишком привлекательные виджеты раскрытия информации, используя только семантический HTML. Элементы <details> и <summary> — это все, что вам нужно: они представляют собой встроенный способ управления раскрытием и свертыванием содержимого. Когда пользователь щелкает или касается <summary> или отпускает клавишу Enter , когда <summary> находится в фокусе, содержимое родительского элемента <details> становится видимым!

Как и любой другой семантический контент, вы можете постепенно улучшать функции и внешний вид по умолчанию. В данном случае было добавлено немного CSS, но больше ничего:

Обратите внимание, что эти Codepens не содержат JavaScript.

Переключение видимости: атрибут open

Элемент <details> — это контейнер виджета раскрытия. <summary> — это сводка или легенда для родительского элемента <details> . Сводка отображается всегда и действует как кнопка, переключающая отображение остального содержимого родительского элемента. Взаимодействие с <summary> переключает отображение самомаркированных одноуровневых сводных элементов путем переключения атрибута open элемента <details> '.

open атрибут является логическим атрибутом. Если он присутствует, независимо от его значения или его отсутствия, он указывает, что пользователю показано все содержимое <details> . Если атрибут open отсутствует, отображается только содержимое <summary> .

Поскольку атрибут open добавляется и удаляется автоматически при взаимодействии пользователя с элементом управления, его можно использовать в CSS для различного оформления элемента в зависимости от его состояния.

Вы можете создать аккордеон со списком из нескольких элементов <details> , каждый из которых имеет дочерний элемент <summary> . Отсутствие атрибута open в HTML означает, что все <details> будут свернуты или закрыты, и при загрузке страницы будут видны только сводные заголовки; каждый заголовок является началом остального содержимого родительского элемента <details> . Если вы включите атрибут open в свой HTML, <details> будет отображаться развернутым, а содержимое будет видимым при загрузке страницы.

Скрытый контент в свернутом состоянии доступен для поиска в некоторых браузерах, но не в других, даже если свернутый контент не является частью DOM. Если вы выполняете поиск в Edge или Chrome, сведения, содержащие поисковый запрос, будут расширены, чтобы отобразить вхождение. Такое поведение не воспроизводится в Firefox или Safari.

<summary> должен быть первым дочерним элементом элемента <details> , представляющим сводку, заголовок или легенду для остального содержимого родительского элемента <details> , в который он вложен. Содержимым элемента <summary> может быть любое содержимое заголовка, обычный текст или HTML, который можно использовать внутри абзаца.

Переключение маркера сводки

В двух предыдущих Codepen вы увидите стрелку, указывающую на начало строки сводки. Виджет раскрытия обычно отображается на экране в виде небольшого треугольника, который вращается (или поворачивается), указывая на открытое/закрытое состояние, с меткой рядом с треугольником. Содержимое элемента <summary> обозначает виджет раскрытия. Вращающаяся стрелка вверху каждого раздела — это ::marker , установленный в элементе <summary> . Как и элементы списка, элемент <summary> поддерживает сокращенное свойство list-style и его полные свойства, включая list-style-type . Вы можете стилизовать треугольник раскрытия с помощью CSS, в том числе изменить используемый маркер с треугольника на любой другой тип маркера, включая изображение, с помощью list-style-image .

Чтобы применить другие стили, используйте селектор, аналогичный details summary::marker . Псевдоэлемент ::marker принимает только ограниченное количество стилей. Удаление ::marker и замена его на более простой в оформлении ::before является обычной практикой, при этом стили CSS слегка меняют стиль генерируемого контента в зависимости от наличия (или отсутствия) атрибута open. Вы можете удалить значок виджета раскрытия, установив list-style: none или установив для содержимого маркера значение none , но всегда включайте визуальные индикаторы, чтобы информировать зрячих пользователей о том, что сводное содержимое представляет собой кнопку-переключатель, которая будет отображать и скрывать содержимое при активации.

details summary::before {
  /* all the styles */
}
details[open] summary::before {
  /* changes applied when open only */
}

В этом примере удаляется маркер по умолчанию и добавляется сгенерированное содержимое, чтобы создать + , когда сведения закрыты, и - когда сведения открыты.

Если вы хотите, чтобы блок сведений открывался по умолчанию, включите атрибут open в открывающий тег <details> . Вы также можете добавить пространство между каждым диалогом и изменить вращение маркера, созданного с помощью сгенерированного содержимого, чтобы улучшить внешний вид:

Как обрабатываются ошибки

Если вы не включили <summary> , браузер создаст его для вас: с маркером и словом «подробности». Эта сводка является частью теневого корня , поэтому к ней не будут применены авторские стили сводки CSS. К сожалению, Safari не включает детали в порядок фокусировки клавиатуры .

Если вы включили <summary> , но это не первый элемент в <details> , браузер все равно отображает сводку так, как должно. Это также не помешает, если вы включите ссылку, метку или другой интерактивный элемент в сводку, но браузеры по-разному обрабатывают интерактивный контент внутри интерактивного контента. Например, если вы включите ссылку в сводку, некоторые браузеры добавят и сводку, и ссылку в порядок табуляции по умолчанию, но другие браузеры по умолчанию не будут фокусироваться на ссылке. Если вы нажмете на <label> вложенный в <summary> , некоторые браузеры передадут фокус соответствующему элементу управления формой; другие браузеры будут уделять внимание элементу управления формой и переключать <details> на открытие или закрытие.

Интерфейс HTMLDetailsElement

Как и все элементы HTML, HTMLDetailsElement наследует все свойства, методы и события от HTMLElement и добавляет свойство open экземпляра и событие toggle . Свойство HTMLDetailsElement.open представляет собой логическое значение, отражающее open атрибут HTML и указывающее, должно ли содержимое элемента (не считая <summary> ) отображаться пользователю. Событие переключения вызывается, когда элемент <details> открывается или закрывается. Вы можете прослушать это событие, используя addEventListener() .

Если вы хотите написать скрипт, который будет закрывать открытые данные, когда пользователь открывает какие-либо другие данные, удалите атрибут open с помощью removeAttribute("open") :

Это единственный пример использования JavaScript. Вам, вероятно, не понадобится JavaScript, за исключением функции закрытия других открытых виджетов раскрытия.

Помните, что <details> и <summary> могут иметь строгие стили и даже использоваться для создания всплывающих подсказок . Но если вы собираетесь использовать эти семантические элементы в случаях, когда собственная семантика не соответствует, всегда обеспечивайте доступность . HTML по большей части доступен по умолчанию. Наша задача как разработчиков — обеспечить доступность нашего контента.

Проверьте свое понимание

Проверьте свои знания деталей и резюме.

<summary> должен быть первым дочерним элементом какого элемента?

<p>
Попробуйте еще раз.
<details>
Правильный!
<fieldset>
Попробуйте еще раз.