иконка discount

Скидка 15% по промокоду

кибер понедельник до 01.12иконка discount
CYBER2025
логотип PurpleSchool
логотип PurpleSchool

Маркированный список HTML ul - основы синтаксиса стилизация и лучшие практики

Автор

Олег Марков

Введение

Маркированный список в HTML создается с помощью тега <ul> и используется для отображения неупорядоченных наборов элементов. Это могут быть пункты меню, списки преимуществ, чек-листы, группы ссылок и многое другое.

Смотрите, я покажу вам, как это выглядит в самом простом виде:

<ul>
  <li>Первый пункт</li>
  <li>Второй пункт</li>
  <li>Третий пункт</li>
</ul>

Маркированные списки кажутся простой темой, но в реальной верстке вокруг них возникает много вопросов: как правильно вкладывать списки, как менять вид маркеров, как использовать <ul> для меню, как не ломать семантику и доступность сайта. В этой статье вы разберетесь с основами и увидите практические примеры применения <ul> в реальных интерфейсах.

Синтаксис и базовая структура <ul>

Минимальная разметка

Маркированный список всегда состоит из контейнера <ul> и элементов списка <li>. Без <li> тег <ul> не имеет смысла.

<ul>
  <li>HTML</li>   <!-- Элемент списка -->
  <li>CSS</li>
  <li>JavaScript</li>
</ul>

Ключевые моменты:

  • <ul> — контейнер списка.
  • <li> — отдельный пункт списка.
  • Каждый пункт списка должен быть внутри <ul> (или <ol>).
  • Внутри <li> могут находиться другие элементы: текст, ссылки, изображения, вложенные списки и т.д.

Когда использовать <ul>

Используйте маркированный список, когда:

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

Не стоит использовать <ul> только ради отступов или декоративных точек, когда список по смыслу не нужен. В таких случаях лучше применить обычные блоки и CSS.

Семантика и роль <ul> в структуре документа

Семантический смысл <ul>

Тег <ul> сообщает браузеру и вспомогательным технологиям (например, скринридерам), что перед ними список однородных элементов. Это важно:

  • для доступности (озвучивание количества пунктов, навигация по спискам),
  • для SEO и анализа структуры контента,
  • для удобства поддержки кода.

По умолчанию:

  • <ul> имеет роль списка;
  • <li> — роль элемента списка.

Если вы используете <ul> для навигации, часто его оборачивают в <nav>:

<nav>
  <ul>
    <li><a href="/">Главная</a></li>
    <li><a href="/blog">Блог</a></li>
    <li><a href="/contacts">Контакты</a></li>
  </ul>
</nav>

Так вы явно показываете браузеру и поисковым системам, что этот список — часть навигации.

Разница между <ul>, <ol> и <dl>

Чтобы понимать, когда именно нужен <ul>, сравним его с другими типами списков:

  • <ul> — неупорядоченный список, маркеры без номера, порядок не важен.
  • <ol> — нумерованный список, важен порядок пунктов (инструкции, шаги алгоритма).
  • <dl> — список описаний, используется для пар «термин — определение».

Если вы описываете шаги установки программы — лучше <ol>. Если просто перечисляете функции программы — <ul>.

Вложенные списки и иерархические структуры

Очень часто требуется показать структуру с подуровнями: категории и подкатегории, пункты меню второго уровня и т.д. Здесь помогают вложенные <ul>.

Простой пример вложенного списка

Давайте разберемся на примере многоуровневого меню:

<ul>
  <li>Фрукты
    <ul> <!-- Вложенный список -->
      <li>Яблоки</li>
      <li>Бананы</li>
      <li>Апельсины</li>
    </ul>
  </li>
  <li>Овощи
    <ul>
      <li>Морковь</li>
      <li>Огурцы</li>
    </ul>
  </li>
  <li>Ягоды</li>
</ul>

Обратите внимание:

  • Вложенный <ul> располагается внутри <li> родительского списка.
  • Нельзя вкладывать <ul> напрямую в <ul> без <li> между ними.
  • Каждый уровень списка можно стилизовать по‑разному с помощью CSS.

Управление отступами и маркерами у вложенных списков

Чаще всего разработчикам нужно настроить внешний вид вложенных уровней: уменьшить отступы, сменить маркеры и т.д.

<ul class="categories">
  <li>Фрукты
    <ul>
      <li>Яблоки</li>
      <li>Бананы</li>
    </ul>
  </li>
  <li>Овощи
    <ul>
      <li>Морковь</li>
      <li>Огурцы</li>
    </ul>
  </li>
