Использование списков

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

Хлебные крошки

Хлебные крошки помогают ориентироваться на сайте и показывают положение текущей страницы относительно других разделов сайта. Это позволяет легко переходить на уровень выше и понять, в каком разделе вы находитесь сейчас. Так, для технического сайта навигация может быть следующей (рис. 1).

Вид хлебных крошек

Рис. 1. Вид хлебных крошек

Последний текст указывает на текущую страницу и ссылкой не является. Все пункты отделяются друг от друга каким-нибудь символом, обычно это стрелка (→), слэш (/), знак больше (>) и тому подобное.

Поскольку оформление возложено на стили, то код HTML весьма лаконичен. Создаём список и присваиваем ему класс breadcrumbs чтобы стиль на другие списки не распространялся.

<ul class="breadcrumbs">
 <li><a href="#">Главная</a></li>
 <li><a href="#">Передачи</a></li>
 <li><a href="#">Редукторы</a></li>
 <li>Редуктор червячный</li>
</ul>

Заметьте, что никаких разделителей здесь нет, они выводятся с помощью стилевого свойства content (пример 1).

Пример 1. Создание хлебных крошек

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Хлебные крошки</title>
  <style>
   .breadcrumbs {
    margin: 0; padding: 0; /* Убираем отступы */
   }
   .breadcrumbs li {
    display: inline-block; /* Выстраиваем по горизонтали */
   }
   .breadcrumbs li::before {
    content: '/'; /* Разделитель */
    margin-left: 5px; /* Отступ слева */
    margin-right: 5px; /* Отступ справа */
    color: #7f7f7f; /* Цвет разделителя */
   }
   .breadcrumbs li:first-child::before {
    content: ''; /* Убираем разделитель для первого пункта */
   }
  </style>
 </head>
 <body>
  <ul class="breadcrumbs">
   <li><a href="# ">Главная</a></li>
   <li><a href="#">Передачи</a></li>
   <li><a href="#">Редукторы</a></li>
   <li>Редуктор червячный</li>
  </ul>
 </body>
</html>

Для начала мы обнуляем все поля и отступы у списка и выстраиваем пункты горизонтально через свойство display со значением inline-block. Оно же убирает маркеры, поэтому специально это делать уже не надо. Псевдоэлемент ::before требуется для добавления разделителя между пунктами и управления его видом. Текст добавляется ко всем пунктам, включая первый, что нам, конечно же, не надо. Поэтому убираем его с помощью псевдокласса :first-child, который применяет стиль к первому элементу <li>.

Нумерация страниц

Большое количество материалов, например статьи сайта, часто разбивают на отдельные страницы по 10-15 статей на страницу, что приводит к сокращению загрузки сайта. Переход между отдельными страницами делается через их нумерацию, где каждый номер служит ссылкой на соответствующую страницу. Возможен вывод всех страниц, определённого их количества или только ссылок на следующую и предыдущую страницу. Какой вариант выбрать зависит от дизайна сайта и ваших предпочтений. Один из возможных способов нумерации показан на рис. 2.

Нумерация страниц

Рис. 2. Нумерация страниц

Чтобы сделать такую нумерацию мы опять используем простой список, теперь уже с классом pager, каждый пункт этого списка будет ссылкой на страницу. Чтобы выделить текущую страницу добавим класс active (пример 2).

