WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Селекторы в CSS

В этой статье я постараюсь понятно объяснить что такое CSS селекторы и как использовать каждый из них. Здесь описаны все селекторы, которые нужно знать при работе с CSS.

Что такое CSS селекторы и каскадность?

CSS селектор - это часть правила, с помощью которого можно выбирать элемент в HTML/XHTML/XML документе. Выбранный элемент можно оформить с помощью различных свойств (стилей) CSS.

Для начала обусловимся:

  • Под словом «селектор» подразумевается один CSS селектор: div, #content, :hover;

  • Под словом «CSS правило» (далее просто «правило») подразумевается комбинация селекторов: #content .text p.

Приоритеты и каскадность

Прежде чем разбирать селекторы, важно знать главный принцип CSS — каскадность (Cascading Style Sheets — каскадные таблицы стилей). Каскадность — это приоритет одних правил (стилей) над другими.

При вычислении приоритета в браузере, каждый селектор получает баллы, затем баллы складываются. Так css-правило получает «вес». В итоге, элемент получит стили самого «весомого» правила.

#content .text p{ color:red; } /* 100 + 10 + 1 = 111 */
.text p{ color:blue; }         /* 10 + 1 = 11 */

Тег <p> внутри элемента .text получит стиль color:red;, а не color:blue;, потому что приоритет выше (111, а не 11).

Если несколько css-правил с одинаковым весом влияют на один элемент, то элемент получит стили правила, которое ближе к концу HTML страницы (ниже в коде).

Какой селектор какие баллы получает:

Тип селектора Описание селектора Баллы
\* универсальный селектор 0
div тег 1
:first-letter псевдо-элемент 1
[атрибут="значение"] селектор атрибута 10
.text класс 10
:hover псевдо-класс 10
#content селектор по id 100
style="color:red;" атрибут style 1000
!important добавка к значению 10000

Немного практики:

* {}                        /* =   0 */
li {}                       /* =   1 */
li::first-line {}           /* =   2 */
ul li {}                    /* =   2 */
ul ol+li {}                 /* =   3 */
ul li.red {}                /* =  12 */
li.red.level {}             /* =  21 */
li:not(.red){}              /* =  11 */
li:not(.red):not(.green){}  /* =  11 */

#t34 {}                     /* = 100 */

#content #wrap {}           /* = 200 */

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

меню

Приоритеты при медиа запросах

Медиа запросы, например: @media ( max-width:500px ){ } не участвуют в подсчете приоритета и всегда должны располагаться ниже всех остальных правил, чтобы перебивать предыдущие, когда срабатывает указанное медиа условие.

Правильно:

.section{ width:100%; }

@media ( max-width:500px ){
	.section{ width:50%; }
}

Неправильно: потому что так медиа запрос всегда имеет меньший приоритет и вообще не будет работать:

@media ( max-width: 500px ){
	.section{ width:50%; }
}

.section{ width:100%; }

Все селекторы CSS (коротко)

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

Такие селекторы указываются в HTML документе (их можно увидеть в исходном коде страницы).

Селектор Пример Описание
* * Все элементы. Кроме псевдо-элементов.
.class .myclass Элемент с class="myclass".
#id #main Элемент с id="main".
HTML тег span Элемент <span>.
[атрибут] [title] Элементы с атрибутом title.
[атрибут = значение] [title="cost"] Элементы с атрибутом  title="cost".
[атрибут ~= значение] [title~="cost"] Элементы с атрибутом title, в значение которого есть cost окруженное или нет пробелом '``':cost,cost foo,foo cost``
[атрибут ^= значение] [src^="http"] Элементы с атрибутом src, значение которого начинается с http.
[атрибут $= значение] [src$=".png"] Элементы с атрибутом src, значение которого заканчивается на .png.
[атрибут *= значение] [src*="kama"] Элементы с атрибутом src, в значении которого присутствует 'kama'.
  • есть еще селектор: [атрибут |= значение]. Пример: [lang |= ru] - элементы с атрибутом lang, значение которого равно ru или начинается с ru-, например "ru-RU". Но он практически не используется и его заменяет комбинация: [lang = ru], [lang ^= ru-].

  • Все эти селекторы отлично поддерживаются всеми браузерами.
меню

Псевдо-классы

Не указывается в разметке HTML-документа. Иногда динамичны - срабатывают при определенном условии (наведение курсора на элемент). Начинаются с двоеточия ':'.