</ul>
/* Стили для корневого списка */
.categories {
  list-style-type: disc;   /* Классические кружки */
  padding-left: 20px;      /* Отступ слева */
}

/* Стили для вложенных списков */
.categories ul {
  list-style-type: circle; /* Маркер-колечко для второго уровня */
  padding-left: 20px;
}

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

Атрибут type и свойство list-style-type

Атрибут type у <ul>

Исторически <ul> поддерживает атрибут type, который задает тип маркера. Однако в HTML5 его использование считается устаревшим. Лучше управлять маркерами через CSS.

Пример устаревшего подхода (так лучше не делать в новом коде):

<ul type="square">
  <li>Пункт 1</li>
  <li>Пункт 2</li>
</ul>

Сейчас предпочтительнее использовать CSS.

Свойство CSS list-style-type

Современный способ задать стиль маркера — CSS:

<ul class="features">
  <li>Высокая производительность</li>
  <li>Удобный интерфейс</li>
  <li>Гибкая настройка</li>
</ul>
.features {
  list-style-type: disc;   /* Возможные значения disc circle square none и др. */
}

Наиболее часто используемые значения:

  • disc — закрашенный кружок (по умолчанию),
  • circle — пустой кружок,
  • square — квадрат,
  • none — без маркеров.

Если вы хотите полностью убрать маркеры (например, для горизонтального меню), используйте:

.menu {
  list-style-type: none;   /* Убираем стандартные маркеры */
  margin: 0;               /* Часто обнуляют еще и отступы */
  padding: 0;
}

Сброс стандартных стилей и работа с отступами

Почему важно обнулять отступы

Каждый браузер по‑своему задает отступы для <ul>. Это может ломать дизайн, особенно в шапках и футерах. Поэтому в макетах часто обнуляют margin и padding у списков, а затем задают нужные отступы явно.

<ul class="menu">
  <li><a href="/">Главная</a></li>
  <li><a href="/services">Услуги</a></li>
  <li><a href="/about">О компании</a></li>
</ul>
.menu {
  list-style: none;  /* Сокращенная запись - убираем маркеры */
  margin: 0;         /* Обнуляем внешний отступ */
  padding: 0;        /* Обнуляем внутренний отступ */
}

Смотрите, я покажу вам, как можно добавить свои отступы уже к элементам списка:

.menu li {
  display: inline-block;  /* Делаем пункты горизонтальными */
  margin-right: 16px;     /* Задаем промежуток между пунктами */
}

Свойство list-style как сокращенная запись

Вместо list-style-type, list-style-position и list-style-image можно использовать одно свойство:

ul.custom {
  list-style: square inside; 
  /* square - тип маркера
     inside - положение маркера внутри блока li */
}

Здесь мы задаем сразу несколько параметров в одной строке.

Кастомные маркеры: иконки, изображения, псевдоэлементы

Стандартных кружков и квадратиков часто недостаточно. В современных интерфейсах вы часто увидите свои иконки вместо стандартных маркеров.

Использование list-style-image

Самый прямой способ — указать изображение как маркер:

<ul class="with-icon">
  <li>Пункт с картинкой</li>
  <li>Еще один пункт</li>
</ul>
.with-icon {
  list-style-image: url("bullet.png"); 
  /* Используем изображение как маркер */
}

Но у этого подхода есть ограничения: сложно контролировать размер и отступы маркера.

Кастомные маркеры через псевдоэлемент ::before

Более гибкий и популярный подход — полностью убрать стандартный маркер и нарисовать свой через ::before.

<ul class="checklist">
  <li>Проверено</li>
  <li>Подтверждено</li>
  <li>Завершено</li>
</ul>
.checklist {
  list-style: none;      /* Убираем стандартные маркеры */
  margin: 0;
  padding: 0;
}

.checklist li {
  position: relative;    /* Чтобы псевдоэлемент позиционировать относительно li */
  padding-left: 24px;    /* Оставляем место под кастомный маркер */
}

.checklist li::before {
  content: "✔";          /* Сам маркер - символ галочки */
  position: absolute;
  left: 0;
  top: 0;
  color: green;
  /* Можно добавить line-height и другие параметры 
     чтобы выровнять значок по вертикали */
}

Теперь вы увидите, как это выглядит в коде: стандартные маркеры пропали, вместо них выводится зеленая галочка слева от текста.

Преимущества этого метода:

  • легко менять иконку (можно использовать символ, SVG, фон),
  • гибкий контроль отступов,
  • удобно подстраивать под дизайн.

Пример с иконкой через фон

Еще один вариант — использовать фоновое изображение:

.list-icon {
  list-style: none;
  margin: 0;
  padding: 0;
}

.list-icon li {
  background: url("icon.svg") no-repeat 0 4px; 
  /* Располагаем иконку слева и немного смещаем вниз */
  padding-left: 24px;    /* Делаем отступ под иконку */
}

В этом случае маркер — часть фона элемента списка.

Горизонтальные списки и меню на <ul>

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

Одно из самых частых применений <ul> — создание навигационного меню. Давайте посмотрим, что происходит в следующем примере.

<nav>
  <ul class="main-menu">
    <li><a href="/">Главная</a></li>
    <li><a href="/catalog">Каталог</a></li>
    <li><a href="/prices">Цены</a></li>
    <li><a href="/contacts">Контакты</a></li>
  </ul>
</nav>
.main-menu {
  list-style: none;  /* Убираем маркеры */
  margin: 0;
  padding: 0;
  display: flex;     /* Выстраиваем элементы в строку */
  gap: 20px;         /* Расстояние между пунктами меню */
}

.main-menu a {
  text-decoration: none; /* Убираем подчеркивание ссылок */
  color: #333;
  padding: 8px 12px;     /* Внутренние отступы для кликабельной зоны */
}

.main-menu a:hover {
  background-color: #f0f0f0; /* Подсветка при наведении */
}

Здесь <ul> выступает структурным контейнером, а CSS задает нужный вид.

Списки-кнопки и панели управления

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

<ul class="tabs">
  <li class="active"><button type="button">Профиль</button></li>
  <li><button type="button">Настройки</button></li>
  <li><button type="button">Безопасность</button></li>
</ul>
.tabs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  border-bottom: 1px solid #ccc;
}

.tabs li {
  margin-right: 12px;
}

.tabs button {
  border: none;
  background: transparent;
  padding: 8px 16px;
  cursor: pointer;
}

.tabs .active button {
  border-bottom: 2px solid #007bff; /* Активная вкладка */
  font-weight: 600;
}

Покажу вам, как это реализовано на практике: сам список задает структуру, а визуальное оформление и «кнопочность» целиком в руках CSS и JavaScript.

<ul> и доступность (a11y)

Как списки помогают скринридерам

Семантически корректные списки упрощают навигацию для пользователей со скринридерами. Когда вы используете <ul> и <li>:

  • скринридер может сообщить «список из N элементов»;
  • пользователь может быстро перемещаться между элементами списка;
  • структура контента становится предсказуемой.

Важно:

  • не вставлять посторонние элементы между <ul> и <li>, которые ломают структуру;
  • не использовать <br> вместо корректных <li>.

Текст ссылок в списках навигации

Если у вас <ul> в навигации, следите, чтобы текст ссылок был понятным вне контекста. Например, вместо:

<ul>
  <li><a href="/more">Подробнее</a></li>
  <li><a href="/click">Кликните сюда</a></li>
</ul>

лучше так:

<ul>
  <li><a href="/pricing">Тарифы</a></li>
  <li><a href="/documentation">Документация</a></li>
</ul>

Так пользователю (и скринридеру) будет понятно, куда ведет каждая ссылка.

Использование ARIA свойств

В большинстве случаев <ul> с <li> достаточно без дополнительных атрибутов ARIA. Но, если вы делаете сложные компоненты (например, выпадающее меню), могут понадобиться роли и атрибуты вроде role="menu", role="menuitem", aria-expanded и т.д.

Важно: добавлять ARIA стоит только тогда, когда вы понимаете, как это повлияет на поведение скринридеров. Для обычных списков с текстом или ссылками в большинстве случаев достаточно стандартной семантики <ul>.

Частые ошибки при работе с <ul>

Неправильное вложение элементов

Одна из типичных ошибок — вставка других элементов вместо <li> напрямую в <ul>.

<ul>
  <p>Текст внутри ul</p> <!-- Так делать не нужно -->
  <li>Правильный пункт</li>
</ul>

Корректный вариант:

<ul>
  <li>Текст внутри списка</li>  <!-- Текст должен быть внутри li -->
  <li>Еще один пункт</li>
</ul>

Если вам нужен заголовок над списком, разместите его до <ul>, а не внутри.

<h3>Основные преимущества</h3>
<ul>
  <li>Надежность</li>
  <li>Простота использования</li>
  <li>Гибкая настройка</li>
</ul>

Использование списка только ради отступов

Иногда новички используют <ul> как способ создать отступы или выровнять элементы:

<!-- Неправильный подход -->
<ul>
  <li>Блок 1</li>
  <li>Блок 2</li>