Пример 2. Нумерация страниц

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Нумерация страниц</title>
  <style>
   .pager {
    margin: 0; padding: 0; /* Убираем все отступы */
    border-bottom: 2px solid #006cc9; /* Линия между номерами */
    display: inline-block; /* Ограничиваем ширину списка */
   }
   .pager li { 
    display: inline-block;  /* Выстраиваем по горизонтали */
    width: 30px; height: 30px; /* Размеры круга */
    border-radius: 50%; /* Делаем круг */
    background: #006cc9; /* Цвет фона */
    line-height: 30px; /* Выравниваем по середине высоты */
    position: relative; top: 27px; /* Смещаем вниз */
    margin-left: 10px; /* Расстояние между номерами */
   }
   .pager li:first-child {
    margin-left: 0;  /* Для первого числа убираем отступ */
   }
   .pager a {
    color: #fff; /* Цвет текста */
    text-decoration: none; /* Убираем подчёркивание */
    text-align: center; /* Выравниваем по середине */
    display: block; /* Ссылка занимает весь блок */
   }
   .pager .active {
    width: 50px; height: 50px; /* Размер текущего номера */
    line-height: 50px; /* Выравниваем по середине высоты */
    background: #fff; /* Цвет фона */
    border: 3px solid #006cc9; /* Рамка вокруг */
    font-size: 20px; /* Размер текста */
   }
   .pager .active a {
    color: #000; /* Цвет текущего номера */
    font-weight: bold; /* Жирное начертание */
   }
  </style>
 </head>
 <body>
  <ul class="pager">
   <li><a href="#">1</a></li>
   <li class="active"><a href="#">2</a></li>
   <li><a href="#">3</a></li>
   <li><a href="#">4</a></li>
   <li><a href="#">5</a></li>
   <li><a href="#">6</a></li>
  </ul>
 </body>
</html>

Линия между пунктами делается через свойство border-bottom для элемента <ul>. Поскольку <ul> — это блочный элемент и занимает всю доступную ему ширину, её надо ограничить либо задав width, либо, как показано в примере, установив display со значением inline-block. Линия оказывается под числами, так что пункты меню смещаем вниз на половину их высоты.

Размеры всех кругов установлены точно, через width и height, в связи с чем возникает две проблемы. Первая — ссылка гораздо меньше самого круга и пользователь будет промахиваться; вторая — ссылка располагается в верхней части круга, но никак не по его середине. Первая проблема решается просто — надо сделать ссылки блочными, тогда они будут занимать всю ширину и высоту круга. При этом ссылки остаются квадратными и немного выходят за пределы цветного фона. Но это не видно и становится заметно только при наведении курсора в один из углов ссылки. Выравнивание текста делается с помощью свойства line-height, значение которого совпадает с высотой элемента. Этот способ позволяет выровнять текст по середине высоты элемента и он нам ещё пригодится в дальнейшем.

Создание меню

Меню на сайте это один из способов навигации по нему. Самый простой вариант — набор горизонтальных ссылок, напоминающих по своему виду хлебные крошки. Отличие в том, что между ссылок нет указателей (рис. 3).

Горизонтальное меню

Рис. 3. Горизонтальное меню

Для создания такого меню применяем принципы используемые нами в предыдущих примерах, но для разнообразия внесём декоративные изменения. Меню имеет небольшой градиент, под ним находится слабая тень, а пункты меню разделяются вертикальной линией. Сама линия нестандартная и состоит из серой и белой полосок, так что отдельно будем добавлять свою линию к элементам <li> и <a> (пример 3). Они плотно прилегают друг к другу и создают эффект единой полоски.