Псевдо-класс Пример Описание
:link a:link Выбор всех не посещенных ссылок.
:visited a:visited Выбор всех посещенных ссылок.
:active a:active Выбор активной ссылки.
:hover a:hover Выбор ссылки при наведении курсора мышки. Вместо `<a>` может быть любой элемент
По расположению на одном уровне
:first-child *:first-child Любой первый элемент в блоке.
:last-child *:last-child Любой последний элемент в блоке.
:only-child *:only-child Любой элемент в блоке, если там всего один элемент.
:nth-child(n)
*:nth-child(2) Любой второй элемент в блоке.
*:nth-child(2n) Любые элементы в блоке по счету: 2, 4, 6, … (чётные).
*:nth-child(even) Любые элементы в блоке по счету: 2, 4, 6, … (чётные).
*:nth-child(2n+1) Любые элементы в блоке по счету: 1, 3, 5, … (нечётные).
*:nth-child(odd) Любые элементы в блоке по счету: 1, 3, 5, … (нечётные).
*:nth-child(3n+2) Элементы номер 2, 5, 8 и так далее.
Наглядно Посмотреть как это работает →
:nth-last-child(n) *:nth-last-child(2) Любой второй элемент в блоке с конца.
По расположению на одном уровне с тем же тегом
:first-of-type p:first-of-type Выбор первого дочернего элемента <p>.
:last-of-type p:last-of-type Выбор последнего дочернего элемента <p>.
:only-of-type p:only-of-type Выбор дочернего элемента <p>, если у родителя элемент <p> всего один.
:nth-of-type(n) p:nth-of-type(2) Выбор второго дочернего элемента <p>.
:nth-last-of-type(n) p:nth-last-of-type(2) Выбор второго дочернего элемента <p> с конца.
Поля форм
:enabled input:enabled Выбор включенного <input>. Обычно ``:enabled`` просто не пишется.
:disabled input:disabled Выбор выключенного <input>.
:focus input:focus Выбор <input>, который находится в фокусе (в который установлен курсор).
:checked input:checked Выбранный элемент <input> типа radio или checkbox.
Остальные
:root :root Выбор корневого элемента в документе.
:empty p:empty Пустой элемент <p>, в котором нет ни текста ни элементов.
:lang(язык) p:lang(ru) Выбор элемента <p> с атрибутом lang, значение которого начинается с "ru".
:target :target Выбор активного элемента на странице, который имеет якорную ссылку.
:not(селектор) :not(p) Выбор всех элементов, кроме <p>.
  • Актуальную поддержку браузеров для CSS3 селекторов смотрите по этой ссылке.
меню

Псевдо-элементы

Элементы, которых реально не существуют в HTML документе. Начинаются с двойного двоеточия ::, но можно и с одинарного :.

Псевдо-элемент Пример Описание Подд. / CSS
::first-letter p::first-letter Выбирает первую букву элемента <p>. 100% / 1
::first-line p::first-line Выбирает первую строку элемента <p>. 100% / 1
::before p::before Вставляет указанное в content:'' содержимое в начало <p>. 100% / 2
::after p::after Вставляет указанное в content:'' содержимое в конец <p>. 100% / 2
::selection p::selection Оформит выделенный (мышкой) текст внутри <p>. Для firefox нужен префикс moz (p::-moz-selection) 71.41% / 3
меню

Объединение селекторов

Для объединения селекторов, используются символы комбинаторы:  , >, +, ~, ,. Они устанавливают взаимосвязь между селекторами.

Комбинатор Пример Описание Подд. / CSS
правило, правило div a, span i Элемент <a> внутри <div> и элемент <i> внутри <span>. 100% / 1
селекторСелектор .c1.c2 Элементы одновременно с двумя классами c1 и c2. 100% / 1
селектор селектор div span Элемент <span> внутри <div>. 100% / 1
селектор > селектор div > span Элементы <span>, у которых родитель <div>. 100% / 2
селектор + селектор div + p Один элемент <p>, который находится сразу после <div>. 100% / 2
селектор ~ селектор div ~ p Все элементы <p>, которые находятся сразу после <div>. 97.5% / 3
меню

Все селекторы CSS (подробно)

*

Выбирает абсолютно все элементы на странице: ``a, ul, li, div и т.д. Можно использовать для сброса стилей всех элементов. Например, такой код обнуляет внутренние и внешние отступы у всех элементов:

* { margin: 0; padding: 0; }

