Селекторы CSS: виды, специфичность и примеры

Селекторы CSS: виды, специфичность и примеры Полезное

Селектор CSS — это шаблон, по которому браузер находит в HTML-документе элементы и применяет к ним стили. Слева от фигурных скобок в CSS-правиле стоит селектор, справа — объявления (свойство: значение). Один селектор может выбрать один элемент, группу однотипных элементов или элементы по их положению в разметке.

Ниже — основные виды селекторов CSS одной таблицей с примером на каждый, как считается специфичность (кто победит при конфликте стилей) и минимальный рабочий пример HTML и CSS с проговоренным результатом.

Как устроено CSS-правило

Простейшее правило состоит из селектора и блока объявлений:

p {
  color: #333;      /* цвет текста */
  line-height: 1.5; /* межстрочный интервал */
}

Здесь p — селектор по тегу: он выбирает все <p> на странице, а браузер красит их текст в темно-серый и задает межстрочный интервал. Дальше вся разница между видами селекторов — в том, по какому признаку они находят элементы.

Виды селекторов CSS

Основные виды удобно держать в одной таблице: синтаксис, пример и что именно выбирается.

Вид Синтаксис Пример Что выбирает
По тегу (элементный) тег p Все элементы <p>
По классу .имя .note Элементы с class="note"
По id #имя #lead Один элемент с id="lead"
По атрибуту [атрибут], [атрибут="значение"] a[target="_blank"] Ссылки с атрибутом target="_blank"
Универсальный * * Все элементы страницы
Псевдокласс :состояние a:hover Ссылку под курсором
Псевдоэлемент ::часть p::first-line Первую строку абзаца
Комбинатор см. ниже .card p Абзацы внутри .card

Класс и id похожи, но назначение разное. Класс — многоразовый: один и тот же класс можно повесить на сколько угодно элементов любого типа. Id по стандарту уникален: одно значение id должно встречаться на странице ровно один раз, поэтому id берут для единичных блоков (шапка, конкретная форма), а класс — для повторяющихся.

Селектор по атрибуту

Атрибутный селектор выбирает элементы по наличию атрибута или по его значению. Полезно, когда общего класса нет, а признак в разметке уже есть.

