skip to main content

Комбинированные селекторы

css

Кратко 🔗

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

Группировка: .element1, .element2 🔗

Пример 🔗

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

h1 {
font-weight: bold;
}

h2 {
font-weight: bold;
}

h3 {
font-weight: bold;
}

А можно перечислить все селекторы через запятую и написать всего одно CSS-правило:

h1, h2, h3 {
font-weight: bold;
}

Как пишется 🔗

Селекторы просто записываются в произвольном порядке через запятую:

.selector1,
code,
#id,
[attr="value"]
{
color: red
}

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

.heading span,
.block,
.wrapper
{
color: red
}

Это значит, что свойство применится для трёх типов селекторов:

  1. для всех <span> внутри класса .heading (на любом уровне вложенности);
  2. для всех элементов с классом .block;
  3. для всех элементов с классом .wrapper;

Как это понять 🔗

Свойства, описанные в блоке внутри {} будут применены к каждому селектору, разделённому запятой.

В работе 🔗

Роман,

🛠 Лучше записывать селекторы по одному на строчку — так их легче читать и редактировать:

.selector1,
code,
#id,
[attr="value"]
{
color: red;
}

Объединение: .class1.class2 🔗

Пример 🔗

.selector.selector_mod {
color: red;
}

Как пишется 🔗

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

Как это понять 🔗

Такое «склеивание» объединяет селекторы в одно правило.

В работе 🔗

Роман,

🛠 Объединение увеличивает специфичность правила, поэтому это может быть удобно для переопределения свойств без !important:

Код ниже нельзя редактировать по каким-то причинам:

.class1 {
color: red;
}

Увеличим специфичность, чтобы переопределить правило, описанное в нередактируемой части и потому имеющее бо́льший вес:

.class1.class2 {
color: green;
}

.class1 {
color: red;
}

В итоге текст в блоке, имеющем сразу и класс .class1 и класс .class2, будет зелёного цвета.

Потомки: .element1 .element2 🔗

Пример 🔗

article h3 {
color: red;
}

Как пишется 🔗

Селекторы записываются последовательно через пробел.

Как это понять 🔗

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

В работе 🔗

Роман,

🛠 Получается, что даже невинный пробел уже имеет значение при выборе селектор на любом уровне вложенности.

Независимо от уровня вложенности селектор article h3 «найдёт» <h3> с текстом «Очень вложенный заголовок» и любые другие <h3>, которые располагаются внутри <article>:

<article>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<div>
<h3>Очень вложенный заголовок</h3>
</div>
</div>
</div>
<h3>Заголовок</h3>
</div>
</div>
</div>
</div>
</div>
</div>
</article>

Непосредственно вложенные: .element1 > .element2 🔗

Пример 🔗

article > h3 {
color: red
}

Как пишется 🔗

Селекторы разделяются знаком >.

Как это понять 🔗

Последовательность селекторов отражает непосредственную вложенность — селектор справа от оператора должен быть прямым потомком селектора из левой части:

article > h3 {
color: red
}

К h3.article__heading стили для article > h3 не применятся, т. к. прямой потомок <article>div.article__header, а не <h3>:

<article class="article">
<div class="article__header">
<h3 class="article__heading">Заголовок</h3>
</div>
</article>

В этом примере стили к заголовку применяться, потому что <h3> является прямым потомком <article>:

<article class="article">
<h3 class="article__heading">Заголовок</h3>
</article>

И тут тоже всё в порядке — <h3> по-прежнему является прямым потомком <article>, потому что располагается на ближайшем уровне вложенности, хоть и следует после div.article__header:

<article class="article">
<div class="article__header"></div>
<h3 class="article__heading">Заголовок</h3>
</article>

Подсказки 🔗

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

Смежные: .element1 + .element2 🔗

Пример 🔗

label + input {
color: red;
}

Как пишется 🔗

Селекторы объединяются знаком +.

Как это понять 🔗

Элемент справа от + должен следовать в HTML сразу за элементом слева от +. Проще говоря, правый элемент должен быть соседом левого элемента, чтобы селектор сработал.

Код из примера применится только к такому <input>, который стоит сразу после <label>:

label + input {
color: red;
}

К этому не применится, т. к. перед <input> идёт <p>:

<label></label>
<p></p>
<input>

При такой разметке стиль применится только к первому <input>, но не ко второму:

<label>Лейбл</label>
<input>
<input>

И тут правило не сработает. <label> и <input> — на разных уровнях вложенности:

<label>Лейбл</label>
<div>
<input>
</div>

В работе 🔗

Роман,

🛠 С помощью смежного комбинатора удобно «выделять» группу одинаковых элементов по принципу «все кроме первого», например, для отступа.

К первому <li> стили не применятся, поскольку перед ним нет другого <li>:

<ul>
<li>Первый пункт</li>
<li>Второй пункт</li>
<li>Третий пункт</li>
<li>Четвёртый пункт</li>
</ul>
li + li {
margin-top: 1em;
}

Последующие: .element1 ~ .element2 🔗

Пример 🔗

.star:hover ~ .star {
color: red;
}

Как пишется 🔗

Селекторы объединяются с помощью символа ~ (тильда).

Как это понять 🔗

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

В работе 🔗

Роман,

Классический пример — вёрстка «звёздного» рейтинга. Для начала опишем структуру:

<div class="rating">
<button></button>
<button></button>
<button></button>
<button></button>
<button></button>
</div>

И стили:

button {
border: none;
background-color: transparent;
font-size: 2em;
}

button:hover,
button:focus,
button:hover ~ button,
button:focus ~ button
{
color: red;
}

Но сейчас при наведении курсора будут выделиться все элементы после (т. е. справа). Чтобы это исправить, мы изменим порядок следования элементов с помощью CSS-свойства direction: rtl:

See the Pen rating by Alena (@solarrust) on CodePen.

Автор: Роман,