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

Основные селекторы

Селекторы типа выбирают элементы HTML-документа по их тегу. Например, селектор p выберет все <p> на странице:

<body>
  <p>Текст</p>
  <p>Другой текст</p>
</body>
p {
  font-size: 16px;
}

Селекторы класса определяют стиль элементов с определённым классом. Например, этот селектор выберет абзац с классом .highlight.

<body>
  <p class="highlight">Текст</p>
  <p>Другой текст</p>
</body>
.highlight {
  background-color: yellow;
}

Селекторы идентификатора выбирают элемент по его уникальному идентификатору. Например, #welcome соответствует элементу с id="welcome":

<div id="welcome">
  <p>Добро пожаловать!</p>
</div>
#welcome {
  background-color: blue;
}

Селекторы наличия и значения атрибута находят все элементы, которые имеют определённый атрибут или значение атрибута. Например, здесь мы выбираем все ссылки, которые начинаются на http://, но не имеют example.com.

a[href^="http://"]:not([href*="[example.com](http://example.com/)"]) {
  color: #000;
  text-decoration: none;
}

Универсальный селектор позволяет прописать стили для всех элементов HTML без исключения. Он указывается в виде звёздочки *. В примере ниже мы используем универсальный селектор с псевдоэлементами, чтобы изменить расчёт общего размера элемента.

*,
*::before,
*::after {
  box-sizing: border-box;
}

Селекторы-комбинаторы

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

Пример DOM-дерева. Здесь html — родитель для head и body. В свою очередь head — родитель для meta и title, а body — для header и main

Соседний родственный комбинатор

Записывается как селектор1 + селектор2. Выбирает элемент, подходящий под селектор2, перед которым расположен элемент, подходящий под селектор1.

<div>
  <p class="first">Сегодня я стал великим фронтендером.</p>
  <p class="second">Я написал стили для текста.</p> 
<div>
.first + .second {
  color: white;
}

Селектор .first + .second применит стили к абзацу с классом .second, потому что перед ним есть элемент с классом .first. Предложение «Я написал стили для текста.» станет белым.

Дочерний комбинатор

Записывается как селектор1 > селектор2. Выбирает элементы, которые являются прямыми потомками элемента, подходящего под селектор1.

<div class="decoration">
  <p>Я выучил CSS</p>
	<div>
    <p>Ну селекторы точно знаю.</p>
  </div>
</div>
.decoration > p {
  color: red;
}

Стили применятся только к «Я выучил CSS», этот текст станет красным.

Общий родственный комбинатор

Записывается как селектор1 ~ селектор2. Добавляет стили для элемента, который соответствует селектор2, если перед ним стоит элемент, подходящий под  селектор1. Оба элемента должны принадлежать одному родителю.

<div>
  <p>Это было прекрасное раннее утро. Идеальное время, чтобы приготовить чашку кофе или чая, открыть ноутбук и выучить CSS.</p>
  <p>Так Вовка и поступил. Погладил кота, набрался решимости и открыл для себя новый мир вёрстки.</p>
</div>
p ~ p {
  margin-top: 1em;
}

Стили применятся ко второму параграфу, появится внешний отступ сверху.

Этот селектор отличается от соседнего селектора тем, что между элементами селектор1  и селектор2 могут находиться другие элементы.

Комбинатор потомка

Записывается как селектор1 селектор2. Находит все потомки элемента, который подходит под селектор1, и применяет к ним стили.

<p>Оказалось, что селекторы — это
  <span>не так страшно,</span>
  как я думал. Нужно только немного попрактиковаться,
  <span>и всё сразу станет ясно.</span>
</p>
p span {
  color: blue;
}

Здесь в синий цвет окрасятся «не так страшно» и «всё сразу станет ясно.».

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

Псевдоклассы — это простые селекторы, позволяющие выбирать элементы на основе информации, которая находится за пределами DOM-дерева или которую невозможно выразить с помощью простого селектора.

💡 Простой селектор — это селектор по одному условию, односоставной.

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

Чтобы использовать псевдокласс, нужно добавить его в селектор, например:

