Селекторы

Селектор — это паттерн, по которому браузер находит HTML-элементы для применения CSS-стилей.

Зачем нужно

Селекторы — основа CSS. Без них невозможно указать, к каким элементам применять стили. Понимание селекторов позволяет точно нацеливаться на нужные элементы, избегая лишних классов и громоздкого HTML.

Где используется

  • Стилизация любых HTML-элементов
  • JavaScript: document.querySelector и document.querySelectorAll используют CSS-селекторы
  • Тестирование: Playwright, Cypress используют CSS-селекторы для поиска элементов
  • Инструменты разработчика (DevTools) — фильтрация элементов

Предпосылки

Базовые селекторы

Селектор тега (типа)

Выбирает все элементы данного типа.

/* Все параграфы */
p {
  line-height: 1.6;
  color: #333;
}

/* Все заголовки h2 */
h2 {
  font-size: 24px;
  margin-top: 32px;
}

Селектор класса (.)

Выбирает элементы с указанным классом. Самый популярный селектор.

.card {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.btn-primary {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 10px 20px;
  cursor: pointer;
}
<div class="card">
  <button class="btn-primary">Нажми</button>
</div>

Селектор ID (#)

Выбирает единственный элемент с данным id. Используется редко из-за высокой специфичности.

#header {
  background-color: #1a1a2e;
  color: white;
  padding: 20px 0;
}

#main-nav {
  display: flex;
  gap: 20px;
}

Универсальный селектор (*)

Выбирает все элементы.

/* Сброс отступов (не рекомендуется в проде) */
* {
  margin: 0;
  padding: 0;
}

/* Лучше — box-sizing для всех */
*,
*::before,
*::after {
  box-sizing: border-box;
}

Комбинаторы

Потомок (пробел)

Выбирает элемент, который вложен на любом уровне.

/* Все ссылки внутри nav (любая вложенность) */
nav a {
  text-decoration: none;
  color: inherit;
}

/* Параграфы внутри article */
article p {
  font-size: 18px;
}

Дочерний элемент (>)

Выбирает прямого потомка (только первый уровень).

/* Только прямые li внутри ul */
ul > li {
  list-style: disc;
  margin-bottom: 8px;
}

/* Прямые div внутри .container */
.container > div {
  padding: 10px;
}

Соседний элемент (+)

Выбирает элемент, идущий сразу после указанного (на том же уровне).

/* Параграф сразу после заголовка */
h2 + p {
  font-size: 18px;
  color: #666;
}

/* Отступ между соседними карточками */
.card + .card {
  margin-top: 16px;
}

Все последующие (~)

Выбирает все элементы после указанного (на том же уровне).

/* Все параграфы после h2 (на том же уровне) */
h2 ~ p {
  margin-left: 20px;
}

Селекторы атрибутов

/* Элемент с атрибутом */
[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Точное значение */
[type="email"] {
  border-color: blue;
}

/* Значение начинается с */
[href^="https"] {
  color: green;
}

/* Значение заканчивается на */
[href$=".pdf"] {
  color: red;
}
[href$=".pdf"]::after {
  content: " (PDF)";
}

/* Значение содержит */
[class*="btn"] {
  cursor: pointer;
}

/* Значение — слово в списке через пробел */
[class~="active"] {
  font-weight: bold;
}

/* Значение равно или начинается с "en-" */
[lang|="en"] {
  quotes: "\201C" "\201D";
}

Группировка селекторов (список)

Одинаковые стили для нескольких селекторов:

h1,
h2,
h3 {
  font-family: 'Georgia', serif;
  color: #222;
}

.btn-primary,
.btn-secondary,
.btn-outline {
  display: inline-block;
  padding: 10px 20px;
  border-radius: 4px;
  font-size: 16px;
  cursor: pointer;
}

Составные селекторы

Объединение нескольких условий без пробела — элемент должен соответствовать всем одновременно:

/* Элемент p с классом .intro */
p.intro {
  font-size: 20px;
  font-style: italic;
}

/* input с типом text и классом .large */
input[type="text"].large {
  font-size: 20px;
  padding: 15px;
}

/* div с двумя классами одновременно */
div.card.featured {
  border: 2px solid gold;
}

Псевдоклассы (обзор)

/* Наведение мыши */
a:hover {
  color: red;
}

/* Первый / последний ребёнок */
li:first-child {
  font-weight: bold;
}
li:last-child {
  border-bottom: none;
}

/* Каждый чётный */
tr:nth-child(even) {
  background-color: #f5f5f5;
}

/* Каждый 3-й начиная со 2-го */
li:nth-child(3n+2) {
  color: blue;
}

/* Пустой элемент */
div:empty {
  display: none;
}

/* Отрицание */
p:not(.special) {
  color: gray;
}

/* Фокус */
input:focus {
  outline: 2px solid #007bff;
  border-color: #007bff;
}

/* Проверка формы */
input:valid {
  border-color: green;
}
input:invalid {
  border-color: red;
}

Псевдоэлементы (обзор)

/* Контент до и после элемента */
.quote::before {
  content: "\201C"; /* открывающая кавычка */
  font-size: 2em;
  color: #ccc;
}

.quote::after {
  content: "\201D"; /* закрывающая кавычка */
}

/* Первая буква */
p::first-letter {
  font-size: 2em;
  float: left;
  margin-right: 4px;
  color: #c0392b;
}

/* Первая строка */
p::first-line {
  font-weight: bold;
}

/* Выделение текста */
::selection {
  background-color: #007bff;
  color: white;
}

/* Плейсхолдер */
input::placeholder {
  color: #999;
  font-style: italic;
}

Таблица специфичности селекторов

Селектор Пример Специфичность
* * 0-0-0
Тег p 0-0-1
Класс .card 0-1-0
Атрибут [type="text"] 0-1-0
Псевдокласс :hover 0-1-0
ID #header 1-0-0
inline style style="" — (перебивает всё)
!important — (перебивает inline)

Частые ошибки

  1. Слишком длинные цепочки селекторов — хрупкие и медленные:
    /* ПЛОХО */
    body > div.wrapper > main > section > article > p.text() {}
    
    /* ХОРОШО */
    .article-text {}
    
  2. Злоупотребление ID-селекторами — сложно переопределить:
    /* ПЛОХО — специфичность 1-0-0 */
    #sidebar .link { color: blue; }
    
    /* ХОРОШО — специфичность 0-2-0 */
    .sidebar .link { color: blue; }
    
  3. Забытая запятая в группировке — создаёт комбинатор потомка:
    /* Это h1 И h2 */
    h1, h2 { color: red; }
    
    /* А это h2 ВНУТРИ h1 */
    h1 h2 { color: red; }
    
  4. Путаница .class1.class2 и .class1 .class2 — первое: оба класса на одном элементе; второе: потомок

Практика

  • Написать селектор для каждого типа: тег, класс, ID, атрибут
  • Использовать комбинаторы: пробел, >, +, ~
  • Создать стили для чётных строк таблицы через :nth-child
  • Стилизовать ссылки через :hover, :visited, :active
  • Создать ::before с иконкой для внешних ссылок ([href^="http"])
  • Проверить специфичность своих селекторов в DevTools

Связанные темы

Ресурсы