burger-menu
меню

CSS-селекторы и их мощь: Учимся управлять стилями как профи

Тут мы разберём один из самых мощных инструментов в веб-стилизации — CSS-селекторы. Именно они помогают находить нужные элементы на странице и придавать им стиль. Если ты знаешь, как ими управлять, то сможешь легко кастомизировать сайт без лишнего кода.

Простые селекторы — наша база

Это фундамент, на котором строятся все стили. Давай рассмотрим три главных типа:

Селектор элемента

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

p {
  color: blue;
  font-size: 16px;
}

Этот код окрасит все <p> на странице в синий цвет и сделает их размером 16px.

Пример в HTML

<p>Привет, мир!</p>
<p>Это обычный абзац.</p>

Оба <p> будут синими.

Когда использовать?

Селектор класса

Применяется только к тем элементам, у которых есть определённый class.

Как работает?

.highlight {
  background-color: yellow;
  font-weight: bold;
}

Теперь любой элемент с class="highlight" получит жёлтый фон и жирный текст.

Пример в HTML

<p class="highlight">Я выделенный абзац!</p>
<p>А я обычный.</p>

Только первый <p> будет выделен, потому что у него есть class="highlight".

Так что выбрать?
Вопрос Селектор элемента Селектор класса
Что выбирает? Все <p>, <h1>, <button> и т. д. Только элементы с указанным классом (например .highlight)
Применяется ко всем таким тегам? Да Нет
Можно переиспользовать? Да, но только на один тег Да, на любые элементы
Специфичность Низкая (1) Средняя (10)
Гибкость? Ограниченная Гибкая

Селектор ID

Стилизует уникальный элемент (но лучше использовать классы, а не ID):

#header {
  background-color: black;
  color: white;
}

Этот стиль применяется только к элементу с id="header".

Пример в HTML:

<p class="header">Я выделенный абзац!</p>
<p id="header">А я обычный.</p>

Второй <p> получит чёрный фон и белый текст, потому что у него есть id="header".

Почему лучше использовать классы, а не ID для стилизации?

ID слишком специфичен

CSS работает по принципу специфичности:

Если ты стилизуешь элемент через #id, а потом захочешь его переопределить в другом месте, то обычный класс не сможет его "перебить" без !important.

Пример проблемы:

#button {
  color: red;
}

.button {
  color: blue;
}

Даже если мы добавим class="button" на тот же элемент, он всё равно останется красным, потому что #id более специфичен.

ID нельзя переиспользовать

ID должен быть уникальным на странице, а классы можно применять к нескольким элементам.

Плохой пример:

<button id="primary-btn">Купить</button>
<button id="primary-btn">Отмена</button> <!-- Ошибка! -->

Так делать нельзя! А если бы мы использовали класс .primary-btn, то всё ок.

Проблемы с поддержкой и масштабируемостью

Если твой проект разрастается, а стили написаны через #id, их сложно переопределять и поддерживать.
Приходится переписывать много кода, если что-то меняется.

Как правильно?

.button {
  background-color: blue;
  color: white;
}
<button class="button">Купить</button>
<button class="button">Отмена</button>

Теперь легко изменить стиль для всех необходимых кнопок разом!

Итог

Используй ID только для JavaScript (например, для getElementById) и якорных ссылок.
А для CSS всегда лучше использовать классы, потому что они гибкие, переиспользуемые и не создают проблем со специфичностью.

Комбинированные селекторы — когда одной цели мало

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

Группировка элементов

Стили можно задать сразу нескольким тегам:

h1, h2, h3 {
  font-family: Arial, sans-serif;
}

Теперь все заголовки будут с одинаковым шрифтом.

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

Применяется только к прямым потомкам.

div > p {
  color: red;
}

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

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

Работает на всех уровнях вложенности:

div p {
  font-style: italic;
}

Все <p>, находящиеся внутри <div>, станут курсивными.

Соседние элементы

