Статьи

CSS селекторы: комбинаторы

cssmasterthumb

Ниже приводится выдержка из нашей книги CSS Master , написанной Тиффани Б. Браун. Копии продаются в магазинах по всему миру, или вы можете купить их в электронном виде здесь .

Правила CSS соответствуют элементам с селекторами . Есть несколько способов сделать это, и вы, вероятно, знакомы с большинством из них. Тип элемента, имя класса, ID и селекторы атрибутов хорошо поддерживаются и широко используются.

Спецификации Селекторов Уровня 3 и Уровня 4 представили несколько новых селекторов. В некоторых случаях это новые варианты существующих типов. В других случаях они являются новыми функциями языка.

В этой главе мы рассмотрим текущий ландшафт браузера для селекторов CSS с акцентом на новые селекторы. Это включает в себя новые селекторы атрибутов и комбинаторы, а также ряд новых псевдоклассов. В разделе « Выбор селекторов мудро» мы рассмотрим концепцию специфики.

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

Совет: охват браузерами селекторов

Всесторонний взгляд на текущее состояние поддержки селекторов в браузере можно найти в CSS4-Selectors.

Комбинаторы

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

Вы должны быть знакомы с большинством этих комбинаторов:

  • комбинатор потомка или символ пробела

  • детский комбинатор, или >

  • комбинатор соседнего брата или +

  • общий братский комбинатор, или ~

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

SelectorsCombinators

Эта форма была создана с использованием следующего фрагмента HTML:

 <form method="GET" action="/processor">
<h1>Buy Tickets to the Web Developer Gala</h1>
<p>Tickets are $10 each. Dinner packages are an extra $5. All fields are required.</p>
<fieldset>
	<legend>Tickets and Add-ons</legend>

	<p>
		<label for="quantity">Number of Tickets</label> 
		<span class="help">Limit 8</span>
		<input type="number" value="1" name="quantity" id="quantity" step="1" min="1" max="8">
</p>

	<p>
		<label for="quantity">Dinner Packages</label> 
		<span class="help">Serves 2</span>
		<input type="number" value="1" name="quantity" id="quantity" step="1" min="1" max="8">
	</p>

</fieldset>
<fieldset>
	<legend>Payment</legend>
	<p>
		<label for="ccn">Credit card number</label>
		<span class="help">No spaces or dashes, please.</span>
		<input type="text" id="ccn" name="ccn" placeholder="372000000000008" maxlength="16" size="16">
	</p>
	<p>
		<label for="expiration">Expiration date</label>
		<span class="help"><abbr title="Two-digit month">MM</abbr>/<abbr title="Four-digit Year">MM</abbr>YYYY</span>
		<input type="text" id="expiration" name="expiration" placeholder="01/2018" maxlength="7" size="7">
	</p>

</fieldset>
<fieldset>
	<legend>Billing Address</legend>
	<p>
		<label for="name">Name</label>
		<input type="text" id="name" name="name" placeholder="ex: John Q. Public" size="40"> 
	</p>
	<p>
		<label for="street_address">Street Address</label>
		<input type="text" id="name" name="name" placeholder="ex: 12345 Main Street, Apt 23" size="40">
	</p>

	<p>
		<label for="city">City</label>
		<input type="text" id="city" name="city" placeholder="ex: Anytown">
	</p>

	<p>
		<label for="state">State</label>
		<input type="text" id="state" name="state" placeholder="CA" maxlength="2" pattern="[A-W]{2}" size="2">
	</p>

	<p>
		<label for="zip">ZIP</label>
		<input type="text" id="zip" name="zip" placeholder="12345" maxlength="5" pattern="0-9{5}" size="5">
	</p>
</fieldset>

<button type="submit">Buy Tickets!</button>
</form>

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

Вы, наверное, довольно хорошо знакомы с потомком комбинатора. Это было вокруг с первых дней CSS (хотя это было без имени типа до CSS2.1). Это широко используется и широко поддерживается.

Комбинатор-потомок — это просто пробельный символ. Он отделяет родительский селектор от его потомка, следуя шаблону AB , где B — это элемент, содержащийся в A. Давайте добавим немного CSS в нашу разметку сверху и посмотрим, как это работает:

 form h1 {
color: #009;
}

Мы только что изменили цвет заголовка нашей формы, результат которого можно увидеть ниже.

DescendantCombinator

Давайте добавим еще немного CSS, на этот раз, чтобы увеличить размер нашего сообщения о ценах («Билеты по 10 долларов США каждый»):

 form p {
font-size: 22px;
}

Однако есть проблема с этим селектором, как вы можете видеть ниже. Мы фактически увеличили размер текста во всех абзацах нашей формы, а это не то, что нам нужно. Как мы можем это исправить? Давайте попробуем детский комбинатор.

DescendentCombinator2

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

В отличие от комбинатора-потомка дочерний комбинатор (>) выбирает только непосредственные дочерние элементы элемента. Он следует шаблону A> B , сопоставляя любой элемент B, где A является непосредственным предком.

Если бы элементы были людьми, по аналогии, дочерний комбинатор соответствовал бы дочернему элементу материнского элемента. Но потомок комбинатор также будет соответствовать ее внукам и правнукам. Давайте изменим наш предыдущий селектор, чтобы использовать дочерний комбинатор:

 form > p {
font-size: 22px;
}

Теперь это касается только прямых потомков article

ChildCombinator

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

С помощью соседнего братского комбинатора ( + Это следует схеме A + B. Стили будут применены к элементам B, которым непосредственно предшествуют элементы A.

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

 label + input {
display: block;
clear: both;
}

Вы можете увидеть результаты ниже.

AdjacentSibling1

Давайте посмотрим на другой пример, который объединяет универсальный селектор (*) с селектором типа:

 * + fieldset {
margin: 5em 0;
}

В этом примере поле 5emfieldset Поскольку мы используем универсальный селектор, не нужно беспокоиться о том, является ли предыдущий элемент другим fieldsetp

AdjacentSibling3

Примечание: больше вариантов использования соседнего селектора

Хейдон Пикеринг (Heydon Pickering) исследует более умные способы использования соседнего селектора брата в своей статье «Аксиоматический CSS и лоботомизированные совы».

Что, если мы хотим стилизовать элемент родного брата, который не соседствует с другим, как в нашем поле Number of Tickets ? В этом случае мы можем использовать общий братский комбинатор.

Генеральный брат и сестра комбинатор

С помощью общего братского комбинатора « тильда» мы можем выбирать элементы, которые имеют одного и того же родителя, не считая их смежными. Учитывая шаблон A ~ B , этот селектор сопоставляет все элементы B, которым предшествует элемент A , независимо от того, являются ли они смежными.

Давайте снова посмотрим на поле « Количество билетов» . Его разметка выглядит так:

 <p>
<label for="quantity">Number of Tickets</label> 
<span class="help">Limit 8</span>
<input type="number" value="1" name="quantity" id="quantity" step="1" min="1" max="8">
</p>

Наш inputlabelspan Поскольку элемент spaninputlabel Давайте изменим наш соседний братский комбинатор на общий братский комбинатор:

 label ~ input {
display: block;
}

Теперь все наши inputlabel

GeneralSiblingCombinator

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