20 простых способов оформления элемента HTML details

В этой статье мы рассмотрим некоторые простые способы стилизации HTML-элемента <details>, который очень полезен для отображения и скрытия фрагментов контента на веб-странице.

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

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

Table of Contents

Введение элемента деталей

Вот базовый код для элемента <details>:

<details>
  <summary>Click me!</summary>
  <p>Peekaboo! Here's some hidden content!</p>
</details>

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

Вот живой пример этого кода:

Click me!

Пeekабу! Вот некоторый скрытый контент!

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

Цвета фона, границы и отступы

A really simple way to enhance the look of the <details> element is to add some padding along with a border or some background colors.

Добавление границы

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

details {
  padding: 10px; 
  border: 5px solid #f7f7f7;
  border-radius: 3px;
}

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

Добавление цвета фона

Давайте добавим цвет фона к нашему элементу <details> вместо границы:

details {
  padding: 10px;
  background-color: #e4eaef;
  border-radius: 5px;
}

Результат показан в стиле ниже.

Цвет фона дает элементу лучшее определение, а отступы помогают создать некоторое пространство внутри него.

Мы также можем дать другой цвет фона элементу <summary> для отличия его от остального контента и изменить цвет его текста:

summary {
  background-color: #2196F3;
  color: white;
  padding: 10px;
}

Обратите внимание, что изменение цвета текста элемента <summary> также меняет цвет маркера-стрелки. Это происходит потому, что маркер присоединен к элементу <summary> так же, как маркеры (например, точки) присоединены к пунктам списка. Мы увидим ниже, как стилизовать их отдельно.

Стилизация маркера

Элемент <summary> установлен с display равным list-item. Поэтому стандартная стрелка (▶), которая идет с ним, может быть изменена так же, как стандартные маркеры в HTML-пунктах списка. Мы можем изменить символ, который используется, и независимо изменить его цвет.

Изменение цвета маркера

Давайте установим стандартный маркер в другой цвет. Просто для удовольствия, давайте также увеличим размер шрифта маркера. Это можно сделать с помощью псевдо-элемента ::marker:

summary::marker {
  color: #e162bf;
  font-size: 1.2em;
}

Результат показан ниже.

Это хорошее, простое решение, хотя, к сожалению, ::marker не поддерживается в Safari, поэтому см. другие варианты ниже, если это является критичным.

Изменение расстояния маркера

По умолчанию, маркер-стрелка расположен довольно близко к тексту summary. Его list-style-position установлен как inside. Если мы изменим его на outside, мы можем добавить пространство между текстом summary и маркером, добавив немного левого padding. Нам также нужно добавить некоторое левое margin, чтобы треугольник не выступал за пределы контейнера:

summary {
  list-style-position: outside;
  margin-left: 30px;
  padding: 10px 10px 10px 20px;
  border-radius: 5px;
}

Результат показан ниже.

I’ve exaggerated the spacing between the arrow marker and the summary text just to make it obvious. Unfortunately, using list-style-position: outside; with the <summary> element doesn’t work in Safari. Fortunately, there are other options, as we’ll see below.

Изменение формы маркера

Маркер на нашем элементе <summary> не обязательно должен быть треугольником. Мы можем заменить его любым символом по своему усмотрению:

summary {
  list-style-type: '⬇ ';
} 

Обратите внимание, что мы использовали '⬇ ' (с пробелом рядом с стрелкой), что является альтернативой пробелам, которые мы пробовали выше.

Теперь у нас есть стрелка вниз вместо треугольника. Но … эта стрелка вниз не изменится, когда элемент <details> открыт. Это происходит потому, что элемент <details> имеет два состояния — closed и open — и мы установили стиль маркера только для состояния closed. Итак, давайте также установим маркер для состояния open:

details[open] > summary {
  list-style-type: '⬆ ';
}

На этот раз мы использовали стрелку, указывающую вверх. Это дает нам результат, показанный ниже.

Черт! Опять же, Safari подводит нас, так как он также не поддерживает list-style-type на элементе <summary>. Не расстраивайтесь, однако, мы рассмотрим более сложные решения ниже.

Мы можем попробовать всевозможные другие символы, такие как + и –, ✓ и Χ или ✗, ⋁ и ⋀, и даже повеселиться с другими символами, такими как ★ или разноцветными фруктами, как 🍏 🍌 🍓 🍋 и 🍐, но помните, что эти символы могут не работать на всех системах, поэтому будьте немного осторожны, и опять же, list-style-type определенно не будет работать в Safari.

Создание пользовательского маркера для элемента summary

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

Удаление настраиваемого маркера

Как и с маркерами элементов списка, мы можем удалить маркер полностью:

summary  {
  list-style: none;
}

/* опять же, Safari */

summary::-webkit-details-marker {
  display: none;
}