* можно использовать в связке с другими селекторами. Например, сделаем так чтобы все дочерние элементы #container выделялись сплошной черной рамкой шириной 1px.

#container * { border: 1px solid black; }

Применение * создает повышенную нагрузку на скорость работы браузера, поэтому используйте его только по необходимости.

меню

.class

Выбирает элемент у которого есть атрибут class с указанным значением: class="myclass".

Название класса, может состоять из латинских букв (a-zA-Z), цифр (0-9), символа дефиса и подчеркивания (- _).

Следующий код устанавливает красный цвет текста для всех элементов с классом error - <div class="error">:

.error { color: red; }

У одного элемента может быть несколько классов (через пробел): <div class="error myclass">.

#id

Выбирает элемент у которого есть атрибут id с указанным значением: id="myid".

Идентификатор может быть присвоен только одному элементу на странице (если присвоить несколько, то мир не рухнет, но так делать не принято).

Идентификатор должен состоять из латинских букв (a-zA-Z), цифр (0-9), символа дефиса или подчеркивания: - _. Начинается он только с буквы!

Следующий код устанавливает ширину и отступ элемента с идентификатором: <div id="container">:

#container { width: 960px; margin: auto; }

Селектор по ID имеет больший приоритет над селектором по классу (см. начало статьи). Поэтому по возможности получайте элемент по селектору класса, это считается правилом хорошего тона и позволит при необходимости без лишних усилий "перебить" стили.

меню

tag

Селектор HTML тега. Применяться ко всем указанным элементам в документе. Часто используется для задания цвета, фона, шрифта и др.

Следующий код задает цвет текста для всех ссылок и отступы для UL списков:

a { color: red; }
ul { margin-left: 0; }

Х Y

CSS-правило, выбирает элемент Y, который является дочерним элемента X. Может состоять из нескольких селекторов (X Y Z). Сначала обязательно указывается родитель, а после него дочерние элементы. Их количество может быть любым. Свойства стиле будут применены только к последнему элементу.

Например, следующий код выбирает любой элемент <а>, являющийся потомком элемента <li>: (<li><a href="ссылка">текст</a></li>):

li a { text-decoration: none; }

Это правило можно сочетать с идентификаторами и классами: body.opera a{ color:blue; }.

меню

a:link, a:visited, a:hover, a:active

Селекторы псевдоклассов. Задает стиль ссылкам на странице документа в зависимости от их состояния. Псевдокласс :link – устанавливает цвет текста непосещенной ссылке, а псевдокласс :visited – стилизует уже посещенную ссылку. При наведении мыши (под курсором) - a:hover, и в момент нажатия - a:active.

a:link { color: red; } /* можно просто а */
a:visted { color: purple; }
a:hover { color: green; }
a:active { color: blue; }

Все непосещенные ссылки будут красные, а посещенные фиолетовые, а при наведении станут зеленые, а при нажатии на ссылку голубые.

меню

Х + Y

Выбирает первый элемент Y, который находится после X (не вложен, а рядом). Стили будут применяться только к последнему элементу X.

Например, следующий код устанавливает красный цвет текста в абзаце p, который расположен сразу после div:

div + p { color: red; }

Получим:

<div>текст</div>
<p>текст 2</p><!-- color: red; -->
<p>текст 3</p>

Демо →

Х ~ Y

Выбирает все элементы Y, которые расположены после X на одном уровне. По поведению похож на X + Y. Разница в том, что будут выбраны все следующие элементы, а не только первый.

Например, в указанном коде будут выбраны все элементы p, которые расположены после div:

div ~ p { color: red; }

Окрасит  "текст 2" и "текст 3":

<div>текст</div>
<p>текст 2</p><!-- color: red; -->
<p>текст 3</p><!-- color: red; -->

Демо →

Х > Y

Выбирает элементы Y, которые являются дочерними к X, но выбирается только первый уровень дочерних элементов.

Пример:

.parent > li{ border: 1px solid red; }

Добавит отступ для li первого уровня, т.е. тех который является прямым потомком элемента ul:

<ul class="parent">
	<li> список1
		<ul class="child">
			<li>список11</li>
			<li>список12</li>
		</ul>
	</li><!-- затронет -->
	<li>список2</li><!-- затронет -->
	<li>список3</li><!-- затронет -->
</ul>

Это правило не коснется <ul class="child">.

Демо >

меню

X[title]

Селектор атрибутов. Выбирает элементы, которые содержат указанный атрибут.

