Креативные способы стилизации списков с помощью CSS
Стандартные списки браузера редко соответствуют реальному дизайну. Независимо от того, создаёте ли вы навигационное меню, пошаговое руководство или список функций продукта, стилизация списков с помощью CSS предоставляет инструменты для придания им продуманного вида. В этой статье рассматриваются наиболее практичные, основанные на стандартах техники — от нативных свойств списков до CSS-счётчиков и пользовательских маркеров — без ущерба для доступности.
Ключевые выводы
- Выбирайте правильный семантический HTML-элемент списка (
<ul>,<ol>или<dl>) перед применением CSS, поскольку программы чтения с экрана опираются на эту структуру. - Используйте
::markerдля простых изменений цвета и шрифта маркера, и::beforeс flexbox, когда вам нужен полный контроль над макетом пользовательских маркеров. - CSS-счётчики позволяют создавать пользовательские форматы нумерации, включая многоуровневую иерархическую нумерацию с помощью
counters(). - Рассмотрите возможность добавления
role="list"при использованииlist-style: noneна значимых списках, особенно для сохранения семантики списков в Safari/VoiceOver.
Начните с правильного типа HTML-списка
Перед работой с CSS выберите правильный элемент:
<ul>— неупорядоченные списки, где последовательность не имеет значения (навигационные меню, списки функций)<ol>— упорядоченные списки, где последовательность важна (инструкции, рейтинги)<dl>— списки описаний, связывающие термины с определениями (глоссарии, метаданные)
Семантический HTML здесь важен. Программы чтения с экрана объявляют тип списка и количество элементов, что помогает пользователям понять контекст до того, как они прочитают хотя бы один элемент.
Свойства list-style-*: ваша отправная точка
Сокращённое свойство list-style объединяет три свойства:
ul {
list-style: square inside none;
/* list-style-type | list-style-position | list-style-image */
}
list-style-position стоит понимать чётко:
outside(по умолчанию) — маркер располагается в отступе, а текст остаётся аккуратно выровненнымinside— маркер располагается вместе с текстом, вызывая перенос на многострочных элементах
list-style-image существует, но имеет ограничения — вы не можете изменить размер или переместить изображение. Для пользовательских маркеров-изображений псевдоэлемент ::before с background-image даёт гораздо больше контроля.
Стилизация нативных маркеров с помощью CSS ::marker
Псевдоэлемент ::marker позволяет стилизовать встроенный маркер или номер напрямую — без дополнительной разметки:
li::marker {
color: deeppink;
font-size: 1.2em;
font-weight: bold;
}
Важное ограничение: ::marker поддерживает только определённый набор CSS-свойств: color, content, font-*, direction, unicode-bidi, white-space, text-combine-upright и свойства анимации/перехода. Вы не можете применять display, background, padding, margin или позиционирование. Рассматривайте его как инструмент стилизации на уровне текста, а не полноценный элемент.
Поддержка ::marker в современных браузерах хорошая, но проверьте вашу целевую матрицу браузеров. Обычно это самый чистый вариант для простых изменений цвета или шрифта нативных маркеров.
Пользовательские маркеры списков с помощью ::before
Когда ::marker недостаточно — для маркеров в виде иконок, сложного выравнивания или переходов — используйте вместо этого ::before:
ul {
list-style: none;
padding-left: 0;
}
ul li {
display: flex;
align-items: flex-start;
gap: 0.5rem;
}
ul li::before {
content: "✓";
color: green;
flex-shrink: 0;
}
Примечание о доступности: Установка
list-style: noneможет привести к тому, что Safari/VoiceOver перестанет распознавать элемент как список. Если семантика списка важна, добавьтеrole="list"к<ul>или<ol>.
Discover how at OpenReplay.com.
CSS-счётчики для стилизованных упорядоченных списков
CSS-счётчики дают полный контроль над форматированием нумерованных списков — полезно для стилизованных упорядоченных списков с пользовательскими префиксами, суффиксами или многоуровневой нумерацией:
ol {
list-style: none;
counter-reset: steps;
}
ol li {
counter-increment: steps;
}
ol li::before {
content: "Step " counter(steps) ". ";
font-weight: bold;
color: #333;
}
Вложенные счётчики
Для вложенных списков counters() (во множественном числе) выводит полную иерархию:
ol {
list-style: none;
counter-reset: steps;
}
ol li {
counter-increment: steps;
}
ol li::before {
content: counters(steps, ".") " ";
}
/* Выводит: 1, 1.1, 1.2, 2, 2.1 */
Свойство counter-increment также принимает размер шага: counter-increment: steps 2 увеличивает на два каждый раз.
Примечание о @counter-style
At-правило @counter-style позволяет определять полностью пользовательские системы счёта — пользовательские символы, алфавиты или циклические шаблоны:
@counter-style thumbs {
system: cyclic;
symbols: "👍" "👎";
suffix: " ";
}
ul {
list-style-type: thumbs;
}
Используйте с осторожностью. Поддержка @counter-style в браузерах остаётся неполной — в частности, Safari добавил поддержку только в версии 17. Всегда тестируйте в целевых браузерах и определяйте запасной вариант list-style-type на том же элементе для обеспечения корректной деградации.
Выбор правильного подхода
| Цель | Лучшая техника |
|---|---|
| Изменить цвет или шрифт маркера | ::marker |
| Пользовательская иконка или сложное выравнивание | ::before с flexbox |
| Пользовательское форматирование нумерации | CSS-счётчики с ::before |
| Пользовательская система счёта | @counter-style (с запасным вариантом) |
Заключение
Хорошая стилизация списков CSS начинается с семантического HTML и наслаивает визуальные улучшения поверх него. Используйте ::marker для лёгких изменений цвета и шрифта, ::before, когда вам нужен контроль над макетом, и CSS-счётчики, когда упорядоченным спискам нужна пользовательская нумерация. Избегайте удаления семантики списков без её восстановления через ARIA. У каждой техники есть чёткий вариант использования — выбирайте тот, который соответствует вашему дизайну, не усложняя его.
Часто задаваемые вопросы
Да, технически можете, но обычно вы выбираете одну стратегию маркеров. Если вы удаляете нативный маркер с помощью list-style: none, используйте ::before для пользовательского маркера. Если вы сохраняете нативный маркер, используйте ::marker для простых изменений цвета и шрифта.
Эвристика доступности Safari интерпретирует list-style: none как сигнал о том, что элемент используется для вёрстки, а не как семантический список. Это приводит к тому, что VoiceOver перестаёт объявлять его как список. Добавление role=list к элементу ul или ol явно восстанавливает семантику списка, чтобы вспомогательные технологии продолжали сообщать правильную структуру и количество элементов.
Да. CSS-счётчики не ограничены элементами списков. Вы можете применять counter-reset и counter-increment к любому элементу, например div, заголовкам или секциям, и отображать значение счётчика с помощью свойства content на псевдоэлементе. Это делает их полезными для нумерации глав, рисунков или любых повторяющихся шаблонов контента.
Установите для ul свойство display flex и удалите стили списка по умолчанию с помощью list-style none и padding-left 0. Затем стилизуйте каждый li или его якорь как встроенный flex-элемент с соответствующим интервалом, используя gap или margin. Не забудьте добавить role=list к ul, если хотите, чтобы программы чтения с экрана по-прежнему объявляли его как навигационный список в Safari.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..