Пример 3. Горизонтальное меню

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Меню</title>
  <style>
   .menu {
    background: linear-gradient(to bottom, #fff, #f1f2f2); /* Градиент */
    border: 1px solid #999; /* Параметры рамки */
    padding: 0 5px; /* Поля */
    font: 14px Arial, sans-serif; /* Параметры шрифта */
    box-shadow: 0 2px 5px rgba(0,0,0,0.2); /* Тень под меню */
   }
   .menu li {
    display: inline-block; /* Выстраиваем по горизонтали */
    border-right: 1px solid #fff; /* Белая линия справа */
   }
   .menu a {
    text-decoration: none; /* Убираем подчёркивание */
    color: #4c4c4c; /* Цвет ссылок */
    display: block; /* Блочные ссылки */
    padding: 10px 15px; /* Поля */
    border-right: 1px solid #d8d8d8; /* Серая линия справа */
   }
   .menu a:hover { color: #006cc9; }
  </style>
 </head>
 <body>
  <ul class="menu">
   <li><a href="#">Первые блюда</a></li>
   <li><a href="#">Вторые блюда</a></li> 
   <li><a href="#">Компот</a></li>
  </ul>
 </body>
</html>

Градиент в данном примере добавляется с помощью функции linear-gradient, а тень — с помощью свойства box-shadow.

Ниспадающее меню

Более сложный вид меню называется ниспадающим. При наведении указателя на пункты появляется подменю, до этого невидимое (рис. 4); как только указатель уходит с текста, то меню прячется вновь.

Вид ниспадающего меню

Рис. 4. Вид ниспадающего меню

Такой вид меню достаточно сложен для вёрстки, поэтому разберём его подробнее. Вначале делаем вложенный список, — пункты первого списка служат текстом основного меню, второй список внутри элемента <li> будет служить подменю. Если подменю не требуется, то оставляем только один элемент <li>, а <ul> в него не добавляем. Структура каждого пункта имеет следующий вид.

<li><a href="#">Русская кухня</a>
 <ul> 
  <li><a href="#">Бефстроганов</a></li> 
  <li><a href="#">Гусь с яблоками</a></li> 
  <li><a href="#">Крупеник новгородский</a></li> 
  <li><a href="#">Раки по-русски</a></li> 
 </ul> 
</li>

Теперь нам надо различить стиль для разных элементов <li>, чтобы установить стиль для пунктов первого и второго уровня меню. Если просто указать селектор li, то стиль будет применяться ко всем пунктам вообще. Так что используем селектор .menu > li, он применяет стиль только к элементам <li> первого уровня. В итоге стиль для нашего горизонтального меню немного меняется.

/* Обнуляем отступы и убираем маркеры у списков */
.menu, .menu ul { 
 list-style: none;
 margin: 0; padding: 0;
}
.menu {
 background: linear-gradient(to bottom, #fff, #f1f2f2); /* Градиент */
 border: 1px solid #999; /* Параметры рамки */
 padding: 0 5px; /* Поля */
 font: 14px Arial, sans-serif; /* Параметры шрифта */
 box-shadow: 0 2px 5px rgba(0,0,0,0.2); /* Тень под меню */
}
.menu > li {
 display: inline-block; /* Выстраиваем по горизонтали */
 border-right: 1px solid #fff; /* Белая линия справа */
 position: relative; /* Относительное позиционирование */
}
.menu a {
 text-decoration: none; /* Убираем подчёркивание */
 color: #4c4c4c; /* Цвет ссылок */
 display: block; /* Блочные ссылки */
}
.menu > li > a {
 padding: 10px 15px; /* Поля */
 border-right: 1px solid #d8d8d8; /* Серая линия справа */
 position: relative; /* Относительное позиционирование */
 z-index: 3; /* Выводим поверх остальных элементов */
}
.menu ul {
 display: none; /* Прячем подменю */
}

Подменю мы прячем через свойство display, в итоге меню должно выглядеть как показано на рис. 3. Также добавлено обнуление значений у списков, это пригодится нам при добавлении подпунктов, плюс задействовано относительное позиционирование, без него z-index работать не будет. А оно нам требуется для правильного наложения одних элементов поверх других.

Временно можно включить показ подменю и настроить их вид.

.menu ul {
 position: absolute; /* Абсолютное позиционирование */
 display: none; /* Прячем подменю */
 width: 200px; /* Ширина подменю */
 background: #fff; /* Цвет фона */
 box-shadow: 0 0 10px #666; /* Параметры тени */
}
.menu ul a {
 padding: 5px 10px; /* Поля */
}
.menu ul a:hover {
 background: #008df2; /* Цвет фона */
 color: #fff; /* Цвет текста */
}

Остаётся сделать вывод подменю при наведении курсора мыши на пункты меню. Для этого используем псевдокласс :hover, добавляя его к li.

.menu li:hover ul {
  display: block;
}

Такой селектор говорит, что стиль следует применить к элементу <ul>, в данном случае отобразить его, только когда указатель мыши наведён на элемент <li> внутри контейнера с классом menu.

После этого наше меню будет работать и выводить подменю где оно имеется. Остаются последние декоративные штрихи, связанные с тенями и их правильным наложением. Чтобы корректно отобразить тень под пунктами меню первого уровня создадим пустой псевдоэлемент через ::before, установим для него тень, и подложим его под ссылку (вот z-index для <a> и пригодился).

.menu > li:hover::before {
 content: ''; /* Создаём пустой псевдоэлемент */
 top: 0; left: 0; right: 0; bottom: 0; /* Размер совпадает с пунктом меню */
 box-shadow: 0 5px 10px #666; /* Параметры тени */
 position: absolute; /* Абсолютное позиционирование */
}

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

Пример 4. Ниспадающее меню

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>Меню</title>
  <style>
   .menu, .menu ul { 
    /* Обнуляем отступы и убираем маркеры у списков */
    list-style: none; margin: 0; padding: 0;
   }
   .menu {
    background: linear-gradient(to bottom, #fff, #f1f2f2); /* Градиент */
    border: 1px solid #999; /* Параметры рамки */
    padding: 0 5px; /* Поля */
    font: 14px Arial, sans-serif; /* Параметры шрифта */
    box-shadow: 0 2px 5px rgba(0,0,0,0.2); /* Тень под меню */
   }
   .menu > li {
    display: inline-block; /* Выстраиваем по горизонтали */
    border-right: 1px solid #fff; /* Белая линия справа */
    position: relative; /* Относительное позиционирование */
   }
   .menu a {
    text-decoration: none; /* Убираем подчёркивание */
    color: #4c4c4c; /* Цвет ссылок */
    display: block; /* Блочные ссылки */
   }
   .menu > li > a {
    padding: 10px 15px; /* Поля */
    border-right: 1px solid #d8d8d8; /* Серая линия справа */
    position: relative; z-index: 3; /* Выводим поверх остальных элементов */
   }
   .menu ul {
    position: absolute; /* Абсолютное позиционирование */
    display: none; /* Прячем подменю */
    width: 200px; /* Ширина подменю */
    background: #fff; /* Цвет фона */
    box-shadow: 0 0 10px #666; /* Параметры тени */
   }
   .menu ul a {
    padding: 5px 10px; /* Поля */
   }
   .menu ul a:hover {
    background: #008df2; /* Цвет фона */
    color: #fff; /* Цвет текста */
   }
   .menu li:hover ul {
    display: block; /* Показываем подменю */
   }
   .menu > li:hover::before {
    content: ''; /* Создаём пустой псевдоэлемент */
    top: 0; left: 0; right: 0; bottom: 0; /* Размер совпадает с пунктом меню */
    box-shadow: 0 5px 10px #666; /* Параметры тени */
    position: absolute; /* Абсолютное позиционирование */
   }
   .menu > li:hover > a {
    background: #fff; /* Цвет фона */
   }
  </style>
 </head>
 <body>
  <ul class="menu">
   <li><a href="#">Русская кухня</a>
    <ul> 
     <li><a href="#">Бефстроганов</a></li> 
     <li><a href="#">Гусь с яблоками</a></li> 
     <li><a href="#">Крупеник новгородский</a></li> 
     <li><a href="#">Раки по-русски</a></li> 
    </ul> 
   </li> 
   <li><a href="#">Украинская кухня</a> 
    <ul> 
     <li><a href="#">Вареники</a></li> 
     <li><a href="#">Жаркое по-харьковски</a></li> 
     <li><a href="#">Капустняк черниговский</a></li> 
     <li><a href="#">Потапцы с помидорами</a></li> 
    </ul> 
   </li>
   <li><a href="#">Кавказская кухня</a></li> 
  </ul>
 </body>
</html>

Автор и редакторы

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