Стандартное list-style: none работает во всех браузерах, кроме… (ты догадался?)… Safari. По крайней мере, в этом случае есть проприетарный -webkit- вариант.

Примечание: другой способ удалить маркер из элемента <summary> – это присвоить элементу <summary> значение display, отличное от list-item — например, block или flex. Это работает во всех браузерах, кроме… (мне даже говорить не нужно?)… Safari.

Теперь наш элемент не имеет маркера.

Отсутствие маркера не дает никакого визуального подсказки о том, что этот элемент кликабелен, поэтому не лучшая идея оставлять его в таком виде.

Использование фонового изображения в качестве маркера

Мы могли бы разместить изображение на фоне, вот так:

summary {
  list-style: none;
  padding: 10px 10px 10px 40px;
  background: url(arrow.svg) no-repeat 14px 50%;
  background-size: 18px;
  font-weight: bold;
}

Результат показан ниже.

Недостатком использования фонового изображения на элементе <summary> является то, что мы не можем вращать его, когда элемент <details> открыт, потому что анимации не могут быть установлены непосредственно на фоновых изображениях в CSS. (Конечно, мы могли бы использовать другое изображение для открытого состояния, но все равно не смогли бы его анимировать, что было бы намного интереснее.) Поэтому, если мы собираемся использовать фоновое изображение, лучше разместить его на элементе, который может быть повернут и/или анимирован.

Использование фонового изображения в качестве маркера с ::after

Давайте поместим фоновое изображение в псевдоэлемент ::after:

summary {
  display: flex;
}

summary::after {
  content: '';
  width: 18px;
  height: 10px;
  background: url('arrow.svg');
  background-size: cover;
  margin-left: .75em;
  transition: 0.2s;
}

details[open] > summary::after {
  transform: rotate(180deg);
}

Вот живой пример этого кода.

Мы использовали display: flex на элементе <summary>, чтобы легко позиционировать стрелку по горизонтали.

Плюс этой конфигурации в том, что мы можем добавить анимацию для стрелки. (Анимация, похоже, не работает в Safari, но поведение достаточно хорошее, и я немного устал от этого браузера!)

Делаем элемент summary похожим на вкладку

Мы устанавливали элемент <summary> на полную ширину, но это не обязательно. Мы могли бы сделать его более похожим на вкладку, с этим простым изменением:

summary {
  display: inline-flex;
}

Пример показан ниже.

Ограничение ширины элемента details

Во всех наших примерах до сих пор элемент <details> растягивался на полную ширину своего контейнера, так как он является блочным элементом. Однако мы можем задать ему другую ширину, если не хотим, чтобы он был таким широким, например width: 50%;. Или мы могли бы установить ему встроенное отображение, чтобы он был такого размера, как и его содержимое:

details {
  display: inline-block;
}

Нажмите на вкладку ниже, чтобы открыть меньшую ширину элемента <details>.

Попробуйте изменить display: inline-block на width: 50% в Пен-коде выше.

Размещение маркера стрелки на дальнем конце summary

Теперь давайте сделаем кое-что немного другое, поместив маркер стрелки на правой стороне элемента <summary>. Поскольку мы использовали display: flex, переместить стрелку в дальний правый угол так же просто, как добавить justify-content: space-between к элементу <summary>:

summary {
  display: flex;
  justify-content: space-between;
}

Использование ::after в качестве маркера без фонового изображения

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

summary::after {
  content: '';
  width: 0; 
  height: 0; 
  border-top: 10px solid #15171b;
  border-inline: 7px solid transparent;
  transition: 0.2s;
}

Вот живой демонстрационный пример.

Теперь у нас есть стрелка, которая вращается между закрытым и открытым состоянием. Мы также добавили хороший затенение тени к элементу <details>.

Еще один способ использования ::after без изображения – это размещение символов Unicode в свойстве content:

summary::after {
  content: "\25BC";
  transition: 0.2s;
}

Это устанавливает треугольную форму (▼) в качестве нашего маркера, как показано в демо на CodePen.

Существует тысячи символов Unicode, и их довольно интересно исследовать. Каждый из них имеет код, например, U + 25BC или U + 025BC. Чтобы использовать этот код внутри свойства content, возьмите символы после + и поместите их внутри кавычек content с \ в начале: content: "\25BC". Если в начале есть один или несколько нулей, их можно опустить. (Например, U + 02248 может стать "\02248" или "\2248".)

Разное

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

Эффект наведения на элементе <details>

Мы можем установить различные эффекты наведения на элементе <details>. Например, мы могли бы сделать что-то вроде этого:

details {
  transition: 0.2s background linear;
}

details:hover {
  background: #dad3b1;
}

Пока мы это делаем, давайте также переведем цвет текста элемента <summary> в состоянии open:

details > summary {
  transition: color 1s;
}

details[open] > summary {
  color: #d9103e;
}

Результат показан ниже.

Мы также можем просто изменить фон элемента <summary>.

