Стили списков: полная кастомизация

0
131
views
verstka logo

Хочешь знать больше про веб?

Подпишись на наш телеграм-канал TechRocks WEB-разработка?

×

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

В этом руководстве мы рассмотрим:

  • 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».

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here