Например, следующий код меняет цвет ссылки при наличии в элементе a атрибутаtitle:

a[title] { color: green; }

Окрасит только "текст":

<a href="" title="описание">текст</a>
<a href="">текст 2</a>

X[href = "Foo"]

Селектор атрибутов с точным значением. Выбирает элементы, у которых имеется атрибут с указанным значением.

Например, следующий код меняет цвета ссылки на сайт «site.ru»:

a[href="http://example.com"] { color: red; }

Окрасит только "текст":

<a href="http://example.com">текст</a><!-- color: red; -->
<a href="http://example.com/article">текст 2</a>

X[href *= "site.ru"]

Селектор атрибутов с плавающим значением. В следующем примере, символ «*» говорит селектору о том, что нужное значение может быть в любом месте атрибута href у тега a:

a[href*="site"] { color: red; }

Окрасит "текст" и "текст 2":

<a href="http://example.com">текст</a><!-- color: red; -->
<a href="http://example.com/article">текст 2</a><!-- color: red; -->
<a href="http://xxx.ru/article">текст 2</a>

Для уточнения выбора можно использовать указатели "^" (в начале строки), "&" (в конце строки) или "~" (точное значение через пробел). См. ниже.

меню

X[data-* = "foo"]

Это другое применение селектора атрибутов со плавающим значением (см. выше).

Допустим ситуация: необходимо стилизовать все ссылки на изображения. Можно писать несколько правил, занимающих много места, например:

a[href $=".JPG"],
a[href $=". JPEG"],
a[href $=".PNG"],
a[href $=".PNG"],
a[href $=".GIF"] {
	color: red;
}

А можно все это сократить до одного правила, но для этого у каждого элемента должен быть один и тот же атрибут: data-filetype="image". Например все ссылки в HTML имею этот атрибут:

<a href="path/to/file.jpg" data-filetype="image">Ссылка на изображение</a>

Тогда все ссылки на картинки можно выбрать так:

a[data-filetype="image"] { color: red; }
меню

X[href ^= "http"]

Селектор атрибутов со значением в начале. Выбирает элемент, атрибут которого начинается с указанного значения.

Следующий код показывает, как выбрать элементы а, ссылки в которых начинаются на «http»:

a[href^="http"] {
   background: url(path/to/external/icon.png) no-repeat;
   padding-left: 10px;
}

Это css-правило установит фоновую картинку только для "текст":

<a href="http://example.com">текст</a>
<a href="/article">текст 2</a>

Рекомендуется не добавлять к параметру вышеуказанного поиска дополнительных символом, так как искомая ссылка может начинаться с «https».

меню

X[href $= ". jpg"]

Селектор атрибутов со значением в конце. "$" - означает конец строки.

Например, выделим элементы, которые ссылаются на файлы определенного расширения. Следующий код выберет ссылки a, ссылающиеся на изображения формата .jpg:

a[href$=".jpg"] { color: red; }

Окрасит только "текст":

<a href="http://example.com/foto.jpg">текст</a>
<a href="http://example.com/foto2.png">текст 2</a>

X[foo ~= "bar"]

Селектор атрибутов с одним из значений разделенных пробелом.

Выбирает элемент у которого в значении атрибута foo есть bar. Он чем-то похож на *=, но если *= ищет указанную строку bar в любом месте значения атрибута, то ~= ищет указанную строку bar которая разделена пробелом. Т.е. bar может быть в начале, середине или конце, где бы он ни был он должен быть разделен пробелом от соседнего значения.

Например такой css код:

a[data-info ~= "external"] { color: red; }

a[data-info ~= "image"] { border: 1px solid black; }

Отработает так:

<a href="http://example.com" data-info="external">текст</a><!-- окрасит в красный -->

<a href="http://nettuts.com">текст 2</a><!-- не тронет -->

<a href="http://example.com" data-info="external image">текст 3</a><!-- окрасит и установит рамку -->

<a href="http://example.com" data-info="image">текст 4</a><!-- установит рамку -->

Об этом селекторе не многие знают, а ведь он иногда очень удобен.

меню

:target

Селектор псевдоклассов. Выделяет активный якорь в HTML. Допустим у нас ссылка ссылается на внутренний якорь <a href="#anchor"> на странице, тогда при клике по этой ссылке этот селектор выделить элемент имеющий атрибут id="anchor".

:target { color: red; }

Получим:

<a href="#anchor1">Перейти на якорь 1</a>
<a href="#anchor2">Перейти на якорь 2</a>

<!-- При клике по этим ссылкам выберется соответствующий элемент ниже -->

<p id="anchor1">Элемент 1</p>
<p id="anchor2">Элемент 2</p>

смотрите пример >

меню

X:checked

Селектор псевдоклассов. Стилизует включенные radio или checkbox. Обычно применяется для выделения текста. Может использоваться с input или option или просто без них: input:checked, option:checked или :checked.

Например, следующий код выделяет сплошной черной рамкой в 1px область возле включенного флажка:

input[type=radio]:checked { border:1px solid black; }

X::before

Селектор псевдоэлементов. Добавляет элемент в начало X (внутрь тега). Работает только совместно со свойством content, которое указывает содержание добавленного элемента. content нужно указывать даже если содержание пустое (content:''), т.к. элемент должен хоть что-то содержать.

Когда-то все браузеры реализовали эти псевдоэлементы с одним двоеточием: :after/:before.
Стандарт с тех пор изменился и сейчас все, кроме IE8, понимают также современную запись с двумя двоеточиями. А для IE8 нужно по-прежнему одно.

Например с помощью таких стилей, можно указать значок для LI списка:

li:before {
	content: '?';
	display: inline-block;
	margin-right: .5em;
}

Получим:

  • ? элемент 1
  • ? элемент 2
меню

X:after

Селектор псевдоэлементов. Добавляет элемент в конец X (внутрь тега). Работать только совместно со свойством content, которое указывает содержание добавленного элемента. content нужно указывать даже если содержание пустое (content:''), т.к. элемент должен хоть что-то содержать.

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

.clear:after {
	content: '';
	display: table;
	clear: both;
}

X:hover

Селектор псевдокласса. Срабатывает только при наведении мышки на элемент, когда курсор над элементом. Может применяться для любых элементов (div, span) не только ссылок <a>.

В следующем примере при наведении мышкой под ссылкой будет появляться черная линия толщиной 1px (замена свойству underline):

a:hover {  border-bottom: 1px solid black; }

А в следующем коде показано изменение цвета фона при наведении на элемент <div>:

div:hover { background: #e3e3e3; }

X:not(selector)

Селектор псевдокласса. Выбирает элементы, которые не содержат указанного селектора. Вместо "selector" может быть любой селектор, кроме псевдоэлементов (:first-letter). Двойное отрицание запрещено - :not(:not(...)).

Например, следующий код выбирает для стилизации все элементы, кроме элемента p:

*:not(p) { color: green; }

А в этом примере выбираются все элементы li, у которых нет класса .last:

ul li:not(.last) { color: blue; }

Выберет "элемент 1" и "элемент 2":

<ul>
	<li>элемент 1</li>
	<li>элемент 2</li>
	<li class="last">элемент 3</li>
</ul>
меню

X::first-line, X::first-letter

Селектор псевдоэлементов. ::first-line стилизует начальную строку.
::first-letter стилизует начальную букву. Изменяются только шрифт, цвет текста, фон, а также сильно привязан к множеству параметров: ширина окна браузера, язык, шрифт и т.п.

С CSS 2.1, для различия, принято псевдоэлементы помечать двойным двоеточием "::", а псевдоклассы одинарным ":".

Эти селекторы можно записывать с одним двоеточием :first-line, но двойное ::first-line предпочтительнее.

В следующих примерах показано, как использовать указанные псевдоэлементы:

#1 Выбираем первую букву в параграфе

p::first-letter {
	float: left;
	font-size: 2em;
	font-weight: bold;
	font-family: cursive;
	padding-right:2px;
}

Применит указанные стили для всех начальных букв всех абзацев в документе.

#2 Выбираем первую строку в абзаце

p::first-line {
	font-weight: bold;
	font-size: 1.2em;
}

Применит указанные стили для всех начальных строк всех абзацев в документе.

меню

X:nth-child(n)

Выбирает каждый "n-ый" элемент Х, который находится на одном уровне с X. Считает все элементы на уровне X, т.е. любой тип, а не только тип X.

Под типом подразумевается именно тег элемента (div, span, li), а не его класс или что-то еще...

Особенность: есть такой же селектор :nth-of-type(n) разница между ними в том, что X:nth-child(n) считает все элементы на одном уровне, не важно какой тип указан в Х, а Х:nth-of-type(n) считает только элементы типа Х находящиеся на одном уровне. Например:

<h1>Заголовок</h1>
<p>Первый параграф.</p><!-- p:nth-child(2) -->
<p>Второй параграф.</p><!-- p:nth-of-type(2) -->

"n" может быть:

  • odd (нечетные),
  • even (четные),
  • число (порядковый номер с 1)
  • и выражение (an+b, a и b целые числа, n — счетчик от 0).
  • смотреть на примере >

n - odd или even

Раскрасим четные и нечетные параграфы в разные цвета:

p:nth-child(odd) {
	background: red;
}
p:nth-child(even) {
	background: blue;
}

Получим:

<h1>Заголовок</h1>
<p>Первый параграф.</p><!-- blue -->
<p>Второй параграф.</p><!-- red -->
<p>Третий параграф.</p><!-- blue -->

n - число

Установит красным цветом второй элемент:

p:nth-child(2) { color: red; }

Окрасит "Второй параграф.":

<h1>Заголовок</h1>
<p>Первый параграф.</p><!-- red -->
<p>Второй параграф.</p>
<p>Третий параграф.</p>

n -  выражение

Формула выражения: an + b, где "a" - число, которое будет умножаться на n, "n" - счетчик от 0-999, "b" - число, отступ. { an + b; n = 0, 1, 2, ... }

  • в селекторе :nth-child(2) указана только "а".

  • :nth-child(odd) можно заменить на :nth-child(2n+1) - 1, 3, 5, 7 ...

  • :nth-child(even) можно заменить на :nth-child(2n) - 2, 4, 6, 8 ...

  • :nth-child(3n+4) - 4, 7, 10, 13 ...

  • :first-child можно заменить на :nth-child(0n+1) или :nth-child(1)

смотреть пример →

Например: обратимся к каждому третьему элементу на текущем уровне, где расположены p:

 p:nth-child(3n) { background: red; }

Получим:

<h1>Заголовок</h1>
<p>Параграф 1</p>
<p>Параграф 2</p><!-- background: red -->
<p>Параграф 3</p>
<p>Параграф 4</p>
<p>Параграф 5</p><!-- background: red -->
<p>Параграф 6</p>
<p>Параграф 7</p>
<p>Параграф 8</p><!-- background: red -->
<p>Параграф 9</p>
меню

X:nth-last-child(n)

Выбирает начиная с конца. Работает точно также как и предыдущий :nth-child(n) только отсчет идет не сверху, а снизу.

Также вместо n  может быть:

  • odd - нечетные
  • even - четные
  • число - порядковый номер с 1
  • выражение an+b, где a и b целые числа, n — счетчик от 0 до 999).

Например, следующий код установит красным цветом второй с конца параграф:

li:nth-last-child(2) { color: red; }

Окрасит "Второй параграф.":

<h1>Заголовок</h1>
<p>Первый параграф.</p>
<p>Второй параграф.</p><!-- red -->
<p>Третий параграф.</p>

Еще примеры смотрите в предыдущем селекторе :nth-child(n).

меню

X:nth-of-type(n)

Выбирает элемент по номеру указанному в "n". Начинает отсчет от первого элемента типа X находящегося на одном уровне.

Под типом подразумевается именно тег элемента (div, span, li), а не его класс...

Особенность: есть такой же селектор :nth-child(n) разница между ними в том, что X:nth-of-type(n) выберет только элементы типа Х находящиеся на одном уровне, а X:nth-child(n) считает все элементы всех типов на одном уровне, не важно какой тип указан в Х. Например:

<h1>Заголовок</h1>
<p>Первый параграф.</p><!-- p:nth-child(2) -->
<p>Второй параграф.</p><!-- p:nth-of-type(2) -->

"n" может быть:

  • odd - нечетные
  • even - четные
  • число - порядковый номер с 1
  • выражение an+b, где a и b целые числа, n — счетчик от 0 до 9999.

#1 n - add или even

Раскрасим четные и нечетные параграфы в разные цвета. Считает именно параграфы без h1, как это делает :nth-child:

p:nth-of-type(odd)  { background: red; }
p:nth-of-type(even) { background: blue; }

Получим:

<h1>Заголовок</h1>
<p>Первый параграф.</p><!-- red -->
<p>Второй параграф.</p><!-- blue -->
<p>Третий параграф.</p><!-- red -->

#2 n - число

Установит красным цветом второй элемент:

li:nth-of-type(2) { color: red; }

Окрасит "Второй параграф.":

