Селектор сестринского элемента

Автор: Александр Головко Дата публикации: 11.05.2011
Последнее обновление:12.09.2017

Предыдущая статья Селектор дочернего элемента.

Описание селектора:

  • Выполняемая задача — выбор элемента, расположенного непосредственно за другим заданным элементом и имеющего с ним общего родителя.
  • Обозначение — цепочка: простой селектор предыдущего элемента, комбинатор «+», простой селектор выбираемого элемента.
  • Пример использования:

элемент span, следующий сразу после заголовка h1 (при условии, что у них есть общий родитель) будет выделен жирным текстом:

h1 + span {
	font-weight: bold;
}

Подробнее про селектор сестринского элемента

Чтобы все окончательно стало понятно давай посмотрим несколько примеров HTML кода. Мысленно применим к ним CSS, приведенный выше, и представим результат.

Этот span будет жирным — он идет сразу за h1 и предполагается, что у них есть общий родитель:

<h1>Очень полезная статья</h1>
<span>Тут указан, например, автор. Жирный текст</span>
<p>Далее идет текст статьи</p>

А такой span не будет жирным — между ним и h1 имеется дополнительный элемент:

<h1>Очень полезная статья</h1>
<p>Далее идет текст статьи</p>
<span>Нежирный текст</span>

Далее пример немного сложнее. Как думаешь, будет ли следующий span выделен жирным?

<h1>Очень полезная статья</h1>
Далее идет текст статьи.
<span>Мы с h1 сестринские?</span>

Правильный ответ — да, будет. Запомни, согласно спецификации W3C простой текст (не взятый ни в какой тег) игнорируется сестринским селектором. Также проигнорировались бы комментарии (если бы мы их расположили между h1 и span).

Посмотри еще несколько примеров:

<h1>Очень полезная статья</h1>
<p><span>Нежирный текст</span> Далее идет текст статьи</p>

<div>
	<h1>Очень полезная статья</h1>
</div>
<span>Нежирный текст</span>

Эти span'ы не будут жирными, так как у них и у элемента h1 разные родители.

Для того, чтобы подробнее разобраться с родственными связями в HTML можешь почитать статью Дерево документа HTML.

Псевдоинверсия :first-child

Не забудь, что селектор выбирает именно тот элемент, который в записи следует после комбинатора. В нашем примере выбирался именно «span после h1», но не наоборот. На этом принципе построен интересный прием выбора первого из группы однотипных элементов:

li + li {
	font-weight: bold;
}
<ul>
	<li>Нежирный текст</li>
	<li>Жирный текст</li>
	<li>Жирный текст</li>
	<li>Жирный текст</li>
</ul>

Получается как бы :first-child наоборот. Стили применяются ко всем элементам кроме первого. Конечно, это не совсем :first-child. Тут подразумевается «кроме первого из группы однотипных».

Никто не запретит написать такой код:

p + p {
	font-weight: bold;
}
<div>
	<h1>Заголовок</h1>
	<span>Тут затесался какой-то span!</span>	
	<p>Нежирный текст</p>
	<p>Жирный текст</p>
	<p>Жирный текст</p>
	<p>Жирный текст</p>
	<p>Жирный текст</p>
</div>

Затесавшийся между h1 и группой абзацев span не позволит применить индивидуальные стили для первого абзаца с помощью :first-child, ведь теперь первый потомок именно span! А сестринский элемент эту задачу решит просто и элегантно (надеюсь, понятно, что «применить стили к первому абзацу» и «применить стили ко всем абзацам кроме первого» — это фактически равнозначные действия, так как и то и другое позволит выделить первый абзац и задать ему индивидуальное оформление).

Хотя, по правде говоря, я слабо представляю, где вышеприведенный код придется использовать в реальном проекте. Так что будем считать последний пример просто демонстрацией возможностей.

Ограничение

IE6 не понимает сестринский селектор. Вразумить его можно с помощью experssion. Подробнее читай статью Сестринский селектор для IE6.

Область применения

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

Например, можешь ознакомиться со статьей Индивидуальные стили для li. Избавляемся от классов.

Следующая статья — Селектор обобщенных родственных элементов.