CSS-селекторы и их мощь: Учимся управлять стилями как профи
Тут мы разберём один из самых мощных инструментов в веб-стилизации — CSS-селекторы. Именно они помогают находить нужные элементы на странице и придавать им стиль. Если ты знаешь, как ими управлять, то сможешь легко кастомизировать сайт без лишнего кода.
Простые селекторы — наша база
Это фундамент, на котором строятся все стили. Давай рассмотрим три главных типа:
Селектор элемента
Выбирает все элементы с определённым тегом.
Как работает?
p {
color: blue;
font-size: 16px;
}
Этот код окрасит все <p> на странице в синий цвет и сделает их размером 16px.
Пример в HTML
<p>Привет, мир!</p>
<p>Это обычный абзац.</p>
Оба <p> будут синими.
Когда использовать?
- Если тебе нужно задать общий стиль для всех элементов (h1, p, button).
- Для базовых стилей, например, body { font-family: Arial; }.
Селектор класса
Применяется только к тем элементам, у которых есть определённый 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 (#id) имеет очень высокий приоритет (100).
- Класс (.class) имеет средний приоритет (10).
- Тег (div, p) — низкий приоритет (1).
Если ты стилизуешь элемент через #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>, станут оранжевыми.
Псевдоклассы — динамические и структурные
Динамические псевдоклассы
Они помогают менять стиль в зависимости от действий пользователя.
- :hover — при наведении
a:hover {
color: red;
}
Ссылка <a> становится красной при наведении.
- :focus — при фокусе (например, на поле ввода)
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) — Чётные и нечётные элементы
- odd (нечётные): 1-й, 3-й, 5-й...
- even (чётные): 2-й, 4-й, 6-й...
Пример:
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) содержимого реального элемента.
Главное правило:
- Псевдоэлементы НЕ появляются в HTML-коде, но их можно стилизовать в CSS.
- Они обязательно требуют content: "" (даже если контент пустой).
Пример:
.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 type="submit".
- Сделать все внешние ссылки (https://...) зелёными.
- Выбрать кнопки с определённым 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://, станут зелёными.
Где использовать?
- Чтобы выделить безопасные ссылки (https — безопасный протокол).
- Для стилизации картинок с определённого домена (src^="https://cdn.example.com").
[атрибут$="конец"]
[атрибут$="конец"] — если значение заканчивается на указанный текст
Этот селектор применяется, если значение атрибута заканчивается на определённое слово.
img[src$=".jpg"] {
border: 5px solid blue;
}
HTML:
<img src="photo.jpg"> <!-- Синяя рамка -->
<img src="photo.png"> <!-- Обычный -->
Только изображения .jpg получат синюю рамку.
Где использовать?
- Для стилизации определённых типов файлов (.jpg, .pdf).
- Выделить кнопки, заканчивающиеся на "-danger" (button[id$="-danger"]).
[атрибут*="подстрока"]
[атрибут*="подстрока"] — если значение содержит указанный текст
Выбирает элементы, если значение атрибута содержит указанный текст (в любой части строки).
div[data-role*="admin"] {
background-color: gold;
}
HTML:
<div data-role="admin-user">Я админ</div> <!-- Золотой фон -->
<div data-role="user">Я обычный пользователь</div> <!-- Обычный -->
Только div, содержащий "admin" в data-role, получит стили.
Где использовать?
- Например, чтобы выбрать все элементы, содержащие "admin", "user" и т. д.
- Например, чтобы найти все ссылки, содержащие "promo" (a[href*="promo"]).