Анимация открытия и закрытия элемента <details>

Хаха, обманул тебя! Похоже, невозможно анимировать открытие и закрытие элемента <details>. Согласно MDN:

К сожалению, на данный момент нет встроенного способа анимировать переход между открытым и закрытым состояниями.

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

details article {
  opacity: 0;
}

details[open] article {
  animation: fadeIn .75s linear forwards;
}

@keyframes fadeIn {
 0% {
   opacity: 0;
 }
 100% {
   opacity: 1;
 }
} 

Результат показан ниже.

Другой трюк может заключаться в том, чтобы содержимое скользило, вот так:

details {
  overflow: hidden;
}

details[open] article {
  animation: animateUp .5s linear forwards;
}

@keyframes animateUp {
  0% {
    opacity: 0;
    transform: translatey(100%);
  }
  100% {
    opacity: 1;
    transform: translatey(0);
  }
}

Результат показан ниже.

Это немного кислое и, возможно, чрезмерно, но стоит попробовать в любом случае. К сожалению, эти анимации работают только при первом клике по элементу (если только открыты инструменты разработчика браузера, по какой-то странной причине!). Вам по сути нужно вмешательство JavaScript, чтобы эффект работал повторно.

Изменение содержимого summary в открытом и закрытом состояниях

В демо-версиях выше <select> всегда имел одинаковый текст, независимо от того, открыт или закрыт элемент <details>. Но мы могли бы это изменить. Во-первых, давайте оставим текущий текст “Нажми меня”, но также добавим дополнительный текст для каждого состояния с помощью псевдоэлемента ::after:

summary::after {
  content: " to show hidden content";
}

details[open] summary::after {
  content: " to hide extra content";
}

Это дает нам результат, показанный ниже.

Изменение курсора summary

Стандартный курсор (или указатель мыши) для элемента `<details>` выглядит немного странно. По большей части это обычная стрелка, а при наведении на текст `<summary>` становится текстовым указателем (или I-образным).

Для интереса изменим его на курсор в виде руки (или “указателя”):

summary {
  cursor: pointer;
}

Это устанавливает курсор мыши в виде руки при наведении на любую часть элемента `<summary> как показано ниже.

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

Изменение стилей доступности для фокуса

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

Они довольно похожи: в основном простая, темная (синяя или черная), сплошная рамка шириной около `3px`.

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

summary:focus {outline: none;}
summary:focus-visible {outline: 3px dotted #ff0060;}
summary {padding: 10px;}

По умолчанию контур фокуса не отображается при нажатии на элемент <summary>. Но если мы изменим стиль фокуса, этот стиль отображается даже для неклавиатурных пользователей (то есть, когда мы кликаем на элемент <details> с помощью мыши). Таким образом, в коде выше мы установили outline на none и вместо этого использовали focus-visible для установки стилей, так как это означает, что стили фокуса будут видимы только для пользователей клавиатуры (для которых это действительно полезно).

На изображении ниже показано наше новое оформление.

Вот живой демонстрационный пример.

С этим можно насладиться, используя анимации, цвета фона и т.д., когда элемент <details> находится в фокусе. Я оставляю это вам для дальнейшего экспериментирования.

Использование нескольких элементов деталей, как в списке аккордеонов

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

На данный момент нет способа сделать это только с помощью HTML и CSS, но есть несколько остроумных примеров, которые делают это с помощью JavaScript (например, здесь, здесь, и здесь).

Лучшее, что мы можем сделать с помощью CSS, – это оформить текущий открытый элемент по-другому по сравнению с другими, используя некоторые из техник, которые мы рассмотрели выше.

Вот простой пример:

details {
  background-color: #2196F3;
}

details[open] {
  background-color: #ce0e99;
}

Оформление заголовка внутри summary

Некоторые разработчики, обеспокоенные структурой своего HTML, предпочитают размещать элемент заголовка внутри элемента <summary>. Полезно это или нет покажет время, но стандартное отображение некрасиво, с заголовком, расположенным на строке ниже стрелки. Это можно исправить, установив для заголовка display: inline или display: inline-block:

summary h2 {
  display: inline;
}

Вы можете посмотреть демо-версию этого на CodePen.

Вывод

Как мы пытались показать выше, существует множество простых способов стилизации элемента <details>. Установка границ, отступов и фоновых цветов – это легко, и это значительно улучшает внешний вид. Некоторые методы стилизации стандартного маркера очень удобны, но учитывая, что Фруктовая компания Форреста () имеет много проблем со стилизацией маркера, возможно, лучше отказаться от этого варианта в пользу создания полностью настраиваемого элемента маркера. (И все же, стилизация маркера не ломает элемент <details> в Safari.)

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

Чтобы узнать больше об элементе <details>, ознакомьтесь с следующим:

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

Source:
https://www.sitepoint.com/style-html-details-element/