Сосед справа (+) — применяет стиль только к следующему элементу на том же уровне:

h1 + p {
  color: green;
}

Только первый <p> сразу после <h1> станет зелёным.

Все соседи справа (~) — затрагивает все подходящие элементы после указанного:

h1 ~ p {
  color: orange;
}

Теперь все <p>, которые идут после <h1>, станут оранжевыми.

Псевдоклассы — динамические и структурные

Динамические псевдоклассы

Они помогают менять стиль в зависимости от действий пользователя.

a:hover {
  color: red;
}

Ссылка <a> становится красной при наведении.

input:focus {
  border: 2px solid blue;
}

Когда пользователь кликает на <input>, его рамка становится синей.

:active — при нажатии

button:active {
  background-color: gray;
}

Кнопка меняет цвет в момент нажатия.

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

:first-child — Первый ребёнок в родителе

Этот селектор применяется к первому дочернему элементу внутри родителя.

Пример:

p:first-child {
  color: red;
}

HTML:

<div>
  <p>Я первый — стану красным!</p>
  <p>Я обычный.</p>
</div>

Красным станет только первый <p> внутри <div>.

Важно! Если перед <p> будет другой тег, правило не сработает:

<div>
  <h1>Заголовок</h1>
  <p>Я НЕ изменюсь, потому что не первый ребёнок!</p>
</div>

<p> не изменится, потому что первым ребёнком <div> является <h1>.

:last-child — Последний ребёнок

Работает аналогично :first-child, но выбирает последний элемент в родителе.

Пример:

p:last-child {
  color: blue;
}

HTML:

<div>
  <p>Обычный абзац.</p>
  <p>Я последний — стану синим!</p>
</div>

Синим станет только последний <p> внутри <div>.

:nth-child(n) — Выбор элемента по номеру

Этот псевдокласс позволяет выбрать конкретный элемент по порядковому номеру.

Пример:

p:nth-child(3) {
  color: green;
}

HTML:

<div>
  <p>Абзац 1</p>
  <p>Абзац 2</p>
  <p>Абзац 3 — стану зелёным!</p>
  <p>Абзац 4</p>
</div>

Только третий <p> изменится.

:nth-child(odd) и :nth-child(even) — Чётные и нечётные элементы

Пример:

li:nth-child(odd) {
  background-color: lightgray;
}
li:nth-child(even) {
  background-color: white;
}

HTML:

<ul>
  <li>Элемент 1 (серый)</li>
  <li>Элемент 2 (белый)</li>
  <li>Элемент 3 (серый)</li>
  <li>Элемент 4 (белый)</li>
</ul>

Это полезно, например, для зебра-стиля в таблицах.

:nth-child(n) с формулой

Ты можешь использовать математические выражения, чтобы выбрать элементы с определённым шагом.

Выражения:
Формула Выбор элементов
:nth-child(3n) 3-й, 6-й, 9-й...
:nth-child(3n+1) 1-й, 4-й, 7-й...
:nth-child(4n+2) 2-й, 6-й, 10-й...

Пример:

li:nth-child(3n) {
  font-weight: bold;
}

Сделает каждый 3-й элемент жирным.

:nth-last-child(n) — Отсчёт с конца

Этот селектор работает как :nth-child(n), но считает с конца.

Пример:

p:nth-last-child(2) {
  color: purple;
}

HTML:

<div>
  <p>Абзац 1</p>
  <p>Абзац 2</p>
  <p>Абзац 3 (второй с конца) — фиолетовый!</p>
  <p>Абзац 4</p>
</div>

Выбирает второй с конца <p>.

:only-child — Единственный ребёнок

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

Пример:

p:only-child {
  background: yellow;
}

HTML:

<div>
  <p>Я единственный и стану жёлтым!</p>
</div>

<div>
  <p>Я не изменюсь, потому что нас тут двое.</p>
  <p>Видишь?</p>
