Селекторы :nth-child, :last-of-type, :not, :empty и им подобные. Надо разбираться…
Это расширенное руководство по псевдоклассам CSS для позиционного выбора элементов охватывает все основные селекторы семейства nth, а также дополнительные псевдоклассы для точного выбора элементов на веб-странице.
Основные псевдоклассы для позиционного выбора
:nth-child() — выбор по позиции среди всех соседних элементов
Селектор :nth-child() выбирает элементы по их порядковому номеру, учитывая все элементы на одном уровне, независимо от их типа.
Синтаксис: :nth-child(n)
Ключевая особенность: Считает все элементы на уровне, не важно какого они типа.
Основные варианты использования:
/* Конкретный элемент */
li:nth-child(4) { color: red; }
/* Четные элементы */
p:nth-child(even) { background: lightgray; }
p:nth-child(2n) { background: lightgray; } /* аналогично */
/* Нечетные элементы */
div:nth-child(odd) { border: 1px solid blue; }
div:nth-child(2n+1) { border: 1px solid blue; } /* аналогично */
/* Каждый третий элемент */
span:nth-child(3n) { font-weight: bold; }
/* Первые 5 элементов */
li:nth-child(-n+5) { text-decoration: underline; }
/* Начиная с 3-го элемента */
div:nth-child(n+3) { margin-top: 10px; }Математические выражения в :nth-child():
an+b— гдеaиbцелые числа,n— счетчик от 03n+2выберет элементы 2, 5, 8, 11, 14…4n+1выберет элементы 1, 5, 9, 13…-n+3выберет первые 3 элемента
:nth-of-type() — выбор по позиции среди элементов одного типа
Селектор :nth-of-type() выбирает элементы по порядковому номеру, но учитывает только элементы указанного типа.
Синтаксис: :nth-of-type(n)
Ключевая особенность: Считает только элементы того же типа.
/* Второй параграф (считая только <p>) */
p:nth-of-type(2) { font-size: 18px; }
/* Каждое четное изображение */
img:nth-of-type(even) { border-radius: 10px; }
/* Каждый третий заголовок h2 */
h2:nth-of-type(3n) { color: purple; }Разница между :nth-child() и :nth-of-type():
<div>
<h1>Заголовок</h1>
<p>Первый параграф</p><!-- p:nth-child(2), p:nth-of-type(1) -->
<p>Второй параграф</p><!-- p:nth-child(3), p:nth-of-type(2) -->
</div>:nth-last-child() — выбор с конца среди всех элементов
Работает как :nth-child(), но отсчет ведется с последнего элемента.
/* Предпоследний элемент */
li:nth-last-child(2) { font-style: italic; }
/* Последние 3 элемента */
div:nth-last-child(-n+3) { background: yellow; }
/* Четные элементы с конца */
tr:nth-last-child(even) { background: #f0f0f0; }:nth-last-of-type() — выбор с конца среди элементов одного типа
Аналог :nth-of-type(), но отсчет с конца и только среди элементов того же типа.
/* Последний параграф */
p:nth-last-of-type(1) { margin-bottom: 0; }
/* Второй span с конца */
span:nth-last-of-type(2) { text-decoration: underline; }
/* Каждый третий элемент с конца */
p:nth-last-of-type(3n) { background: red; }Селекторы для выбора первых и последних элементов
:first-child и :last-child
Выбирают первый и последний элемент среди всех соседних элементов.
/* Первый элемент любого типа */
p:first-child { margin-top: 0; }
/* Последний элемент любого типа */
li:last-child { border-bottom: none; }Важно: Элемент должен действительно быть первым/последним среди всех элементов, а не только своего типа.
:first-of-type и :last-of-type
Выбирают первый и последний элемент конкретного типа.
/* Первый заголовок h2 в контексте */
h2:first-of-type { color: blue; }
/* Последний параграф */
p:last-of-type { margin-bottom: 20px; }
/* Первое изображение */
img:first-of-type { border: 3px solid gold; }Селекторы для единственных элементов
:only-child
Выбирает элемент, который является единственным дочерним элементом своего родителя.
/* span, который единственный в родителе */
span:only-child {
font-weight: bold;
color: red;
}
/* Единственный элемент списка */
li:only-child {
list-style: none;
text-align: center;
}Эквивалентно записи: :first-child:last-child
:only-of-type
Выбирает элемент, который является единственным элементом своего типа среди соседей.
/* Единственный заголовок h1 */
h1:only-of-type { text-align: center; }
/* Единственная таблица в контейнере */
table:only-of-type { width: 100%; }Специальные псевдоклассы
:empty — выбор пустых элементов
Выбирает элементы, которые не содержат текста или дочерних элементов.
/* Скрыть пустые div */
div:empty { display: none; }
/* Стилизация пустых параграфов */
p:empty {
height: 20px;
background: #f0f0f0;
border: 1px dashed #ccc;
}
/* Скрыть пустые элементы реакций */
.reactions:empty { display: none; }Важные нюансы :empty:
- Пробелы и переносы строк считаются содержимым
- HTML-комментарии НЕ считаются содержимым
- Псевдоэлементы НЕ считаются содержимым
<div></div> <!-- Пустой -->
<div> </div> <!-- НЕ пустой (пробел) -->
<div><!-- комментарий --></div> <!-- Пустой -->
<div><br></div> <!-- НЕ пустой (дочерний элемент) -->:not() — отрицающий селектор
Исключает из выборки элементы, соответствующие указанному селектору.
/* Все div, кроме с классом special */
div:not(.special) { opacity: 0.8; }
/* Все активные поля ввода */
input:not(:disabled) { border: 2px solid green; }
/* Все элементы списка кроме последнего */
li:not(:last-child) { margin-bottom: 10px; }
/* Все кнопки кроме primary и danger */
button:not(.primary):not(.danger) { opacity: 0.5; }Современный синтаксис CSS4 (ограниченная поддержка):
/* Список селекторов через запятую */
button:not(.primary, .danger) { opacity: 0.5; }Комбинирование селекторов
Выбор диапазона элементов
Для выбора элементов в определенном диапазоне используйте комбинацию селекторов:
/* Элементы с 4 по 8 включительно */
li:nth-child(n+4):nth-child(-n+8) {
background: lightblue;
}
/* Все элементы кроме первых трех */
p:nth-child(n+4) { margin-left: 20px; }
/* Первые 5 элементов */
div:nth-child(-n+5) { border-top: 1px solid black; }Условные селекторы по количеству
Выбор элементов в зависимости от общего количества:
/* Первый элемент, только если всего элементов 6 */
li:nth-last-child(6):first-child { color: tomato; }
/* Все элементы, только если их 6 или больше */
li:nth-last-child(n+6),
li:nth-last-child(n+6) ~ li { color: green; }
/* Все элементы, только если их 6 или меньше */
li:nth-last-child(-n+6):first-child,
li:nth-last-child(-n+6):first-child ~ li { color: blue; }Практические примеры
Стилизация таблиц
/* Полосатая таблица */
tr:nth-child(even) { background: #f9f9f9; }
tr:nth-child(odd) { background: white; }
/* Первая строка заголовка */
thead tr:first-child {
font-weight: bold;
background: #333;
color: white;
}
/* Последняя ячейка в строке */
td:last-child { text-align: right; }Навигационные меню
/* Все пункты меню кроме последнего */
.menu li:not(:last-child) { border-right: 1px solid #ddd; }
/* Первый пункт меню */
.menu li:first-child a { padding-left: 0; }
/* Активный пункт меню, но не последний */
.menu li.active:not(:last-child) {
border-right-color: #007acc;
}Формы
/* Все поля ввода кроме отключенных */
input:not(:disabled):focus {
border-color: blue;
box-shadow: 0 0 5px rgba(0,0,255,0.3);
}
/* Каждое второе поле для создания "зебры" */
.form-field:nth-child(even) { background: #f8f8f8; }
/* Последнее поле в форме */
.form-field:last-child { margin-bottom: 0; }Галереи изображений
/* Каждое третье изображение в ряд */
.gallery img:nth-child(3n) { margin-right: 0; }
/* Первое изображение в галерее */
.gallery img:first-of-type {
width: 100%;
height: 300px;
object-fit: cover;
}
/* Пустые контейнеры изображений */
.image-placeholder:empty {
background: #ddd;
height: 200px;
display: flex;
align-items: center;
justify-content: center;
}Лучшие практики и советы
1. Производительность
- Избегайте слишком сложных выражений
:nth-child()может быть медленнее:first-childили:last-child- Используйте классы для часто повторяющихся паттернов
2. Читаемость кода
/* Хорошо */
.article p:first-of-type { font-size: 18px; }
/* Избегайте слишком сложных селекторов */
.content div:nth-child(3n+2):not(.special):first-of-type { ... }3. Совместимость
- Большинство селекторов поддерживается всеми современными браузерами
:not()с несколькими селекторами (CSS4) имеет ограниченную поддержку
4. Отладка
Используйте инструменты разработчика браузера для тестирования селекторов:
/* Временно подсветить выбранные элементы */
li:nth-child(3n+1) {
outline: 2px solid red !important;
}Эти CSS-селекторы предоставляют мощные инструменты для точного выбора элементов без необходимости добавления дополнительных классов в HTML. Правильное использование этих псевдоклассов позволяет создавать более чистый и гибкий код стилизации.