Основы CSS: селекторы и декларации

CSS управляет внешним видом элементов на странице. Любое правило состоит из двух частей: селектора (что выбирать) и декларации (какие свойства применять). Начните с понимания простых селекторов, специфичности и комбинаторов — это решает большинство задач стилизации.
Важно: эта статья сосредоточена на селекторах; примеры деклараций приведены для иллюстрации и сохранения контекста.
Что такое правило CSS
Файл CSS — это набор правил. Каждое правило отвечает на два вопроса: что нужно стилизовать и как это делать. Первая часть — селекторы. Вторая — блок деклараций с парами свойство: значение.
Определение термина: селектор — это выражение, которое выбирает узлы DOM для применения стиля.
CSS = селекторы + декларации
Пример простого правила:
p.intro { margin-bottom: 0.5rem; color: #333; }Здесь p.intro — селектор, а { margin-bottom: 0.5rem; color: #333; } — декларация.
Исторически селекторы развивались по уровням. Современные браузеры поддерживают основные возможности уровней 1–3. Для практической работы достаточно знать эти три уровня и несколько приёмов работы со специфичностью.
Уровень 1 — базовые селекторы
Уровень 1 включает самые часто используемые типы селекторов. Они покрывают большинство практических задач.
| Паттерн | Соответствует |
|---|---|
E | всем элементам E |
.c | всем элементам с class=”c” |
#myid | элементу с id=”myid” |
E F | элементу F внутри элемента E |
| Псевдоклассы | |
E:link | ссылке, которая ещё не посещена |
E:visited | посещённой ссылке |
E:active | ссылке в активном состоянии |
| Псевдоэлементы | |
E::first-line | первая форматированная строка элемента E |
E::first-letter | первая форматированная буква элемента E |
Селектор по типу
Селектор по типу выбирает все элементы заданного тега:
p { margin-bottom: 0; }
b { font-family: sans-serif; }Подходит для глобальных настроек элементов.
Селектор по классу
Классы добавляют семантику к элементам и позволяют сгруппировать несколько разных тегов под одним именем класса:
.intro { font-weight: bold; }Такой селектор совпадёт с любым элементом, у которого class="intro", независимо от тега. Чтобы ограничить область, комбинируйте с типом:
p.intro { font-weight: bold; }Селектор по id
Атрибут id должен быть уникален в документе. Селектор по id выглядит так:
#contents { color: #333; }Используйте id для очень специфичных целей, например для якорей или уникальных областей интерфейса.
Комбинатор-потомок
Комбинатор-потомок — это пробел между селекторами. Он выбирает элементы внутри других элементов, на любом уровне вложенности:
table b { font-weight: normal; }Псевдоклассы и псевдоэлементы
Псевдо-селекторы позволяют выбрать элементы или части документов, которые неявно доступны браузеру:
p::first-line { text-transform: uppercase; }Они полезны для типографических нюансов и состояний элементов.
Списки селекторов
Чтобы применить одно и то же правило к нескольким селекторам, объедините их через запятую:
th, td { padding: 1em; }Это уменьшает дублирование и делает код чище.
Специфичность
Если к одному элементу применяются несколько правил, выигрывает правило с большей специфичностью. Уровни приоритетов — сверху вниз:
- Селекторы по id (
#id) — самый высокий приоритет. - Селекторы по классу, атрибуту и псевдоклассы (
.class,[attr],:hover). - Селекторы по типу (
div,p).
Правило со !important может переопределять обычную специфичность, но злоупотреблять им не рекомендуется.
Пример:
p.intro { color: black; }
p { color: gray; }В этом случае p.intro победит, потому что содержит селектор по классу, который специфичнее, чем простой селектор по тегу.
Практическая подсказка: вычисляйте специфичность как вектор уровней: (вхождений id, вхождений классов/атрибутов/псевдоклассов, вхождений типов). Сравнивайте поэлементно.
Уровень 2 — расширенные селекторы и комбинаторы
Уровень 2 добавил атрибутные селекторы и новые комбинаторы.
| Паттерн | Соответствует |
|---|---|
* | любому элементу |
E > F | элементу F, являющемуся непосредственным потомком E |
E + F | элементу F, который напрямую следует за E |
| Атрибутные селекторы | |
E[foo] | элементу E с атрибутом “foo” |
E[foo="bar"] | элементу E, с атрибутом “foo” равным точно “bar” |
E[foo~="bar"] | элементу E, у которого атрибут “foo” содержит слово “bar” в списке значений |
| E[foo|="en"] | элементу E, у которого атрибут “foo” имеет список, разделённый дефисом, начинающийся с “en” | | Псевдоклассы | | | E:first-child | элементу E, который является первым ребёнком родителя | | E:lang(fr) | элементу типа E с языком “fr” | | Псевдоэлементы | | | E::before | генерируемому содержимому перед содержимым E | | E::after | генерируемому содержимому после содержимого E |
Универсальный селектор
* совпадает со всеми элементами. Полезен при сбросе стилей:
* { box-sizing: border-box; margin: 0; }Но его часто не стоит использовать глобально без нужды — это может повлиять на производительность при очень больших DOM.
Атрибутные селекторы
Позволяют таргетировать элементы по атрибутам:
a[title] { text-decoration: underline dotted; }
a[href^="https:"] { color: green; }
img[src$=".svg"] { max-width: 100%; }Это удобно, когда семантика передаётся через атрибуты — например, data-атрибуты или состояние контролов.
Комбинатор: непосредственный ребёнок
E > F выбирает только прямых потомков. Используйте, когда важна иерархия уровня:
ul > li { list-style: disc; }Комбинатор: соседний элемент
E + F выбирает элемент F, который сразу следует за E (пропуская текстовые узлы). Часто применяется для настройки отступов между заголовком и первым параграфом:
h1 + p { margin-top: 0.5rem; }Наследование
Некоторые свойства наследуются от предков к потомкам. Типичные наследуемые свойства — color, font-family, line-height. С другой стороны, margin, padding, border не наследуются.
Правило: задавайте общие свойства на уровне :root или body, а конкретные — на элементах.
:root { --brand-color: #0a66c2; font-family: Inter, system-ui, sans-serif; }
body { color: #222; }Если свойство должно быть явно унаследовано, можно использовать inherit:
code { color: inherit; background: #f5f5f5; }Уровень 3 — расширенные возможности и псевдоклассы
Уровень 3 содержит мощные селекторы для структурного выбора и более гибких условий.
| Паттерн | Соответствует |
|---|---|
E ~ F | элементу F, который следует за E, но не обязательно сразу |
| Атрибутные селекторы | |
E[foo^="bar"] | атрибут начинается с “bar” |
E[foo$="bar"] | атрибут заканчивается на “bar” |
E[foo*="bar"] | атрибут содержит подстроку “bar” |
| Псевдоклассы | |
E:root | корневой элемент документа |
E:nth-child(n) | n-ый ребёнок родителя |
E:nth-last-child(n) | n-ый ребёнок родителя, считая с конца |
E:nth-of-type(n) | n-ый сосед данного типа |
E:last-child | последний ребёнок |
E:first-of-type | первый среди своих однородных соседей |
E:only-child | единственный ребёнок |
E:empty | элемент без дочерних узлов, включая текстовые |
E:target | элемент, на который ссылается URI (якорь) |
E:enabled | элемент интерфейса, доступный для ввода |
E:disabled | недоступный элемент интерфейса |
E:checked | чекбоксы/радио в состоянии checked |
E:not(s) | элемент E, не совпадающий с простым селектором s |
Селекторы по шаблону
Селекторы ^=, $= и *= позволяют гибко работать с содержимым атрибутов. Это удобно при работе с динамическими значениями URL, названиями классов и data-атрибутами.
Псевдоклассы для структурного выбора
:nth-child() и похожие селекторы помогают выбирать элементы по их позиции. Это полезно для чередования стилей, нумерации, или выбора последнего элемента в списке без добавления классов.
li:nth-child(odd) { background: #fafafa; }
tr:nth-child(2n) { background: #fff; }Общий комбинатор соседства
E ~ F выбирает все элементы F, которые идут после E в рамках одного родителя. Отличается от E + F тем, что сопоставляет не только непосредственного соседа.
h2 ~ p { color: #444; }Практическая методика выбора селектора
Короткая методика, чтобы быстро принять решение:
- Используйте семантическую разметку и назначайте классы для визуально важных блоков.
- Выбирайте самый общий селектор, который покрывает задачу, не делая его чрезмерно глобальным.
- Избегайте повышать специфичность без причины — это затрудняет поддержку.
- При необходимости используйте
data-атрибуты для состояния или привязки к JavaScript.
Мини-шпаргалка:
- Для глобальных правил — селекторы по типу или
:root. - Для компонентов — классы.
- Для уникальных зон —
idили специфичный класс. - Для описания состояния — псевдоклассы (
:hover,:focus) илиdata-атрибуты.
Частые ошибки и когда селекторы не подходят
- Использование очень специфичных селекторов, которые затем тяжело переопределить.
- Привязка стилей к структуре DOM (например
ul > li > a > span) вместо использования классов — ломаются при изменении разметки. - Злоупотребление
!important. - Сложные цепочки селекторов ради единственного визуального эффекта — уменьшайте связность.
Чек-лист ролей перед релизом
Разделённый по ролям список задач, которые помогут избежать регрессий:
Дизайнер:
- Проверить макеты в нескольких разрешениях.
- Убедиться, что типографика и цветовая палитра совпадают с токенами.
Верстальщик/фронтенд-разработчик:
- Использовать семантические теги.
- Отклонить избыточную специфичность.
- Добавить полезные переменные в
:root.
QA:
- Проверить основные сценарии в поддерживаемых браузерах.
- Протестировать изменения стилей при изменении DOM (адаптивность).
Разработчик JS:
- Использовать
data-атрибуты для привязки скриптов, чтобы не ломать классы.
- Использовать
Шпаргалка селекторов (Cheat sheet)
E— все элементы E.class— элементы с классом#id— уникальный элементE F— потомкиE > F— прямые детиE + F— следующий соседE ~ F— все последующие соседиE[attr],E[attr="val"],E[attr^="val"],E[attr$="val"],E[attr*="val"]— по атрибутам:nth-child(),:first-child,:last-child,:not()— для структуры и исключений::before,::after,::first-line— для контента и типографики
Decision flowchart (Mermaid)
flowchart TD
A[Нужно стилизовать элемент?] --> B{Можно изменить HTML?}
B -- Да --> C[Добавить семантический класс и использовать .class]
B -- Нет --> D{Элемент уникален?}
D -- Да --> E[Использовать #id или более специфичный селектор]
D -- Нет --> F{Стили для состояния?}
F -- Да --> G[Использовать псевдоклассы :hover/:focus или data-атрибуты]
F -- Нет --> H[Использовать комбинаторы или атрибутные селекторы]
C --> I[Проверить специфичность и совместимость]
E --> I
G --> I
H --> I
I --> Z[Тест и ревью]Критерии приёмки
- Страница в основных разрешениях выглядит как в дизайне.
- Нет лишних
!importantи трудно переопределяемых правил. - Критические элементы доступны с клавиатуры, стили не мешают доступности.
- Производительность не ухудшилась: стили не применяются чрезмерно глобально.
Тестовые случаи для регрессионного тестирования
- Проверить стили заголовков при наличии и отсутствии дополнительных элементов между ними и параграфами.
- Проверить поведение
:hoverи:focusна интерактивных элементах в клавиатурной навигации. - Проверить внешние и внутренние отступы при использовании
box-sizing. - Проверить переходы и псевдоэлементы (
::before,::after) на мобильных устройствах.
Примеры шаблонов и сниппетов
Глобальная установка коробочной модели и переменных:
:root {
--gap: 1rem;
--max-width: 1200px;
--text-color: #222;
}
*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; color: var(--text-color); font-family: Inter, system-ui, sans-serif; }Частая комбинация для карточек:
.card { border-radius: 8px; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.08); padding: 1rem; }
.card h3 { margin-top: 0; }Совместимость и миграция
- Проверяйте поддержку новых селекторов в целевых браузерах. Для старых систем можно полагаться на полифилы или упрощённые правила.
- При рефакторинге CSS последовательно заменяйте инлайн-стили и хардкод-классы на компоненты с переменными и атомарными классами.
Безопасность и доступность
- Не используйте селекторы, полагающиеся на порядок DOM, для определения видимости компонентов критичных для безопасности.
- Псевдоклассы
:focusи:focus-visibleважны для доступности — сохраняйте видимую индикацию фокуса.
Короткий глоссарий
- Селектор — выражение для выбора элементов DOM.
- Декларация — блок
{}со свойствами и значениями. - Комбинатор — оператор, задающий отношение между элементами.
- Специфичность — правило приоритета конфликтующих стилей.
Заключение
Селекторы — ключ к гибкой и масштабируемой системе стилей. Понимание базовых селекторов, комбинаторов и специфичности даёт вам контроль над тем, какие элементы будут стилизованы. Используйте классы для компонентов, атрибутные селекторы для тонкой настройки и псевдоклассы для состояний; избегайте чрезмерной специфичности и !important.
Image Credit: Pankaj Patel/ Unsplash
Похожие материалы
Подготовка к техническому собеседованию разработчика
Запуск мастера устранения неполадок в Windows
Как создать мем: полное руководство
Как устранить BSOD 0x0000003B в Windows
Clone Stamp в Photoshop — подробное руководство