Давайте разберем, как кастомизированные стили списков могут помочь расположить элементы в разных столбцах, сделать маркеры в виде эмодзи и настроить красивые цифры в нумерации.
В этом руководстве мы рассмотрим:
- data-атрибуты в качестве содержимого псевдоэлементов
- CSS-счетчики для стилизации упорядоченных списков
- CSS-переменные для стилизации пунктов списка
- отзывчивые списки в несколько столбцов.
А также мы разберем, как использовать CSS grid для легкой стилизации списков.
Наши списки в HTML
Для начала давайте создадим нашу HTML-разметку. У нас будет один упорядоченный список (ol
) и один неупорядоченный (ul
). Более длинные пункты списков я включила для демонстрации выравнивания, отступов и высоты строки.
<ul role="list"> <li>Unordered list item</li> <li>Cake ice cream sweet sesame snaps dragée cupcake wafer cookie</li> <li>Unordered list item</li> </ul> <ol role="list"> <li>Ordered list item</li> <li>Cake ice cream sweet sesame snaps dragée cupcake wafer cookie</li> <li>Ordered list item</li> </ol>
Обратите внимание на использование role="list"
. Поначалу кажется, что это лишнее. Но мы при помощи CSS удалим стили, присущие спискам. А несмотря на то, что CSS не часто затрагивает семантическое значение элементов, list-style: none
может удалить семантику списка для некоторых скринридеров.
Самый простой способ это исправить — определить атрибут role
для восстановления этой семантики. Узнать больше на эту тему можно, прочитав статью Скотта О’Хара «»Fixing» Lists».
Базовый CSS наших списков
Для начала мы добавим сброс стилей списка в дополнение к их определению как сетки с промежутками.
ol, ul { margin: 0; padding: 0; list-style: none; display: grid; grid-gap: 1rem; }
Свойство grid-gap
добавляет пространство между li
, заменяя более старый метод li + li { margin-top: ... }
.
Далее мы подготовим элементы списка:
li { display: grid; grid-template-columns: 0 1fr; grid-gap: 1.75em; align-items: start; font-size: 1.5rem; line-height: 1.25; }
Мы также сразу учтем использование сетки в стилях элементов списка. И проапгрейдим старый «хак». Раньше, чтобы оставить пространство для абсолютно позиционированного псевдоэлемента, использовался padding-left
. Вместо этого мы поставим комбинацию нулевой ширины первого столбца и grid-gap
. Скоро вы увидите, как это работает.
Затем мы прописываем align-items: start
вместо дефолтного stretch
и стили, касающиеся шрифтов.
UL: data-атрибуты для маркеров списка в виде эмодзи
Это, вероятно, не совсем масштабируемое решение. Но чисто для интереса мы добавим кастомный data-атрибут, определяющий эмодзи для маркера списка для каждого элемента.
Для начала давайте обновим HTML для ul
:
<ul role="list"> <li data-icon="🦄">Unordered list item</li> <li data-icon="🌈">Cake ice cream sweet sesame snaps dragée cupcake wafer cookie</li> <li data-icon="😎">Unordered list item</li> </ul>
Чтобы применить эмодзи в качестве маркеров списка мы применим довольно магический прием. В нем data-атрибуты могут использоваться как значения свойства content
для псевдоэлементов:
ul li::before { content: attr(data-icon); /* Make slightly larger than the li font-size but smaller than the li grid-gap */ font-size: 1.25em; }
Вот результат с показом элемента ::before
для иллюстрации того, как работает сетка:
Эмодзи позволяется занимать ширину, чтобы быть видимым, но он надежно сидит в grid-gap
.
Можете поэкспериментировать и установить grid column
как auto
для первого li
. В результате между столбцом с эмодзи и столбцом с текстом полностью применится grid-gap
.
OL: CSS-счетчики и CSS-переменные
CSS-счетчики — вполне жизнеспособное решение со времен IE8. Но мы добавим немного «украшательств»: используем CSS-переменные, чтобы менять цвет фона для каждого номера.
Сперва добавим стили для CSS-счетчика. Сам счетчик назовем orderedlist
:
ol { counter-reset: orderedlist; } ol li::before { counter-increment: orderedlist; content: counter(orderedlist); }
Таким образом достигается следующий вид:
На самом деле полученный результат не слишком отличается от дефолтных стилей упорядоченного списка.
Далее мы применим некоторую базовую стилизацию к числам счетчика:
/* Add to li::before rule */ font-family: "Indie Flower"; font-size: 1.25em; line-height: 0.75; width: 1.5rem; padding-top: 0.25rem; text-align: center; color: #fff; background-color: purple; border-radius: 0.25em;
Во-первых, мы применили один из шрифтов Google и увеличили font-size
. Свойство line-height
установлено в половину от line-height
элемента li
(по крайней мере с этим шрифтом это сработало, но это может быть и магическим числом). Это выравнивает число относительно текстового содержимого li
.
Далее нам нужно явно указать ширину. Если этого не сделать, фон не проявится, хотя текст будет.
Добавляем padding
, чтобы зафиксировать выравнивание текста относительно фона.
Теперь наш список выглядит так:
Он определенно кажется более кастомным. Но мы еще немного усилим этот эффект, заменив цвет в background-color
на CSS-переменную:
ol { --li-bg: purple; } ol li::before { background-color: var(--li-bg); }
Вид от этого не изменится. По крайней мере, пока мы не добавим встроенные стили для второго и третьего пунктов списка для обновления значения переменной:
<ol role="list"> <li>Ordered list item</li> <li style="--li-bg: darkcyan">Cake ice cream sweet sesame snaps dragée cupcake wafer cookie</li> <li style="--li-bg: navy">Ordered list item</li> </ol>
И вот наши итоговые ul
и ol
:
See the Pen Totally Custom List Styles by Stephanie Eckles (@5t3ph) on CodePen.
Списки в несколько столбцов
В нашем примере есть только три коротких пункта списка. Но не забывайте, что мы применили grid
к основе ol
и ul
.
Когда-то, в прошлой жизни, я делала интересные вещи с modulus в PHP, что позволяло разбивать списки и применять дополнительные классы к полученным спискам, равномерно разделенным на несколько столбцов.
При помощи CSS grid это можно сделать в трех строках. При этом результат будет отзывчивым, столбцы — равными, а еще будет учитываться длина строки содержимого.
ol, ul { display: grid; /* adjust the `min` value to your context */ grid-template-columns: repeat(auto-fill, minmax(22ch, 1fr)); grid-gap: 1rem; }
Применим это к нашему примеру. Только не забудьте сперва удалить max-width
для элемента li
.
Вы можете включить это представление в Codepen, установив для переменной $multicolumn
значение true
.
Если в содержимом li у вас не просто текст
К сожалению, если у вас в пункте списка не просто голый текст, сетка сломается. Причем «не просто текст» — это даже добавление ссылки.
Но есть простое решение: поместите контент li
в span
. Сетке плевать на то, что собой представляют элементы. Она просто ожидает только два элемента, первый из которых — псевдоэлемент.
CSS Marker
Несколько месяцев спустя после выхода этой статьи поддержка ::marker
в современных браузерах существенно улучшилась.
Псевдоселектор ::marker
позволяет напрямую менять и стилизовать нумерацию и маркеры в ol
и ul
списках.
При помощи ::marker
мы можем полностью заменить наше решение для маркеров в ul
. Но для ol
-решения это будет даунгрейд, поскольку для ::marker
есть только несколько свойств:
- animation-*
- color
- content
- direction
- font-*
- transition-*
- unicode-bidi
- white-space
Стили неупорядоченного списка с ::marker
Поскольку content
— допустимое свойство для ::marker
, мы можем сохранить наше решение data-icon
, чтобы не отказываться от эмодзи в качестве маркеров.
Нам лишь нужно заменить ::before
на ::marker
:
ul li::marker { content: attr(data-icon); font-size: 1.25em; }
Затем удалим теперь уже ненужные grid-свойства из li
и добавим padding
, чтобы заменить удаленный grid-gap
:
li { /* replace the grid properties with: */ padding-left: .5em; }
Наконец, мы ранее удалили margin, но теперь нам нужно вернуть его обратно. Это обеспечит пространство для ::marker
, чтобы он не обрезался из-за переполнения:
/* update in existing rule */ ol, ul { margin: 0 0 0 2em; /* ...existing styles */ }
Визуально результат такой же, как при предыдущем решении. Посмотреть можно в демо.
Стили упорядоченного списка с ::marker
Что касается упорядоченного списка, мы можем переключиться и воспользоваться преимуществами встроенного счетчика.
Нам придется убрать наши background-color
и border-radius
, так что мы будем использовать нашу CSS-переменную для свойства color
. А имя переменной для ясности изменим на --marker-color
.
Итак, наши урезанные стили выглядят теперь следующим образом:
ol { --marker-color: purple; } li::marker { content: counter(list-item); font-family: "Indie Flower"; font-size: 1.5em; color: var(--marker-color); }
Не забудьте обновить имя CSS-переменной и в HTML!
Обратите внимание. Изменение свойства display
для li
удалит псевдоэлемент ::marker
. Так что, если вам нужен другой тип display
для содержимого списков, нужно обернуть его в дополнительный элемент.
Демо для ::marker
В этом Codepen вы видите обновленные стили с использованием ::marker
.
See the Pen Totally Custom List Styles with CSS ::marker by Stephanie Eckles (@5t3ph) on CodePen.
Выбирая интересные стили списков, не забывайте проверять поддержку в браузерах (с учетом предпочтений вашей аудитории).
Если хотите узнать больше о ::marker
, советую почитать замечательную статью «Custom bullets with CSS ::marker».
Перевод статьи «Totally Custom List Styles».
[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]