a:active {
  color: red;
}

В этом примере мы меняем цвет ссылки на красный, когда пользователь кликает по ней.

:hover

Псевдокласс :hover соответствует элементу, когда пользователь наводит на него курсор мыши. Например, здесь псевдокласс используется, чтобы убрать подчёркивание ссылки:

Как убрать подчёркивание ссылки

<a href="#">Нажми на меня</a>
a:hover {
  text-decoration: none;
}

:active

Псевдокласс :active соответствует элементу, на который активно нажимают. Здесь псевдокласс используется для скругления рамок кнопки, когда на неё кликают:

button:active {
  border-radius: 30px;
}

:visited

Псевдокласс :visited соответствует посещённой ссылке. Например, с его помощью мы можем поменять цвет ссылки, по которой перешёл пользователь:

a:visited {
  color: grey;
}

:focus

Псевдокласс :focus соответствует элементу, находящемуся в фокусе — то есть когда элемент выбран для ввода или навигации с помощью клавиатуры. Например, здесь :focus используется для добавления зелёной рамки вокруг поля ввода:

<input type="text">
input:focus {
  border: 2px solid green;
}

:first-child, :last-child и :nth-child(n)

Эти псевдоклассы выбирают элемент по его порядковому номеру. :first-child соответствует первому дочернему элементу родителя, :last-child — последнему. А псевдокласс :nth-child(n) указывает на n-й дочерний элемент. Например, с его помощью можно выбрать второй, пятый или предпоследний элемент. Вместо n в скобках указывается целое число или математическое выражение.

<ul>
  <li>HTML</li>
  <li>CSS</li>
  <li>JavaScript</li>
</ul>
/* выберет первый элемент — HTML*/
li:first-child {
  font-weight: 700;
}

/* выберет последний элемент — JavaScript*/
li:last-child {
  text-decoration: underline;
}

/* выберет второй элемент — CSS*/
li:nth-child(2) {
  font-weight: 700;
}

:first-of-type, :last-of-type и :nth-of-type(n)

Эти псевдоклассы похожи на предыдущие. Они тоже выбирают элемент по его порядковому номеру, но только с учётом типа — тега.

<div>
  <p>Первый параграф</p>
  <p>Второй параграф</p>
  <div>
    <span>Выделенный текст</span>
    <p>Третий параграф</p>
    <p>Четвёртый параграф</p>
  </div>
  <p>Пятый параграф</p>
  <span>Выделенный текст</span>
</div>
/*Текст в первом теге <p> будет жирным*/
p:first-of-type {
  font-weight: 700;
}

/*Текст во втором теге <p> будет подчёркнут*/
p:nth-of-type(2) {
  color: green;
}

/*Текст в последнем теге <p> будет подчёркнут*/
p:last-of-type {
  text-decoration: underline;
}

«Первый параграф» и «Третий параграф» станут жирными. «Второй параграф и «Четвёртый параграф» окрасятся в зелёный. «Четвёртый параграф» и «Пятый параграф» будут подчёркнутыми.

Если мы используем здесь first-child, nth-child(2) и last-child, то получим другую картину. Жирным станет только «Первый параграф». В зелёный окрасятся «Второй параграф» и «Третий параграф». Подчёркнутым будет «Четвёртый параграф». И всё это из-за того, что между <p> есть другие элементы — <span>.

Слева стилизуем текст с помощью селекторов *-of-type, справа — *-child

:empty

Псевдокласс :empty — это селектор CSS, который соответствует элементам, не имеющим дочерних элементов, включая текстовые узлы и другие элементы. Его можно использовать для стилизации элементов, которые пусты или не имеют содержимого:

<input type="text">
input:empty {
  border: 1px solid red;
}}

В этом примере мы с помощью :empty добавляем красную рамку пустому инпуту.

Заключение

Мы разобрали самые популярные селекторы, но на самом деле их больше. Полный перечень вы найдёте в спецификации W3C. А чтобы научиться использовать селекторы на практике, пройдите эти тренажёры из курса «Старт в программирование».

Ещё статьи про CSS