</div>

Сработает только для <p>, если он один внутри родителя.

Какой псевдокласс использовать?
Селектор Что делает?
:first-child Первый элемент в родителе
:last-child Последний элемент в родителе
:nth-child(n) Конкретный элемент (например, 3-й)
:nth-child(odd) Все нечётные элементы
:nth-child(even) Все чётные элементы
:nth-child(3n) Каждый 3-й элемент
:nth-last-child(n) Элемент с конца
:only-child Если элемент — единственный в родителе

Псевдоэлементы

Псевдоэлементы позволяют добавить контент или стилизацию без изменения HTML.

::before и ::after

Они создают виртуальный элемент, который добавляется до (::before) или после (::after) содержимого реального элемента.

Главное правило:

Пример:

.button::before {
  content: "🔥 "; /* Добавляет эмодзи перед кнопкой */
}

.button::after {
  content: " ➡"; /* Добавляет стрелку после кнопки */
}

Украшаем кнопки без лишнего HTML

button::before {
  content: "👉 ";
}
button::after {
  content: " 🚀";
}

Эффект подчёркивания текста (без border-bottom)

Можно сделать анимированное подчёркивание текста при наведении.

.link::after {
  content: "";
  display: block;
  width: 100%;
  height: 2px;
  background: blue;
  transform: scaleX(0);
  transition: transform 0.3s ease-in-out;
}

.link:hover::after {
  transform: scaleX(1);
}

При наведении появится плавная линия снизу!

Атрибутные селекторы

Обычно для стилизации мы используем классы (.class) и ID (#id), но что делать, если у элементов нет классов?

Тут на помощь приходят атрибутные селекторы! Они позволяют применять стили к элементам по их атрибутам (href, type, data-* и т. д.). Это удобно, когда классы не заданы или когда мы хотим выбрать элементы динамически.

Пример применения:

Основные атрибутные селекторы:

[атрибут]

[атрибут] — выбирает элементы, у которых просто есть этот атрибут

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

input[required] {
  border: 2px solid red;
}

HTML:

<input type="text" required> <!-- Красная рамка -->
<input type="text"> <!-- Обычный -->

Только первое поле получит красную рамку, потому что оно содержит required.

[атрибут="значение"]

[атрибут="значение"] — точное совпадение

Этот селектор выбирает элементы, у которых атрибут имеет ровно указанное значение.

input[type="password"] {
  background-color: lightgray;
}

HTML:

<input type="text"> <!-- Обычный -->
<input type="password"> <!-- Серый фон -->

Только input type="password" изменится, а другие нет.

[атрибут^="начало"]

[атрибут^="начало"] — если значение начинается с указанного текста

Этот селектор применяется, если значение атрибута начинается с указанного слова или символа.

a[href^="https"] {
  color: green;
}

HTML:

<a href="https://example.com">Безопасный сайт</a> <!-- Зелёный -->
<a href="http://example.com">Обычный сайт</a> <!-- Обычный -->

Все ссылки, которые начинаются с https://, станут зелёными.

Где использовать?

[атрибут$="конец"]

[атрибут$="конец"] — если значение заканчивается на указанный текст

Этот селектор применяется, если значение атрибута заканчивается на определённое слово.

img[src$=".jpg"] {
  border: 5px solid blue;
}

HTML:

<img src="photo.jpg"> <!-- Синяя рамка -->
<img src="photo.png"> <!-- Обычный -->

Только изображения .jpg получат синюю рамку.

Где использовать?

[атрибут*="подстрока"]

[атрибут*="подстрока"] — если значение содержит указанный текст

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

div[data-role*="admin"] {
  background-color: gold;
}

HTML:

<div data-role="admin-user">Я админ</div> <!-- Золотой фон -->
<div data-role="user">Я обычный пользователь</div> <!-- Обычный -->

Только div, содержащий "admin" в data-role, получит стили.

Где использовать?

arrow-up