input[type="email"] { border: 1px solid #4a90d9; } /* только поля e-mail */
a[href^="https"]    { color: green; }               /* ссылки, начинающиеся с https */
a[href$=".pdf"]     { font-weight: bold; }           /* ссылки на pdf-файлы */

Здесь ^= означает «начинается с», $= — «заканчивается на», *= — «содержит подстроку».

Комбинаторы: отношения между элементами

Комбинаторы выбирают элементы не сами по себе, а по их положению относительно других. Их четыре, и путать их — частый источник ошибок.

Комбинатор Знак Пример Что выбирает
Потомок пробел .card p Любые <p> внутри .card, на любой глубине
Дочерний > ul > li Только <li> — прямые дети <ul>
Смежный соседний + h2 + p Первый <p> сразу после <h2>
Общий соседний ~ h2 ~ p Все <p> после <h2> на том же уровне

Разница между потомком (пробел) и дочерним (>) видна на вложенности: .card p возьмет и абзац внутри вложенного <div>, а .card > p — только абзацы, лежащие прямо в .card.

Псевдокласс и псевдоэлемент: не одно и то же

Эти два понятия легко перепутать, поэтому развожу их явно.

Псевдокласс пишется с одним двоеточием и выбирает уже существующий в разметке элемент в определенном состоянии или позиции: :hover (курсор наведен), :focus (элемент в фокусе), :active (нажат), :first-child (первый ребенок), :nth-child(2n) (четные), :checked (отмеченный чекбокс).

Псевдоэлемент пишется с двумя двоеточиями и стилизует часть элемента или создает виртуальное содержимое, которого нет в HTML: ::before и ::after (добавляют контент до и после содержимого), ::first-line (первая строка), ::first-letter (первая буква), ::placeholder (текст-подсказка в поле).

Короткая цепочка, чтобы запомнить: a:hover — это ссылка целиком в состоянии наведения; p::first-line — это часть абзаца (первая строка), самого такого элемента в DOM нет. Одно двоеточие — состояние, два — часть.

button:hover      { background: #f0f0f0; } /* псевдокласс: состояние кнопки */
li:first-child    { font-weight: bold; }   /* псевдокласс: позиция в списке */
blockquote::before{ content: "\201C"; }    /* псевдоэлемент: добавляет кавычку */

Отдельно стоит псевдокласс :has() — им можно выбрать родителя по содержимому (например, .card:has(img) — карточка, внутри которой есть картинка). Долгое время его не хватало; на 2026 год :has() поддерживается во всех актуальных версиях Chrome, Edge, Safari и Firefox.

Специфичность: кто победит при конфликте

Когда к одному элементу подходят несколько правил с одинаковым свойством, применяется то, у которого выше специфичность. Считается она как тройка чисел (a, b, c):

  • a — количество id-селекторов;
  • b — классы, атрибутные селекторы и псевдоклассы;
  • c — теги и псевдоэлементы.

Универсальный селектор * и комбинаторы (>, +, ~, пробел) на специфичность не влияют. Сравнение идет по разрядам слева направо: сначала a, при равенстве — b, потом c.

Селектор a b c Специфичность
p 0 0 1 0,0,1
.note 0 1 0 0,1,0
.card p 0 1 1 0,1,1
a[target="_blank"]:hover 0 2 1 0,2,1
#lead 1 0 0 1,0,0

Правило #lead перебьет любое количество классов, потому что старший разряд (id) у него больше. Вне этой схемы стоят два случая: инлайновый стиль в атрибуте style="" весит больше любого селектора, а !important перекрывает и его. Оба — крайние меры: чем больше !important в проекте, тем труднее предсказать итоговый стиль, поэтому приоритетом лучше управлять аккуратными селекторами.

Минимальный рабочий пример

Ниже цельный HTML-файл: его можно сохранить как index.html, открыть в браузере и увидеть результат. Стили собраны в <style>, чтобы пример работал без отдельного CSS-файла.

<!DOCTYPE html>
<html lang="ru">
<head>
  <meta charset="utf-8">
  <style>
    p                  { color: #333; }              /* тег: все абзацы */
    .note              { background: #fff8c4; }       /* класс: заметка */
    #lead              { font-size: 20px; }           /* id: первый абзац */
    a[target="_blank"] { color: crimson; }            /* атрибут: внешние ссылки */
    a:hover            { text-decoration: underline; }/* псевдокласс: наведение */
    p::first-line      { font-weight: bold; }         /* псевдоэлемент: первая строка */
    .card > p          { margin: 0; }                 /* комбинатор: прямой ребенок */
  </style>
</head>
<body>
  <p id="lead">Первый абзац страницы.</p>
  <p class="note">Заметка на желтом фоне.</p>
  <div class="card">
    <p>Текст карточки и <a href="/" target="_blank">внешняя ссылка</a>.</p>
  </div>
</body>
</html>

Что видно на экране: первый абзац крупнее остальных (20px, сработал #lead), у всех абзацев первая строка жирная (p::first-line), второй абзац лежит на бледно-желтой подложке (.note), ссылка внутри карточки красная (a[target="_blank"]) и подчеркивается при наведении курсора (a:hover). Текст в карточке без внешних отступов, потому что абзац — прямой ребенок .card.

Частая ошибка новичка — перепутать точку и решетку. Задав в CSS #note вместо .note, вы обратитесь к элементу с id="note", а не к классу; фон не появится, потому что такого id в разметке нет. Симптом («стиль не применился, ошибок в консоли нет») лечится сверкой: точка — класс, решетка — id.

Выводы

  • Селектор CSS — это шаблон выбора элементов HTML; слева от {} он определяет, к чему применить стили справа.
  • Базовые виды: по тегу, по классу (многоразовый), по id (уникальный), по атрибуту и универсальный *.
  • Псевдокласс (одно двоеточие) выбирает элемент в состоянии или позиции; псевдоэлемент (два двоеточия) стилизует часть элемента или добавляет виртуальный контент.
  • Комбинаторы (пробел, >, +, ~) выбирают элементы по их отношению к соседям и родителям.
  • При конфликте стилей выигрывает большая специфичность (id > класс/атрибут/псевдокласс > тег); style="" и !important стоят выше и их стоит избегать.
  • На 2026 год доступен :has() — выбор родителя по содержимому во всех актуальных браузерах.

Где применяется / связь с практикой

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

Селекторы — основа любой верстки: без них не задать ни адаптивную сетку, ни состояния кнопок, ни темы оформления. На практике их пишут в связке с медиазапросами, флексбоксом и grid, а в больших проектах — через препроцессоры, где селекторы можно вкладывать и переиспользовать. Разобраться в этом на реальных макетах помогает курс HTML/CSS в Otus: там верстка идет от разметки к рабочему интерфейсу с проверкой преподавателем. Посмотреть формат и темы можно на бесплатных вебинарах до старта.

Смежные темы: Верстка CSS и использование grid, Sass: описание и применение, Работа с размерами изображения в HTML.

FAQ

Чем селектор отличается от свойства? Селектор стоит слева от {} и отвечает на вопрос «к каким элементам применить», а свойство (например, color) внутри скобок — «что именно изменить». В одном правиле один селектор и сколько угодно свойств.

Можно ли выбрать элемент по тексту внутри него? Напрямую по содержимому текста — нет, CSS-селекторы так не умеют. Но через :has() можно выбрать родителя по наличию внутри определенного элемента (li:has(a)), а точечный выбор по тексту решается классом в разметке или средствами JavaScript.

Что быстрее для браузера — id или класс? Разница в скорости на реальных страницах пренебрежимо мала, выбирать стоит по смыслу: id — для единичного элемента, класс — для повторяющегося стиля.

OTUS Журнал
Скидка 5% 14-20 сентября на курсы (popup)