CSS-селекторы на каждый день
Итак, селектор - это формальное описание того элемента или группы элементов, к которым применяется указанное правило стиля. Простой селектор представляет собой селектор типа, селектор класса либо id-селектор, за которым могут следовать селекторы псевдоклассов и селекторы атрибутов (о последних в данном кратком описании умолчим). Селектор - это последовательность простых селекторов, разделенных пробелами либо символами ">" и "+" . Указанные разделители имеют практичный смысл при создании сайтов и разработаны для удобства.
Несмотря на то, что многие из упомянутых здесь селекторов входят в спецификацию CSS3 и, соответственно, поддерживаются только современными браузерами, Вам все же следует ознакомиться с ними и держать их в памяти, так как они очень практично-удобные.
Виды селекторов
Селектор тегов, в качестве селектора выступает имя тега, для которого необходимо изменить свойства.
Универсальный селектор, который обозначается символом * и применяется для изменения необходимых свойств всех элементов на странице.
Классы, применяются для элементов с атрибутом class и необходимым значением.
Идентификаторы, применяются для элементов с атрибутом id и необходимым значением. Основное отличие классов от идентификаторов состоит в том, что имена вторых должны быть уникальными, не повторяться, что позволяет их использовать вместе со скриптами (JavaScript).
Псевдо-классы предназначены для изменения стиля существующих элементов страницы в зависимости от их динамического состояния, например при работе со ссылками (:link, :visited, :hover, :active, :focus). Псевдо-элементы определяют стиль элементов, чётко не определённых в структуре документа (:first-letter, :first-line), а также позволяют генерировать и стилизовать несуществующее содержимое (:before, :after и свойство content). В CSS3 псевдо-элементы начинаются с двух двоеточий :: (::first-letter, ::first-line, ::before, ::after).
Селекторы атрибутов. Позволяют стилизовать элемент не только по значению тега, но и по значению атрибута (a[attr]).
Контекстные селекторы. Стилизация элементов, находящихся внутри другого элемента (a b).
Дочерние селекторы. Стилизация элемента, расположенного сразу за другим элементом и являющегося его прямым потомком (a > b).
Соседние селекторы. Предназначены для стилизации соседних элементов, у которых общий родитель. (a + b)
Родственные селекторы. Похожи с соседними селекторами, но с тем различием, что стилизуются все соседние элементы, а не только первый соседний элемент. Впервые появились в CSS3. (a ~ b).
Итак, приступим!
*
* { margin: 0; padding: 0; }
Начнем с простейших вещей для новичков, прежде чем перейдем к продвинутым селекторам.
Символ звездочки позволяет выбрать все элементы на странице. Многие веб-разработчики используют это для "обнуления" всех внешних и внутренних отступов.
Также символ * можно использовать для дочерних элементов объекта.
#container * { border: 1px solid black; }
Этот код нацелен на все элементы, которые являются дочерними по отношению к блоку с идентификатором container.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
6.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
#X
#container { width: 960px; margin: auto; }
Символ решетки позволяет нам отбирать элементы по идентификатору. Это один из наиболее распространенных способов отбора элементов, однако будьте осторожны при его использовании.
"Спросите себя: Мне точно необходимо использовать id для какого-то элемента, чтобы сослаться на него?"
Селекторы id негибки и их трудно использовать повторно в разных проектах. Если возможно, пытайтесь сначала использовать имя тэга или даже псевдо-класс.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
6.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
.X
.error { color: red; }
Это селектор класса. Разница между id и классами в том, что с помощью классов можно выбирать сразу несколько элементов. Используйте классы, если Вам нужно применить один стиль к группе элементов.
В противном случае используйте id для нахождения "иголки в стоге сена" и применения стиля только к одному конкретному объекту.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
6.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X Y
li a { text-decoration: none; }
Следующий часто используемый тип селектора - селектор потомка. Его следует использовать, когда нужно производить более точечный отбор элементов.
К примеру, как быть, если нужно выбрать не все тэги ссылок, а только те, что находятся внутри неупорядоченного списка? Это как раз тот случай, когда следует использовать селектор потомка.
"Совет: Если Ваш селектор похож на X Y Z A B.error, то Вы, вероятно, что-то делаете на так. Всегда спрашивайте себя, действительно ли это самый простой способ"
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
6.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X
a {color: red;} ul {margin-left: 0px;}
Что, если Вы хотите сослать на все элементы определенного типа на странице, если у них нет id или классов? Делайте проще, используйте селекторы типа. Если Вам нужно выбрать все неупорядоченные списки, используйте ul{}.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
6.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:visited и X:link
a:link {color: red;} a:visited {color: purple;}
Здесь мы используем псевдо-класс :link для выбора всех ссылок, на которых еще не был совершен клик.
Также есть псевдо-класс :visited, который, как Вы и ожидали, позволяет нам применить стиль только к тем ссылкам, по которым был совершен клик или переход.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X + Y
ul + p { color: red; }
Это так называемый смежный селектор. В этом случае каждый параграф следующий сразу после каждого элемента ul будет красного цвета.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X > Y
#container > ul { border: 1px solid black; }
Различие между X Y и X > Y в том, что последний выберет только прямых потомков. Рассмотрим следующий пример:
<div id="container"> <ul> <li>Элемент списка <ul> <li>Потомок</li> </ul> </li> <li>Элемент списка</li> <li>Элемент списка</li> <li>Элемент списка</li> </ul> </div>
Селектор #container > ul выберет только те элементы ul, которые являются прямыми потомками блока div с идентификатором container. Т.е. в данном случае этот селектор не отберет элемент ul, который является потомком первого элемента li.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X ~ Y
ul ~ p { color: red; }
Эта комбинация сестринских (сиблинговых) элементов похожа на X + Y, но она менее строгая. Если в случае ul + p будут выбраны только первые элементы p, следующие за ul (т.е. наблюдается смежность в выборе), то рассматриваемый нами сейчас селектор более общий.
В нашем случае он отберет все элементы p, следующие за элементом ul.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X[title]
a[title] { color: green; }
Здесь мы обращаемся к атрибуту селектора. В нашем примере будут окрашены в зеленый цвет только ссылки, имеющие атрибут title.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X[href="foo"]
a[href="http://www.codeharmony.ru"] { color: red; }
Код выше позволит придать стиль всем ссылкам, атрибут href у которых равен http://www.codeharmony.ru. Эти ссылки будут красного цвета. Остальные ссылки не получат данного стиля.
Это работает хорошо, но это немного негибко. Что, если ссылка на самом деле ведет на Codeharmony.ru но, возможно, адрес указан, как codeharmony.ru а не http://www.codeharmony.ru? В таких случаях мы можем использовать основы регулярных выражений.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X[href*="codeharmony"]
a[href*="codeharmony"] { color: red; }
Поехали дальше; это как раз то, что нам нужно. Звездочка означает, что искомое значение может находиться в любой части атрибута href. Таким образом, мы можем отобрать и http://www.codeharmony.ru и www.codeharmony.ru и codeharmony.ru.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X[href^="http"]
a[href^="http"] { background: url(path/to/external/icon.png) no-repeat; padding-left: 10px; }
Вы когда-нибудь думали о том, как на некоторых сайтах рядом с ссылками, ведущими на другие сайты (внешние по отношению к текущему) проставлены небольшие иконки, которые дают знать об этом пользователю? Это отличные "напоминалки" пользователю о том, что ссылка ведет на другой сайт.
Делается это с помощью символа ^ (карат). Он обычно используется в регулярных выражениях для обозначения начала строки. Если мы хотим отобрать ссылки, у которых атрибут href начинается с http, то мы можем использовать селектор из примера выше.
"Обратите внимание, что мы не ищем http://. Это необязательно и, к тому же, не учитывает ссылки по протоколу https://."
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X[href$=".jpg"]
a[href$=".jpg"] { color: red; }
И снова мы используем регулярное выражение и символ $ для того, чтобы обозначить конец строки. В данном примере мы ищем все ссылки, которые ссылаются на картинки с расширением .jpg. Разумеется, такой подход не будет работать для картинок с расширениями .gif, .png и т.д.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X[data-*="foo"]
a[data-filetype="image"] { color: red; }
Как же мы можем охватить различные типы картинок? Мы можем создать, например, несколько селекторов:
a[href$=".jpg"], a[href$=".jpeg"], a[href$=".png"], a[href$=".gif"] { color: red; }
Но это муторно и не элегантно. Другой вариант - это создать собственный атрибут data-filetype и добавить его к каждой ссылке, ведущей на картинку.
<a href="path/to/image.jpg" data-filetype="image">Ссылка</a>
Поступив таким образом, мы можем использовать код данного примера:
a[data-filetype="image"] { color: red; }
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X[foo~="bar"]
a[data-info~="external"] { color: red; } a[data-info~="image"] { border: 1px solid black; }
Вот еще один интересный трюк, о котором не все знают. Знак ~ (тильда) позволяет нам выбирать атрибуты со значениями, разделенными пробелами, т.е.
<a href="path/to/image.jpg" data-info="external image">Кликни сюда</a>
Используя данный прием мы можем делать выборки с нужными нам комбинациями:
/* Отобрать атрибут data-info, который содержит значение external */ a[data-info~="external"] { color: red; } /* и отобрать атрибут data-info, который содержит значение image */ a[data-info~="image"] { border: 1px solid black; }
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:checked
input[type=radio]:checked { border: 1px solid black; }
Этот псевдо-класс отбирает те элементы, которые были отмечены, например, радиокнопку или чекбокс.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:after
.clearfix:after { content: ""; display: block; clear: both; visibility: hidden; font-size: 0; height: 0; } .clearfix { *display: inline-block; _height: 1%; }
Данный псевдо-класс позволяет сгенерировать контент вокруг выбранного элемента.
Данный пример показывает, как с помощью псевдо-класса :after после блока с классом .clearfix создаётся пустая строка, после чего очищается. Хороший метод, когда невозможно применить overflow: hidden.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
8.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:hover
div:hover { background: #e3e3e3; }
Это Вы точно знаете. Официальное название звучит вроде "псевдо-класс, основанный на действии пользователя". Звучит страшновато, хотя на деле все просто. Хотите применить к элементу определенный стиль, когда на него наводится курсор мыши? Это оно самое!
"Помните, что старые версии IE не понимают этого псевдо-класса по отношению к чему-бы то ни было, кроме тэга а."
Часто данный прием используется для задания нижней границы для ссылок при наведении на них курсора:
a:hover { border-bottom: 1px solid black; }
"Мега-чит: border-bottom: 1px solid black; выглядит лучше, чем text-decoration: underline;"
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
6.0+ (в IE6 работает только по отношению к ссылкам) | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:not(selector)
div:not(#container) { color: blue; }
Отрицание может быть также очень полезным. Предположим, я хочу выбрать все блоки div, кроме одного с идентификатором container. Для этого отлично подойдет код с отрицанием (не равно).
Если же мне нужно выбрать все элементы, кроме тэгов параграфов, то можно написать так:
*:not(p) { color: green; }
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X::pseudoElement
p::first-line { font-weight: bold; font-size: 1.2em; }
Псевдоэлементы можно использовать для придания стилей фрагменту элемента, например, первой строке или первой букве. Применяется только к блочным элементам.
Выбираем первую букву параграфа:
p::first-letter { float: left; font-size: 2em; font-weight: bold; font-family: cursive; padding-right: 2px; }
Этот кусок кода найдет все параграфы на странице и применит к первой букве каждого из них указанные стили. Часто это используется для создания эффекта "газетного заголовка".
Выбираем первую строку параграфа:
p::first-line { font-weight: bold; font-size: 1.2em; }
Аналогично предыдущему примеру, но в данном случае будет выбрана первая строка каждого параграфа.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
6.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:nth-child(n)
li:nth-child(3) { color: red; }
Помните времена, когда мы не имели возможности обратиться к конкретному порядковому элементу-потомку? Данный псевдо-класс решает эту проблему!
В качестве параметра принимается целое число. Если нужно выбрать 2-й элемент списка, нужно использовать конструкцию: li:nth-child(2).
Мы можем даже выбирать группы элементов-потомков. К примеру, чтобы выбрать каждый четвертый элемент списка, нужно использовать конструкцию: li:nth-child(4n).
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:nth-last-child(n)
li:nth-last-child(2) { color: red; }
Что, если у Вас есть большой неупорядоченный список и Вам нужно, к примеру, выбрать третий элемент с конца. Вместо того, чтобы писать li:nth-child(397), Вы можете воспользоваться псевдо-классом nth-last-child.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:nth-of-type(n)
ul:nth-of-type(3) { border: 1px solid black; }
Иногда бывают ситуации, когда вместо того, чтобы выбирать определенных потомков, нужно сделать выбор по типу элемента.
Представьте, что на странице есть пять неупорядоченных списков. Если Вам нужно применить стили только к третьему списку, но у него нет уникального идентификатора и иных "зацепок", то можно воспользоваться псевдо-классом nth-of-type(n). В коде выше показан способ придания стиля только третьему неупорядоченному списку.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:nth-last-of-type(n)
ul:nth-last-of-type(3) { border: 1px solid black; }
Да, для полноты картины есть и такой вариант. Так можно выбрать n-ный элемент определенного типа с конца.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:first-child
ul li:first-child { border-top: none; }
Этот псевдо-класс позволяет выбрать только первого потомка родительского элемента. Часто используется для удаления границ первого и последнего элементов списка.
К примеру, если у вас есть список рядов, каждый из которых имеет border-top и border-bottom, то последний и первый элементы списка будут немного выбиваться из общего строя.
Для устранения этого недостатка можно использовать данный псевдо-класс.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
7.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:last-child
ul > li:last-child { color: green; }
В противоположность классу first-child, last-child выберет последний элемент родительского элемента.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:only-child
div p:only-child { color: red; }
Честно говоря, это довольно редко используемый псевдо-класс, но, тем не менее, он тоже бывает полезен. Он позволяет выбрать Вам те элементы, которые являются единственными потомками для своих родителей.
В нашем примере стиль будет применен только к параграфу, который является единственным потомком блока div.
Давайте рассмотрим для наглядности такую разметку:
<div><p>Здесь идет единственный в блоке параграф.</p></div> <div> <p>Здесь идет первый параграф в блоке.</p> <p>Здесь идет второй параграф в блоке.</p> </div>
В этом случае параграфы во втором блоке div выбраны не будут. Стиль будет применен только к параграфу из первого блока div.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:only-of-type
li:only-of-type { font-weight: bold; }
Этот псевдо-класс выбирает элементы, которые не имеют сестринских элементов в содержащем их контейнере. Например, давайте выберем все ul, которые содержат одинокие li.
Вы могли бы написать ul li, но этот способ выберет все элементы li. Единственный способ - использовать only-of-type.
ul > li:only-of-type { font-weight: bold; }
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
X:first-of-type
Этот псевдо-класс позволяет отобрать первого сиблинга того же типа.
Чтобы лучше это понять, скопируйте в свой редактор следующий код:
<div> <p>Здесь параграф.</p> <ul> <li>Элемент 1.</li> <li>Элемент 2.</li> </ul> <ul> <li>Элемент 3.</li> <li>Элемент 4.</li> </ul> </div>
Сейчас, не читая дальше, попробуйте придать стиль только "элементу 2". Когда догадаетесь (либо сдадитесь), читайте дальше.
Решение 1
Есть много способов решить данную задачу. Рассмотри лишь некоторые из них. Начнем с использования first-of-type:
ul:first-of-type > li:nth-child(2) { font-weight: bold; }
Данный код гласит: "Найди первый неупорядоченный список на странице, затем найди только его прямых потомков, являющихся элементами li. После этого выбери только второй по порядку элемент li."
Решение 2
Другой вариант - воспользоваться смежным селектором:
p + ul li:last-child { font-weight: bold; }
Здесь мы находим ul, следующий непосредственно за тэгом параграфа, после чего находим самый последний его дочерний элемент.
Решение 3
Можно еще немного поиграть с селекторами и поступить таким образом:
ul:first-of-type li:nth-last-child(1) { font-weight: bold; }
Сейчас мы уже получаем первый элемент ul на странице, затем ищем самый первый элемент li, но начиная с конца.
Internet Explorer | Chrome | Opera | Safari | Firefox | Android | iOS |
---|---|---|---|---|---|---|
9.0+ | 1.0+ | 3.5+ | 1.0+ | 1.0+ | 1.0+ | 1.0+ |
Вывод
Если Вы все еще пишете код, принимая во внимание существование IE6, то Вам нужно быть предельно осторожным при использовании новых селекторов. Но не делайте из этого оправдания, не говорите, что Вам это не нужно знать - этим Вы осложните жизнь самому себе.
Если Вы работаете с какими-либо JavaScript-библиотеками, например, с jQuery, то всегда старайтесь использовать "родные" CSS3 селекторы, когда это возможно. В этом случае Ваш код будет работать быстрее.
Via codeharmony.ru
Created/Updated: 25.05.2018