<h1>Заголовок</h1>
<p>Первый параграф.</p>
<p>Второй параграф.</p><!-- red -->
<p>Третий параграф.</p>

#3 n -  выражение

Формула выражения: an + b, где "a" - число, которое будет умножаться на n, "n" - счетчик от 0-999, "b" - число, отступ. { an + b; n = 0, 1, 2, ... }

  • в селекторе :nth-of-type(2) указана только "а".

  • :nth-of-type(odd) можно заменить на :nth-of-type(2n+1) - 2, 4, 6, 8 ...

  • :nth-of-type(even) можно заменить на :nth-of-type(2n) - 1, 3, 5, 7 ...

  • :nth-of-type(3n+4) - 4, 7, 10, 13 ...

  • :first-of-type можно заменить на :nth-of-type(0n+1) или просто :nth-of-type(1)

Например: обратимся к каждому третьему элементу p на текущем уровне, где расположены p:

 p:nth-of-type(3n) { background: red; }

Получим:

<h1>Заголовок</h1>
<p>Параграф 1</p>
<p>Параграф 2</p>
<p>Параграф 3</p><!-- background: red -->
<p>Параграф 4</p>
<p>Параграф 5</p>
<p>Параграф 6</p><!-- background: red -->
<p>Параграф 7</p>
<p>Параграф 8</p>
<p>Параграф 9</p><!-- background: red -->
меню

X:nth-last-of-type(n)

Селектор псевдокласса. Выбирает элемент по номеру указанному в "n". Начинает отсчет от последнего элемента X находящегося на одном уровне.

Это такой же селектор как и предыдущий :nth-of-type(n) только считает наоборот, с конца.

Например: обратимся к каждому третьему элементу p с конца, на текущем уровне, где расположены p:

 p:nth-last-of-type(3n) { background: red; }

Получим:

<h1>Заголовок</h1>
<p>Параграф 1</p><!-- background: red -->
<p>Параграф 2</p>
<p>Параграф 3</p>
<p>Параграф 4</p><!-- background: red -->
<p>Параграф 5</p>
<p>Параграф 6</p>
<p>Параграф 7</p><!-- background: red -->
<p>Параграф 8</p>
<p>Параграф 9</p>

Еще примеры смотрите в предыдущем селекторе :nth-of-type(n).

меню

X:first-child

Селектор псевдокласса. Выбирает первый элемент который находится на одном уровне с Х. Отсчет начинается с любого элемента не обязательно Х.

X:first-child это тоже самое что X:nth-child(1)

#1 Пример: обратимся к первому элементу в блоке #container

#container div:first-child{ color:red; }

Получим:

<div id="container">
	<div>элемент 1</div><!-- color:red; -->
	<div>элемент 2</div>
</div>

А вот так не выделит ничего:

<div id="container">
	<h1>Заголовок</h1>
	<div>элемент 1</div><!-- не выделит -->
	<div>элемент 2</div>
</div>

#2 Обнуление границы

:first-child часто используется для обнуления свойства border на граничных элементах списка:

ul li:first-child { border-top: none; }

Такой код обнулит значение верхней границы элемента li, являющимся дочерним по отношению к элементу ul.

меню

X:last-child

Селектор псевдокласса. Выбирает первый с конца элемент который находится на одном уровне с Х. Отсчет начинается с любого элемента не обязательно X.

X:last-child это тоже самое что X:nth-last-child(1)

#1 Пример: обратимся к первому с конца элементу в блоке #container

 #container div:last-child{ color:red; }

Получим:

<div id="container">
	<div>элемент 1</div>
	<div>элемент 2</div><!-- color:red; -->
</div>

А вот так ничего не выделит:

<div id="container">
	<div>элемент 1</div>
	<div>элемент 2</div><!-- не выделит -->
	<p>параграф</p>
</div>

#2  Покрасим последний элемент li в списке ul в зеленый:

ul > li:last-child { color: green; }

Получим:

<ul>
	<li>список 1</li>
	<li>список 2</li>
	<li>список 3</li><!-- color: green; -->
</ul>
меню

X:first-of-type

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

X:first-of-type это тоже самое что X:nth-of-type(1)

#1 Пример: обратимся к первому элементу div в блоке #container

 #container div:first-of-type{ color:red; }

Получим:

<div id="container">
	<h1>Заголовок</h1>
	<div>элемент 1</div><!-- color:red; -->
	<div>элемент 2</div>
</div>

