Использование псевдоэлемента ::marker

Влад Мержевич

Для изменения вида маркеров в списке издавна используется приём с псевдоэлементом ::before. Для начала скрываем исходные маркеры через свойство list-style.

li { list-style: none; }

Затем добавляем свои маркеры с помощью комбинации ::before и свойства content.

li::before {
 content: '►';
}

У таких искусственно созданных маркеров есть несколько преимуществ. К примеру, мы можем выбрать любой доступный нам символ и задать ему цвет, фон и другие стилевые параметры (пример 1).

Пример 1. Использование ::before

<!DOCTYPE html>
<html lang="ru">
 <head>
  <meta charset="utf-8">
  <title>::before</title>
  <style>
   li {
    list-style: none; /* Убираем исходные маркеры */
   }
   li::before {
    content: '►'; /* Символ маркера */
    color: red; /* Цвет маркера */
    margin-right: 0.5em; /* Расстояние от маркера до текста */
   }
  </style>
 </head>
 <body>
  <ul>
   <li>Леонардо</li>
   <li>Рафаэль</li>
   <li>Микеланджело</li>
   <li>Донателло</li>
  </ul>
 </body>
</html>

Результат данного примера показан на рис. 1.

Вид списка

Рис. 1. Вид списка

Более современный способ для управления видом маркеров основан на использовании псевдоэлемента ::marker. Работает он схожим образом c ::before, только не приходится добавлять list-style (пример 2).

Пример 2. Использование ::marker

<!DOCTYPE html>
<html lang="ru">
 <head>
  <meta charset="utf-8">
  <title>::marker</title>
  <style>
   li::marker {
    content: '►'; /* Символ маркера */
    color: red; /* Цвет маркеров */
   }
   li {
    padding-left: 0.5em; /* Расстояние от маркера до текста */
   }
  </style>
 </head>
 <body>
  <ul>
   <li>Леонардо</li>
   <li>Рафаэль</li>
   <li>Микеланджело</li>
   <li>Донателло</li>
  </ul>
 </body>
</html>

Для ::marker действует ограниченный набор свойств, в частности, не работают свойства background, padding, margin и ряд других. По этой причине в примере выше свойство padding-left перенесено в селектор li.

Таким образом, для простых ситуаций, когда надо лишь заменить символ маркеров и задать им цвет, псевдоэлемент ::marker подходит лучше всего. Когда к маркерам требуется добавить фон, мы переключаемся на ::before (пример 3).

Пример 3. Изменение стиля маркеров

<!DOCTYPE html>
<html lang="ru">
 <head>
  <meta charset="utf-8">
  <title>::before</title>
  <style>
   li { 
    list-style: none; /* Убираем маркеры */
    line-height: 1.5; /* Межстрочный интервал */
   }
   li::before {
    --h: 20px;
    content: '>'; /* Символ маркера */
    display: inline-block; /* Строчно-блочный элемент */
    background-color: #ff6600; /* Цвет фона */
    color: #fff; /* Цвет символов */
    margin-right: 0.5em; /* Расстояние от маркера до текста */
    border-radius: 50%; /* Превращаем в круг */
    width: var(--h); height: var(--h); /* Размеры */
    line-height: var(--h); /* Выравниваем по вертикали */
    text-align: center; /* Выравниваем по горизонтали */
    font-family: 'Courier New', Courier, monospace; /* Семейство шрифта */
    font-weight: bold; /* Жирное начертание */
   }
  </style>
 </head>
 <body>
  <ul>
   <li>Леонардо</li>
   <li>Рафаэль</li>
   <li>Микеланджело</li>
   <li>Донателло</li>
  </ul>
 </body>
</html>

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

Вид списка

Рис. 2. Вид списка

Также следует упомянуть, что ::marker не работает в старых браузерах. Так что если по какой-либо причине требуется поддержка Internet Explorer, то для управления стилем маркеров лучше использовать псевдоэлемент ::before.

Псевдоэлемент ::marker и <summary>

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

Спойлер

Убийца — дворецкий!

К элементу <summary> браузер по умолчанию добавляет символ треугольника, который легко заменить на другой через ::marker, к примеру, на символ плюса.

summary::marker {
 content: '+';
}

Чтобы при щелчке по <summary> менялся и наш символ, используем следующий селектор:

details[open] summary::marker {
content: '-';
}

В примере 4 показано добавление вопроса и ответа, которые исходно занимают буквально одну строку. При щелчке по заголовку становится виден ответ и меняется символ маркера в заголовке вопроса.

Пример 4. Использование <summary>

<!DOCTYPE html>
<html lang="ru">
 <head>
  <meta charset="utf-8">
  <title>::marker</title>
  <style>
   details {
    background-color: #edf6ff; /* Серый цвет фона */
   }
   summary {
    cursor: pointer; /* Меняем вид указателя */
    background-color: #1b4268; /* Цвет фона */
    color: #fff; /* Белый цвет текста */
    padding: 0.5em 1em; /* Расстояние от текста до края */
    user-select: none; /* Запрещаем выделение текста */
   }
   summary::marker {
    content: '+ '; /* Исходный символ */
    color: #ff6600; /* Цвет символа */
    font-family: 'Courier New', Courier, monospace; /* Семейство шрифта */
    font-weight: bold; /* Жирное начертание */
   }
   details[open] summary::marker {
    content: '‒ '; /* Символ после открытия */
   }
   details div {
    padding: 1em; /* Расстояние от текста до края */
   }
  </style>
 </head>
 <body>
  <details>
   <summary>Надо ли в HTML5 закрывать одиночные теги?</summary>
   <div>Нет, это не обязательно, поэтому вместо &lt;br/&gt; достаточно 
    написать &lt;br&gt;. Впрочем, допустима и старая форма записи, это не 
    считается ошибкой.</div>
  </details>
 </body>
</html>

Результат данного примера показан на рис. 3.

Вид summary с пользовательским символом

Рис. 3. Вид <summary> с пользовательским символом

Итого

  • Псевдоэлемент ::marker позволяет менять вид маркера у пунктов списка и заголовка <summary>.
  • Маркерам, созданным через ::marker, можно задать цвет и параметры шрифта.
  • Элементы <details> и <summary> многие недооценивают, хотя они позволяют делать интересные элементы интерфейса, вроде ниспадающего меню, аккордеона и др.
  • С помощью ::marker допустимо менять символ маркера в элементе <summary>.
CSS

Не выкладывайте свой код напрямую в комментариях, он отображается некорректно. Воспользуйтесь сервисом cssdeck.com или jsfiddle.net, сохраните код и в комментариях дайте на него ссылку. Так и результат сразу увидят.