</ul>

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

Непоследовательная структура списков

Старайтесь, чтобы структура всех элементов списка была похожей. Плохой пример:

<ul>
  <li>
    <h4>Заголовок</h4>
    <p>Описание пункта</p>
  </li>
  <li>Просто текст без заголовка</li>
</ul>

Лучше выровнять структуру:

<ul>
  <li>
    <h4>Заголовок 1</h4>
    <p>Описание пункта</p>
  </li>
  <li>
    <h4>Заголовок 2</h4>
    <p>Еще одно описание</p>
  </li>
</ul>

Так код становится более предсказуемым и удобным для стилизации.

<ul> внутри других элементов: карточки, статьи, списки в списках

Список характеристик в карточке товара

Очень распространенный сценарий — использовать <ul> для характеристик товара.

<article class="product">
  <h2>Ноутбук X100</h2>
  <p>Мощный ноутбук для работы и игр.</p>

  <h3>Характеристики</h3>
  <ul class="product-specs">
    <li>Процессор Intel Core i7</li>
    <li>16 ГБ оперативной памяти</li>
    <li>SSD 512 ГБ</li>
  </ul>
</article>
.product-specs {
  list-style: disc inside; /* Маркеры внутри строки текста */
}

Здесь <ul> помогает структурировать данные и делает их легко воспринимаемыми.

Список внутри пункта списка

Иногда внутри одного <li> вам нужно сделать еще один список. Например, план занятий:

<ul>
  <li>Понедельник
    <ul>
      <li>Математика</li>
      <li>Физика</li>
    </ul>
  </li>
  <li>Вторник
    <ul>
      <li>История</li>
      <li>Литература</li>
    </ul>
  </li>
</ul>

Обратите внимание, как этот фрагмент кода решает задачу структурирования: каждый день — отдельный пункт, а внутри него — список уроков.

Управление позиционированием маркера

Свойство list-style-position

С помощью list-style-position можно управлять тем, где именно рисуется маркер — внутри или снаружи блока <li>.

ul.inside {
  list-style-position: inside;  /* Маркер будет внутри области li */
}

ul.outside {
  list-style-position: outside; /* Маркер снаружи области li (значение по умолчанию) */
}

Посмотрим на пример:

<ul class="inside">
  <li>Длинный текст пункта списка, который переносится на несколько строк и выравнивается по маркеру.</li>
</ul>

<ul class="outside">
  <li>Тот же длинный текст, но маркер расположен иначе, и выравнивание строк будет другим.</li>
</ul>
  • При inside переносы строк начинаются под маркером.
  • При outside переносы идут под началом текста, а маркер остается слева в полях.

Это особенно важно, если вы заботитесь о читаемости длинных пунктов.

Стилизованные списки в макетах (UI‑паттерны)

Список шагов или этапов

Даже если порядок не критичен, часто хочется визуально показать шаги или этапы процесса с помощью <ul>.

<ul class="steps">
  <li>
    <h4>Шаг 1</h4>
    <p>Заполните форму регистрации.</p>
  </li>
  <li>
    <h4>Шаг 2</h4>
    <p>Подтвердите email.</p>
  </li>
  <li>
    <h4>Шаг 3</h4>
    <p>Начните работу с личным кабинетом.</p>
  </li>
</ul>
.steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

.steps li {
  margin-bottom: 16px;
  padding-left: 12px;
  border-left: 2px solid #007bff; /* Вертикальная линия слева */
}

Здесь мы используем <ul> как структурный контейнер, но полностью переопределяем его внешний вид.

Колонки с помощью flex или grid

Списки можно «разложить» по колонкам:

<ul class="columns">
  <li>Пункт 1</li>
  <li>Пункт 2</li>
  <li>Пункт 3</li>
  <li>Пункт 4</li>
  <li>Пункт 5</li>
  <li>Пункт 6</li>
</ul>
.columns {
  list-style: disc inside;
  columns: 2;          /* Две колонки */
  -webkit-columns: 2;  /* Поддержка старых браузеров WebKit */
  -moz-columns: 2;     /* Поддержка старых Firefox */
}

Или через flex:

.columns {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;      /* Разрешаем перенос элементов на новую строку */
  gap: 8px 24px;        /* Вертикальные и горизонтальные отступы */
}

.columns li {
  width: 45%;           /* Укладываем примерно по два элемента в строке */
}

Так <ul> помогает создавать адаптивные сетки.

Заключение

