Вам часто приходилось использовать JavaScript для создания виджета, показывающего и скрывающего какое-то содержимое? Возможно, для этого вы даже скачивали целую JavaScript-библиотеку? Что ж, можете радоваться: HTML5 позволяет создавать подобное всего лишь парой строчек кода, без применения JavaScript. Зависит от браузера, конечно, но мы вернёмся к этому позже. Представляем вам элемент <details>
.
Вот что о нём написано в спецификации:
Элемент
<details>
представляет собой раскрывающийся виджет, показывающий пользователю дополнительную информацию или элементы управления.
Мы можем использовать <details>
для создания «виджетов-аккордеонов», которые пользователь может разворачивать и сворачивать. Внутри этого элемента можно разместить любое содержимое.
Поддержка браузерами Скопировать ссылку
Прежде чем мы продолжим, вам нужно учесть, что сейчас только Chrome поддерживает элемент <details>
. Скоро к нему присоединится и Opera, но немного костылей нам все-таки понадобится. Что ж, запускайте Chrome, и давайте смотреть.
Использование <details>
Скопировать ссылку
Имеются два элемента: <details>
и необязательный <summary>
. Элемент <details>
— это обёртка для содержимого, которое мы хотим показать и скрыть, а <summary>
содержит описание и заголовок этой группы. Формально <summary>
нам не нужен. В его отсутствие браузер подставит текст по умолчанию, например «details» в Chrome. Давайте взглянем на код:
<details>
<summary>Покажи-скрой меня</summary>
<p>Бурное развитие внутреннего туризма привело Томаса Кука.</p>
</details>
Вы можете посмотреть это в действии на jsbin. Даже этот простой пример прекрасно демонстрирует эффект переключения. Без JavaScript!
Атрибут open
Скопировать ссылку
В вышеприведенном примере содержимое скрыто при загрузке страницы. Мы можем сделать его видимым по умолчанию, добавив одиночный атрибут open
для <details>
, пример на jsbin:
<details open>
<summary>Покажи-скрой меня</summary>
<p>Бурное развитие внутреннего туризма привело Томаса Кука.</p>
</details>
Атрибута closed
не существует. Поэтому, опуская open
, вы по умолчанию подразумеваете closed
.
Элемент <summary>
Скопировать ссылку
Мы бегло взглянули на <summary>
в действии, теперь остановимся на нём подробнее. Внутри <summary>
могут использоваться строчные элементы, такие как <span>
или <strong>
. Для чего это может быть нужно? Например, для дополнительного оформления или, как предлагает спецификация, использования <label>
для элемента формы. По крайней мере, было бы удобно, если бы подобная конструкция работала корректно:
<details>
<summary><label for="name">Имя:</label></summary>
<input type="text" id="name" name="name" />
</details>
Теоретически, нажатие на <summary>
должно раскрывать содержимое элемента <details>
. Но в этом примере содержимое не будет развернуто, потому что вы, фактически, взаимодействуете с <label>
, который переводит фокус на соответствующий <input>
— даже если он скрыт с помощью <details>
.
Честно говоря, этот момент еще требует прояснения. А что по вашему мнению должно происходить? Возможно, у разработчиков браузеров, читающих эту статью, есть какие-то идеи? :)
Вложенность <details>
Скопировать ссылку
Вы можете помещать <details>
друг в друга, если хотите, как это сделано в следующем, вполне валидном примере:
<details>
<summary>Вопрос 1</summary>
<p>Население превышает широкий кристаллический фундамент.</p>
<details>
<summary>Приложенные документы</summary>
<ul>
<li><a href="#">Болгары очень дружелюбны;</a></li>
<li>Скумбрия неумеренно перевозит вулканизм;</li>
<li>Дождливая погода, куда входят Пик-Дистрикт;</li>
<li>Белый саксаул дегустирует живописный утконос;</li>
</ul>
</details>
</details>
Примеры использования Скопировать ссылку
Так в каких же случаях вы можете использовать <details>
? Первое, что приходит в голову — FAQ. Разработчики часто используют для них «аккордеоны», поэтому <details>
замечательно подходит.
Также не забывайте о навигации по странице. Это может быть закрепленный блок, передвигающаяся одновременно с прокруткой. Возможно, что-то вроде этого?
Вы можете использовать <details>
для сворачивания и разворачивания блока комментариев в блоге, для профиля пользователя, для описания загружаемого файла, для сложных форм или в веб-приложениях, как показано в этом примере из спецификации:
На самом деле, даже глядя сейчас на админку WordPress, я вижу множество возможностей использования <details>
. Если у вас есть ещё какие-то идеи и предложения — расскажите о них в комментариях.
Оформление Скопировать ссылку
Как же нам оформить эту штуку? Для элемента, раскрывающего содержимое, в WebKit вы можете использовать псевдоэлемент ::-webkit-details-marker
. Небольшой пример:
details summary::-webkit-details-marker {
background: red;
color: #fff;
font-size: 500%;
}
Мы также можем позиционировать этот элемент по отношению к родителю. Здесь, например, он прижат к правому краю. В общем-то, и все.
А как же заменить раскрывающий элемент своей иконкой? Используя выборку по атрибуту, вы можете определить, когда <details>
раскрыт, а когда закрыт, и применить соответствующее фоновое изображение. Мы делаем примерно то же самое в этом примере, за исключением того, что вместо фонового изображения мы используем псевдоэлемент ::after
:
summary::-webkit-details-marker {
display: none
}
summary::after {
background: red;
border-radius: 5px;
content: "+";
color: #fff;
float: left;
font-size: 1.5em;
font-weight: bold;
margin: -5px 10px 0 0;
padding: 0;
text-align: center;
width: 20px;
}
details[open] summary::after {
content: "-";
}
В этом примере символы +
и -
используются в качестве раскрывающей ссылки. В зависимости от дизайна вы можете использовать ::before
вместо ::after
, но, в любом случае, оба псевдоэлемента позволяют использование изображения.
Выборка по атрибуту details[open]
скрывает в себе некоторые интересные возможности. Как хорошие HTML5-доктора, мы создали доработанный пример, показанный на этом скриншоте:
Было бы интересно (хотя это и не всегда уместно), если бы мы могли использовать CSS-трансформации для анимации разворачивания и сворачивания <details>
, но пока это невозможно.
Доступность Скопировать ссылку
К сожалению, на момент написания статьи отсутствует возможность управления <details>
с помощью клавиатуры. Стив Фолкнер пишет:
Проблема в том, что на данный момент отсутствует поддержки клавиатуры и нет никакой информации для обеспечения доступности.
Попробуйте сами. Если вы раскроете элемент <details>
с помощью мыши, тогда вы сможете использовать клавиатуру для навигации по вложенным элементам, но вы также должны иметь возможность открывать и закрывать <details>
с клавиатуры. Что ж, неидеально, но я уверен, что разработчики Chrome скоро с этим разберутся. Правда, ребята?
Обратная совместимость Скопировать ссылку
Прежде чем кто-то начнет восклицать, что это не работает в IE6, хочу сказать: мы знаем. Тем не менее, благодаря некоторым умным людям, мы можем обеспечить изящную обратную совместимость. В этой очень полезной коллекции всевозможных кроссбраузерных костылей я нашел два решения, оба они требуют jQuery:
- Обратная совместимость для
<details>
с помощью jQuery от Матиаса Байненса; - Еще одна альтернатива
<details>
, также основанная на jQuery от Мануэля Бье.
Многие из вас захотят использовать Modernizr для определения возможностей браузера, но на данный момент в Modernizr отсутствует проверка поддержки <details>
. Матиас, автор приведенного выше решения для обратной совместимости, предлагает использовать этот Modernizr-сниппет.
Зачем вообще это использовать? Скопировать ссылку
Конечно, дарёному коню в зубы не смотрят, но все-таки — почему этот виджет существует в HTML5? Что ж, как и в случае с другими возможностями HTML5, он просто делает нашу жизнь легче. Реализация таких элементов, как календарь, слайдер, прогресс-бар, а теперь ещё и «аккордеон», становится гораздо проще и не требует использования JavaScript. Кто знает, что будет следующим? Нативные табы? Было бы здорово :)
В заключение Скопировать ссылку
В этой статье мы продемонстрировали, как использовать элементы <details>
и <summary>
. Элемент <details>
при помощи <summary>
создаёт естественный для браузера интерактивный раскрывающийся виджет.
На текущий момент <details>
работает только в Chrome, но, надеюсь, эта ситуация в скором времени изменится. Пока что мы можем использовать в CSS только ::-webkit-details-marker
, но есть и множество других CSS-техник. Если у вас есть какой-либо опыт или идеи для использования элемента <details>
, расскажите об этом в комментариях.