Pull to refresh

Знакомьтесь, <details>

Reading time3 min
Views62K

Я хочу рассказать о замечательном элементе <details> и показать несколько примеров его использования, от простых до безумных.


Вам знаком паттерн верстки компонента, который может менять своё состояние с видимого на скрытый:


.component {
  display:none;
}

.component.open {
  display:block;
}

toggleButton.onclick = () => component.classList.toggle('open')

А теперь забудьте. Существует элемент, который может делать это из коробки. Знакомьтесь — <details>


HTML-элемент <details> используется для раскрытия скрытой (дополнительной) информации.

Базовое применение


Прежде всего давайте посмотрим как этот элемент работает:



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


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



Чтобы изменить состояние элемента в html вам достаточно добавить атрибут open


<!-- Содержимое по-умолчанию видимо -->
<details open> ... </details>

<!-- Содержимое по-умолчанию скрыто -->
<details> ... </details>

А чтобы управлять состоянием средствами JavaScript предусмотрен специальный API:


const details = document.querySelector('details')

details.open = true  // Отобразить содержимое
details.open = false // Скрыть содержимое

Пара слов о доступности


Элемент <summary> фокусируемый. То есть передвигаясь по странице с клавиатуры вы попадёте на этот элемент. А вот содержимое может попасть в фокус только если <details> открыт, то есть фокус никогда не попадет на невидимые элементы внутри <details>.


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


Примеры использования


Далее я примерно повторю некоторые компоненты из документации bootstrap, но практически без JavaScript.


Изменяем маркер


Первое что вам может понадобится — изменить внешний вид маркера. Делается это очень просто:


summary::-webkit-details-marker {
  /* Любые стили */
}

Или вы можете скрыть стандартный маркер и реализовать собственный


/* Убираем стандартный маркер Chrome */
details summary::-webkit-details-marker {
  display: none
}
/* Убираем стандартный маркер Firefox */
details > summary {
  list-style: none;
}

/* Добавляем собственный маркер для закрытого состояния */
details summary:before {
  content: '\f0fe';
  font-family: "Font Awesome 5 free";
  margin-right: 7px;
}

/* Добавляем собственный маркер для открытого состояния */
details[open] summary:before {
  content: '\f146';
}


Collapse Component


Здесь всё просто. Базовый функционал такой же. Нужно лишь немного изменить внешний вид:



Accordion Component


Повторим предыдущий пример, немного изменим внешний вид <summary> и получим аккордеон:



Но, как видите, один элемент не закрывается когда открывается другой. Чтобы добиться этого нам понадобится пара строк JavaScript. <details> поддерживает событие toggle. Используя это, можно очень легко отслеживать открытие одного элемента и по этому событию закрывать остальные:



Popover Component


Эта реализация очень похожа на Collapse Component, с той разницей что содержимое <details> имеет абсолютное позиционирование и перекрывает контент.



Dropdown Component


В своей основе это тот же Popover Component. Отличается лишь внешний вид.



Тот же пример, только с отдельной кнопкой



Но у Dropdown Component есть ещё одно важное отличие: по клику за его пределами он должен скрываться. Чтобы реализовать это снова понадобится написать пару строк JavaScript.


// По клику на тело документа
document.body.onclick = () => {
  // Найти все открытые <details>
  document.body.querySelectorAll('details.dropdown[open]')
    // И закрыть каждый из них
    .forEach(e => e.open = false)
}

Modal Component


И напоследок пример модального окна.



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


Ссылки


Can I Use Details & Summary elements
MDN details element
W3C details element


UPD.
Решил добавить ещё один пример использования <details> — многоуровневая навигация. Ещё раз хочу обратить ваше внимание на то, что пример работает без какого либо JavaScript. И он намного более инклюзивный чем традиционная верстка на <div>.


Tags:
Hubs:
+60
Comments37

Articles

Change theme settings