#2 Обнуление границы

:first-of-type часто используется для обнуления свойства border на граничных элементах списка:

ul li:first-of-type { border-top: none; }

Получим:

<ul>
	<span>текст</span>
	<li>элемент 1</li><!-- border-top: none; -->
    <li>элемент 2</li>
	<li>элемент 3</li>
</ul>
меню

X:only-child (если один элемент в блоке)

Селектор псевдокласса. Выбирает элемент X, который единственный на уровне X. При подсчете элементов название тега X НЕ учитывается.

Другими словами: выбирает дочерние элементы X только, когда у родителя количество всех дочерних элементов (неважно какой тип) равно 1.

Например, выберем элемент, если он единственный в блоке:

p:only-child { background: red; }

Получим:

<div>
	<p>параграф</p><!-- background: red; -->
</div>

<div>
	<span>параграф</span><!-- не выберет, потому что X=p а не span -->
</div>

<div>
	<p>текст</p><!-- не выберет, потому что на этом уровне 2 элемента -->
	<span>параграф</span>
</div>
меню

X:not(:only-child) (если больше чем один элемент в блоке)

Чтобы выбрать все элементы блока, только в том случае, если в этом блоке всего больше чем один элемент, используем :only-child с отрицанием :not():

li:not(:only-of-type) {
  font-size: 1.25em;
}

В результате если у нас один элемент он выбран не будет:

<ul>
	<li></li><!-- не будет выбран -->
</ul>

А если больше одного, то будут выбраны все:

<ul>
	<li></li><!-- будет выбран -->
	<li></li><!-- будет выбран -->
</ul>

X:only-of-type (если один элемент типа X в блоке)

Селектор псевдокласса. Выбирает элемент X, который единственный на уровне X (не имеет соседей). При подсчете элементов название тега X учитывается.

Другими словами: выбирает дочерние элементы X только, когда у родителя количество всех дочерних элементов типа X равно 1.

Например:

p:only-of-type { background: red; }

Получим:

<div>
	<p>параграф</p><!-- background: red; -->
</div>

<div>
	<span>параграф</span><!-- не выделится, потому что X=p а не span -->
</div>

<div>
	<span>параграф</span>
	<p>текст</p><!-- background: red; -->
</div>

#1 Выберем ul только с одним элементом в списке.

ul > li:only-of-type { font-weight: bold; }

Другой вариант: можно ul > li:only-child, потому что обычно в списках ul находятся только li теги.

меню

Немного практики

#1 Сложное выделение

У нас есть такой код:

<div>
	<p>параграф</p>
	<ul>
       <li>Список 1 </li>
       <li>Список 2 </li>
	</ul>

	<ul>
       <li>Список 3 </li>
       <li>Список 4 </li>
	</ul> 
</div>

Как обратиться к "Список 2"?

-

Решение 1

ul:first-of-type > li:nth-child(2) { font-weight: bold; }

Код находит первый список, затем находит его прямого наследника и у которого порядковый номер в списке равен 2.

Решение 2

Использование соседних селекторов.

p + ul li:last-child { font-weight: bold; }

Браузер находит ul, следующий сразу за p, затем находит его последний дочерний элемент.

Решение 3

Это решение пожалуй самое правильное, потому что если между ul или li попадут другие теги, этот пример все равно будет выбирать нужный нам li:

ul:first-of-type li:nth-last-of-type(1) { font-weight: bold; }

Браузер выбирает первый ul (именно ul), затем находит первый с конца элемент li (именно li).

меню

Наглядное пособие по селекторам типа :nth-child

Чтобы быстро и точно понять как работают псевдо-селекторы типа :first-child. Я создал спец. страницу. Там же можно подобрать нужный для себя селектор этого типа, под конкретную задачу.

Смотреть «Наглядное пособие»

Считаем элементы в блоке с помощью nth-child

Полезная статья на Хабре - количественные CSS селекторы, учит считать элементы с помощью nth-child. Например, нужно выделить первый элемент, только, если в блоке 6 элементов указанного типа. Или, нужно выделить все элементы блока, если в блоке всего 6 элементов.

Диапазон элементов в селекторе

Допустим, у вас есть список из 20 элементов и нужно выбрать элементы с 7 по 14 включительно. Это можно сделать вот так:

ol li:nth-child(n+7):nth-child(-n+14) {
  background: lightpink;
}

Видео на десерт: CSS селекторы

24 коммента
Полезные 4 Все