Маркированный список <ul> — один из базовых, но очень гибких инструментов HTML. Он отвечает не только за визуальные маркеры, но и за семантику, структуру и доступность контента. Через <ul> вы можете:

  • строить списки характеристик и преимуществ,
  • организовывать навигацию и меню,
  • создавать многоуровневые структуры и подменю,
  • стилизовать пункты под чек‑листы, шаги, вкладки и другие паттерны интерфейса.

Ключевые практики, которые стоит учитывать:

  • хранить всю структуру списка внутри <li>;
  • использовать CSS (list-style-*, псевдоэлементы) для управления видом маркеров;
  • обнулять стандартные отступы там, где важен точный контроль дизайна;
  • помнить о семантике и доступности при использовании <ul> для навигации и сложных интерфейсов.

Если вы будете сочетать корректную семантику с аккуратной стилизацией, <ul> станет надежной основой для чистой и поддерживаемой верстки.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Можно ли оборачивать <li> в <a>, а не наоборот в меню на основе <ul>?

Да, HTML5 допускает оборачивание <li> в <a>, но более распространенный и предсказуемый вариант — <a> внутри <li>. Если вы хотите кликабельной сделать всю область пункта, лучше стилизовать ссылку как блочный элемент:

<ul class="menu">
  <li><a href="/catalog">Каталог</a></li>
</ul>
.menu a {
  display: block;          /* Делает ссылку блочной и растягивает на всю li */
  padding: 10px 16px;
}

Как сделать разные маркеры для разных пунктов внутри одного <ul>?

У стандартного list-style-type нет возможности задавать разные маркеры для отдельных <li>, поэтому используйте псевдоэлементы:

ul li {
  list-style: none;        /* Убираем стандартный маркер */
  position: relative;
  padding-left: 20px;
}

ul li::before {
  content: "•";            /* Общий маркер по умолчанию */
  position: absolute;
  left: 0;
}

/* Для конкретного пункта */
ul li.important::before {
  content: "❗";           /* Особый маркер */
  color: red;
}

Как перенести длинный текст в <li>, чтобы маркер оставался выровненным?

Используйте list-style-position: outside (по умолчанию) и при необходимости управляйте отступами:

ul {
  list-style-position: outside; /* Маркер вне блока li */
  padding-left: 20px;           /* Общий отступ списка */
}

li {
  padding-left: 4px;            /* Небольшой дополнительный отступ текста */
}

Если вы используете кастомный маркер через ::before, выравнивание задается через padding-left и position: absolute.

Как задать номера внутри <ul> вместо кружков, не используя <ol>?

Семантически это спорно (если есть номера, логичнее <ol>), но технически возможно:

.numbered {
  list-style: none;
  counter-reset: item;          /* Обнуляем счетчик */
}

.numbered li {
  counter-increment: item;      /* Увеличиваем счетчик на каждом li */
  position: relative;
  padding-left: 24px;
}

.numbered li::before {
  content: counter(item) ". ";  /* Выводим номер */
  position: absolute;
  left: 0;
}

Как сделать адаптивное меню на <ul>, которое превращается в столбик на мобильных устройствах?

Сначала строите меню в строку, затем меняете направление при узком экране:

.nav {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;          /* Горизонтальное меню по умолчанию */
  gap: 16px;
}

/* На мобильных экранах */
@media (max-width: 600px) {
  .nav {
    flex-direction: column; /* Переводим элементы в столбик */
    gap: 8px;
  }
}

Структура HTML при этом не меняется — адаптивность полностью обеспечивается за счет CSS.

Нумерованный список HTML olСтрелочка вправо

Постройте личный план изучения Html до уровня Middle — бесплатно!

Html — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Все гайды по Html

Тег section в HTML - семантическая разметка структуры страницыТег nav в HTML - полное руководство по семантической навигацииТег main в HTML - подробное руководство по использованиюТег header в HTML - полное практическое руководствоТег footer в HTML - назначение семантика и практические примерыТег figure в HTML - как правильно оформлять иллюстрации и подписиТег figcaption в HTML - подробное руководство с примерамиТег aside в HTML - назначение правильная семантика и примеры
Текстовая область HTML textarea - практическое руководствоВыпадающий список HTML select - полное руководство для разработчиковОпция списка HTML option - как работает и как правильно использоватьАтрибут method в HTML - как правильно отправлять данные формыЗаголовок группы HTML legend - как правильно использовать и оформлятьТег input в HTML - типы атрибуты валидация и примерыТег формы form в HTMLГруппа полей HTML fieldsetАтрибут action в HTML - как правильно задавать адрес отправки формы
Открыть базу знаний

Лучшие курсы по теме

изображение курса

HTML и CSS

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий