Спойлер

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

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

Вид содержимого <details>

Рис. 1. Вид содержимого <details>

В примере 1 показано использование элемента <details> для создания спойлеров.

Пример 1. Спойлер, сделанный через <details>

Код примера скопирован в буфер
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Спойлер</title>
 </head> 
 <body>
  <details>
   <summary>Внимание, спойлер!</summary>
   <p>Убийца — дворецкий!</p>
  </details>
 </body> 
</html>

В браузерах IE и Edge элементы <summary> и <details> не работают, текст спойлера в них отображается сразу же. Поэтому для универсальности рассмотрим альтернативную реализацию через псевдокласс :checked.

Вместо <details> будем использовать элемент <div> с классом spoiler, заголовок сделаем через <label>, а содержимое спойлера опять же через <div> (пример 2). Для реализации функции открытия-закрытия добавим <input type="checkbox"> и свяжем его с <label> через атрибуты id и for.

Пример 2. Структура спойлера

<div class="spoiler">
  <input type="checkbox" id="spoiler1">
  <label for="spoiler1">Внимание, спойлер!</label>
  <div>Убийца — дворецкий!</div>
</div>

Сперва прячем <input> и текст спойлера через свойство display со значением none.

.spoiler input, .spoiler div  { 
  display: none; 
}

А затем показываем его через псевдокласс :checked с помощью всё того же свойства display.

.spoiler :checked ~ div {
  display: block;
}

Этого уже достаточно, чтобы при щелчке по <label> ниже расположенный <div> отображался и скрывался. Всё остальное это косметические детали для оформления. Добавим перед заголовком стрелку, как это реализовано в <summary>, через псевдоэлемент ::before и свойство content, значением которого будет символ стрелки, направленной вправо или вниз.

/* Закрытый спойлер */
.spoiler label::before {
  content: '►'; 
  margin-right: 5px;
}
/* Открытый спойлер */
.spoiler :checked + label::before {
  content: '▼';
}

Окончательный код продемонстрирован в примере 3.

Пример 3. Спойлер, сделанный через :checked

Код примера скопирован в буфер
<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Спойлер</title>
  <style>
   .spoiler input, .spoiler div  { 
    display: none; /* Скрываем содержимое */
   }
   .spoiler label::before {
    content: '►'; /* Текст перед заголовком */
    margin-right: 5px; /* Расстояние до текста */
   }
   /* Открытый спойлер */
   .spoiler :checked + label::before { content: '▼'; }
   .spoiler :checked ~ div {
    display: block; /* Показываем спойлер */
    padding: 10px; /* Поля вокруг текста */
   }
  </style>
 </head> 
 <body>
  <div class="spoiler">
   <input type="checkbox" id="spoiler1">
   <label for="spoiler1">Внимание, спойлер!</label>
   <div>Убийца — дворецкий!</div>
  </div>
 </body> 
</html>

Результат данного примера в браузере Internet Explorer показан на рис. 2.

Вид спойлера

Рис. 2. Вид спойлера

Теперь наш спойлер работает во всех основных браузерах. К недостаткам метода следует отнести громоздкий код HTML — при добавлении нескольких спойлеров каждому <input> внутри spoiler надо давать уникальный id и это же значение затем писать в атрибуте for для <label>.

Автор: Влад Мержевич
Последнее изменение: 20.02.2024