Что такое селекторы
Селектор (от английского select - выбирать) представляет из себя механизм "выбора" элементов на странице при помощи специальных языковых конструкций. По сути этот механизм определяет к каким html элементам будут применены те или иные css стили (или подвешены js-обработчики).
В общем виде все css стили представляют из себя селекторы и набор свойств заключенных в фигурные скобки:
селектор {
свойство-css: значение;
свойство-css: значение;
свойство-css: значение;
}
Например:
h1 {
font-size: 20px;
font-weight: bold;
line-height: 1.5;
margin: 10px 0px;
}
В данном примере, мы обращаемся (выбираем) все теги
h1
на странице и назначаем им стиль, размер и начертание шрифта (
font-size: 20px; font-weight: bold;
), высоту строки (
line-height: 1.5;
) и внешний отступ (
margin: 10px 0px;
).
По средствам селектором мы можем выбирать группы тегов, отдельные элементы, дочерние элементы тегов, чётные, нечётные, каждый третий (или любой другой элемент) в коллекции. Давайте рассмотрим базовые селекторы детальнее.
Базовые селекторы
Селектор по типу элемента (тегу)
Предназначен для выбора всех элементов страницы по имени тега. Например можно задать всем заголовкам H1 размер шрифта и отступы:
/*для всех заголовков первого уровня*/
h1 {
font-size: 30px;
margin: 15px 0px;
}
Такие правила применяются, когда нам нужно задать внешний вид базовых элементов, заголовков, параграфов, нумерованных и не нумерованных списков, таблиц и т.д.
Селектор по классу
Предназначен для выбора элементов по имени класса (значению атрибута тега
class
).
/* задаём внешний вид для всех тегов с классом alert */
.alert {
color: red;
display: inline-blcok;
padding: 10px;
border:1px solid #000;
}
Селектор по идентификатору
Если вам нужно назначить css правила одному конкретному элементу используется селектор по идентификатору (атрибут id="" тегов), пример:
/* для элемента с id="contact_form" */
#contact_form {
padding: 10px;
font-size: 1em;
}
Универсальный селектор
Часто для сброса базовых стилей html элементов, используется универсальный селектор
/* задаём цвет шрифтов на всём сайте */
* {
font-color: #000;
}
Селекторы по атрибуту
Помимо классов и идентификаторов (которые используются в подавляющем большинстве случаев), вы так же можете обратиться по менее распространённым атрибутам и их значениям.
Для этого используется следующий синтаксист:
[attr]
– по имени атрибута;
-
[attr=value]
– по имени и значению атрибута;
-
[attr^=value]
– по имени и значению, с которого оно должно начинаться;
-
[attr|=value]
– по имени атрибута и его значению, которое равно value
или начинается со value-
;
-
[attr$=value]
– по имени атрибута и значению, на которое оно должно заканчиваться;
-
[attr*=value]
– по указанному атрибуту и значению, которое должно содержать value
;
-
[attr~=value]
– по имени атрибута и значению, которое содержит value отделённое от других с помощью пробела.
Примеры использования
Допустим мы можем подсветить все ссылки содержащие атрибут
target
.
[target] {
color: red;
}
Либо можно выделить ссылки ведущие с сайта на другие ресурсы, например внешнюю документацию.
[target="_blank"] {
color: red;
}
Подсветим ссылки содержащие в атрибуте
href
безопасный протокол
https
, если быть точным, ссылка начинается с
https
[href^="https"] {
color: red;
font-weight: bold;
}
Либо, можно выделить ссылки в
href
которых есть подстрока (где-то в середине).
[href*="youtu.be"] {
background-color: green;
}
Такими селекторами в первую очередь удобно пользоваться для подсветки каких-то элементов в текстах статей, редактируемых контентщиками, которые в свою очередь могут не разбираться в html. Т.е. они просто размещают контент, а вы за счёт совпадений в атрибутах тегов, можете выделить эти элементы на странице.
Псевдоклассы
Псевдоклассы элементов на странице позволяют нам выбирать элемент в зависимости от его состояния. Например, наводя курсор мыши на кнопку, последняя получает псевдокласс
:hover
, и вы можете задать кнопке отличный внешний вид, чтобы пользователю было легче понять, что он навёл курсор на некий активный элемент с которым можно взаимодействовать.
В общем виде, синтаксис выглядит следующим образом:
/*обычный класс описывающий цвет ссылки в меню*/
.menu a {
color: green;
}
/*класс с псевдоклассом :hover, состояние элемента
при наведении на него курсора мышки*/
.menu a:hover {
color: red; /*при наведении поменяется цвет ссылки на красный*/
}
Псевдоклассы так же присутствуют у элементов формы. Например заблокированное поле формы имеет псевдокласс
:disabled
используя который, можно например сделать поле формы полупрозрачным, чтобы визуально дать понять что с этим полем нельзя взаимодействовать в данный момент.
Для групп элементов, например списков (точнее элементов списков) часто применяют псевдоклассы, показывающие положение элемента в коллекции. Такой псевдокласс как
:first-child
позволит вам обратиться к первому элементу списка и задать ему отличный от остальных стиль. Давайте разберёмся детальнее.
Псевдоклассы для выбора элементов по состоянию
К данной группе псевдоклассов относятся следующие:
:link
,
:visited
,
:hover
,
:active
и
:focus
.
Псевдоклассы
:link
и
:visited
работают только у ссылок (тег
<a href="...">ссылка</a>
).
Псевдоклассы
:hover
,
:focus
и
:active
могут применяться не только к ссылкам, но и к другим элементам, например кнопкам, картинкам, спискам, полям формы и т.д.
Псевдокласс :link
Псевдокласс
:link
предназначен для выбора ссылок, которые не успел посетить пользователь. В данном примере, подсветим синим цветом ссылки с классом
wiki
(документация), по которым пользователь ещё не успел перейти.
a.wiki:link {
color: blue;
}
Псевдокласс :visited
Этот псевдокласс наоборот позволяет выделить уже посещённые ссылки. Так например можно визуально показать пользователю какие разделы документации или книги рецептов он успел посомотреть, а что осталось не прочитанным.
a.wiki:visited {
color: red;
}
Псевдокласс :hover
Пожалуй один из наиболее частых псевдоклассов с которыми вы будете сталкиваться на практике. В подавляющем большинстве случаев именно на его основе строятся визуальные эффекты взаимодействия с сайтом, делая сайт более «живым». Этот псевдокласс начинает работать тогда, когда пользователь наводит курсор мыши на элемент. Будь то ссылка, картинка, пункт списка или поле формы, везьде сработает псевдокласс
:hover
вы даже можете прикрутить анимационные эффекты используя этот псевдокласс.
/*исходный класс кнопки*/
.btn {
display: block;
transition: 0.3s; /*анимация, смена фона будет плавной*/
background-color: #00B6BD;
}
/*Меняем цвет фона, при наведении курсора на кнопку*/
.btn:hover {
background-color: #F5F4EF;
}
Псевдокласс :active
Этот псевдокласс срабатывает когда пользователь сайта «активирует» элемент, нажимает на ссылку или кнопку. Т.е. в момент клика левой кнопкой мышки, от момента нажатия кнопки, до момента когда кнопку отпустили. В основном этот класс как и
hover
используется для подсветки ссылок и кнопок, но при необходимости может быть применён и к другим элементам.
/*Стиль кнопки в момент нажатия*/
.btn:active {
background-color: red;
color: white;
}
Псевдокласс :focus
Псевдокласс focus срабатывает тогда, когда элемент получает фокус, например при клике мышки в поле формы.
.form input[type="text"]:focus {
background-color: #8BB100
}
Псевдоклассы по расположению в коллекции (относительно соседей)
При выборе элемента, используя специальные псевдоклассы вы можете дополнительно задать условия выбора этого элемента по их расположению (порядковому номеру) внутри коллекции.
Для этого используются следующие псевдоклассы:
:first-child
,
:last-child
,
:only-child
,
:nth-child(выражение)
,
:nth-last-child(выражение)
. Где выражение представляет собой число, математическую формулу или зарезервированное ключевое слово.
Псевдокласс :first-child
Предназначен для выбора первого дочернего элемента родителя. Например можно подсветить первый пункт меню так:
.menu li:first-child {
font-weight: bold;
color: red;
}
Псевдокласс :last-child
Предназначен для выбора последнего элемента в коллекции.
.menu li:last-child {
font-weight: bold;
color: red;
}
Псевдокласс :only-child
Этот псевдокласс выберет элементы только если они являются единственными дочерними элементами родителя.
span:only-child {
color: red;
}
Пример html
<div>
<span>Этот span единственный дочерни элемент</span>
</div>
<div>
<span>Этот span один из потомков родителя</span>
<span>Этот span один из потомков родителя</span>
</div>
В этом примере красным цветом будет подсвечен первый
span
, т.к. он является единственным дочерним элементом своего родительского
div
.
Псевдокласс :nth-child(выражение)
Один из часто используемых псевдоклассов :nth-child(выражение), позволяет задавать условие выбора дочернего элемента по его порядковому номеру в коллекции (внутри родителя). В качестве выражения как уже было указано выше, можно передать число (порядковый номер элемента), формулу или ключевое слово (чётные/нечётные).
/* выбрать второй элемент li в родителе*/
.li:nth-child(2) { ... }
/* выбрать нечётные элементы родителя 1, 3, 5 и т.д. */
.li:nth-child(odd) { ... }
/* выбрать чётные элементы родителя */
.li:nth-child(even) { ... }
/* выбор элемента по формуле, в данном примере будут выбраны элементы под номером 1, 3, 5, 7, ... внутри родителя */
.li:nth-child(2n+1) { ... }
Выбор по формуле, самый интересны. Давайте разберёмся как она работает. Формула имеет следующую запись:
Xn + Y
.
X
и
Y
- это числа, а
n
— счетчик, принимающий целые значения, начиная с 0 (т.е. 0, 1, 2, 3 ...). Например, формула вида
3n + 2
будет определять элементы с порядковыми номерами (2, 5, 8, ...). Таким образом 3 умножить на 0 плюс 2 равно 2, 3 умножить на 1 плюс 2 равно 5, 3 умножить на 2 плюс 2 равно 8 и т.д.
Псевдокласс :nth-last-child(выражение)
Псевдокласс
:nth-last-child()
выполняет те же действия что и
:nth-child()
за исключением того, что отсчет элементов в родителе ведётся не с начала, а с конца (т.е. в форму в счётчи n будет подставляться не 0 а число, равное числу элементов в родителя минус 1). В псведоклассе
:nth-last-child(выражение)
в качестве выражения можно использовать те же вещи, т.е. число, формулу, или ключевые слова
odd
или
even
Для лучшего восприятия того как работает псевдокласс по порядковому номеру элемента, воспользуйтесь такой шпаргалкой:
Псевдоклассы элементов форм
К этой группе псевдоклассов можно отнести следующие
:enabled
,
:disabled
и
:checked
.
Псевдоклассы этой группы, а также
:hover
,
:active
и
:focus
ещё называют событийными селекторами, т.к. они позволяют применить стили при наступлении определённых событий (клик мышкой, выделение поля формы, выбор chekbox-а в форме и т.д.).
Псевдокласс :enabled
Этот псевдокласс предназначен для выбора включенных элементов формы (элементов где нет атрибута
disabled
), с которыми пользователь может взаимодействовать, например внести текст или выбрать флажок.
/*задаём зелёный цвет фона всем включённым полям формы*/
input:enabled {
background-color: #CBDC00;
}
Псевдокласс :disabled
Если у элемента формы всё же установлен атрибут disabled и с ним нельзя взаимодействовать пользователю, выбрать и задать css стиль таким элементам можно при помощи данного псевдокласса.
input:disabled {
border: 1px solid red;
}
Псевдокласс :checked
Этот псевдокласс нужен для выбора элементов radio, checkbox и option внутри select, которые находятся в выбранном состоянии (отмечен флаг checkbox или выбран пункт в select).
input:checked {
border: 1px solid red;
}
При помощи этого псевдокласса можно так же повлиять на соседние элементы. Например изменить внешний вид заголовка
label
около выбранного
checkbox
.
input:checked + label {
background-color: green;
}
Группировка
Для задания правил нескольким селекторам одновременно их необходимо перечислить через запятую
h3, h4, h5 {
font-size: 20px;
margin-top: 15px;
margin-bottom: 10px;
colot: #000;
}
В примере выше, мы задаём стиль для заголовков
h3
,
h4
а также
h5
. В перечислении можно использовать все возможные селекторы, например.
h3, .title, #contact_form_title {
font-size: 20px;
margin-top: 15px;
margin-bottom: 10px;
colot: #000;
}
В приведённом примере мы задаём стиль для всех заголовков
h3
(т.е. всех тегов
<h3>...</h3>
), для всех элементов содержащих класс
title
, а так же конкретному заголовку с
id="contact_form_title"
. Это позволяет нам выделять общие для нескольких групп элементов стили, и засовывать их в один класс (одни фигурные скобки), а отличия в отдельные классы.
Отношения селекторов
В HTML документе каждый элемент (узел) всегда связан с другими элементами, весь документ представляет так называемое DOM (Document Object Model) дерево, выстроенную иерархию элементов, которую интерпретирует ваш браузер и
мы видим различные графические элементы или форматированный текс.
В рамках DOM дерева можно выделить несколько отношений между его узлами:
- родитель – элемент, непосредственно в котором находится текущий элемент;
- предок – это элемент, который расположен на одном из уровней иерархии элементов, до которого можно дойти двигаясь от текущего элемента к его родителю, и дальше вверх по иерархии.
- дети – это элементы, непосредственно расположенные в текущем рассматриваемом элементе (грубо говоря на 1-м уровне вложенности );
- потомки (дочерние элементы) – это любые элементы, которые находятся в текущем элементе вне зависимости от уровня иерархии, в котором они расположены;
- соседи (сиблинги) – это элементы, расположенные на том же уровне вложенности (иерархии), что и текущий элемент (все элементы у которых тот же родитель что и у текущего);
В представленном ниже примере, комментариями помечены элементы относительно рассматриваемого контейнера с классом
gallary-row
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body><!--Предок gallary-row-->
<div class="container"><!-- родитель gallary-row -->
<div class="row gallary-row"> <!-- gallary-row текущий рассматриваемый элемент-->
<div class="col-4"><!-- дети gallary-row (они так же являются потомками)-->
<img src="/img.jpg" alt=""><!--потомки gallary-row -->
<a href="#">More</a><!--потомки gallary-row -->
</div>
<div class="col-4"><!-- дети gallary-row -->
<img src="/img.jpg" alt=""><!--потомки gallary-row -->
<a href="#">More</a><!--потомки gallary-row -->
</div>
<div class="col-4"><!-- дети gallary-row -->
<img src="/img.jpg" alt=""><!--потомки gallary-row -->
<a href="#">More</a><!--потомки gallary-row -->
</div>
</div>
<div class="row"><!--сосед gallary-row -->
<div class="col-12">
<h1>Header</h1>
</div>
</div>
</div>
</body>
</html>
Приоритет выбора стилей
При работе с CSS вы можете столкнуться с ситуацией когда указанный вами стиль почему-то не влияет на элемент, хотя сам стиль написан безукоризненно. Скорее всего, где-то в таблице стилей уже есть селектор, который описывает внешний вид этого элемента и в котором уже задаются те свойства, которые вы пытаетесь настроить в данный момент. Возможно этот селектор был создан вами ранее или вы вносите изменения в уже готовый проект, не важно.
Проблема заключается в том, что в CSS есть правило расстановки приоритетов, по которым к тому или иному элементу применяются стили. Эти приоритеты можно описать такой таблицей:
Вид селектора
|
Числовой вес
|
Универсальный селектор *
|
0 баллов
|
Селектор по типу элемента, например span
|
1 балл
|
Селектор по классу, например .class
|
10 баллов
|
Селектор по ID, например #contact_form
|
100 баллов
|
inline-стиль элемента, style="border: 1px solid black;"
|
1000 баллов
|
Пример:
<div class="container" id="main_container">Некий контейнер с текстом</div>
Например для этого контейнера несколько стилей используя разные селекторы.
div {
background-color: #CCC;
}
#main_container {
background-color: #41A4F4;
}
.container {
background-color: #CBDC00;
}
Ориентируясь по таблице, не сложно понять что к контейнеру примениться 2-й стиль, с селектором по ID элемента т.к. он имеет большее количество баллов и следовательно выше приоритет.
Баллы имеют свойство складываться, поэтому в описанном ниже стиле будет применён
div.container
т.к. селектор по типу элемента 1 балл + селектор по классу
.container
10 баллов итого 11, больше чем просто селектор по классу
.container
.
div.container {
background-color: #CCC;
}
.container {
background-color: #CBDC00;
}
Но есть ещё один антипаттерн, который лучше не использовать вовсе, но если уж совсем приспичит, то можно. Есть ключевое слово !important которое ставиться непосредственно свойство. Оно делает приоритет применимости этого свойства выше остальных и в случае таких стилей:
div.container {
background-color: #CCC;
}
.container {
background-color: #CBDC00!important;
}
Сработает цвет фона из второго стиля, не смотря на то, что его приоритет ниже (10 меньше 11) чем у первого стиля. Но повторюсь ещё раз, к
!important
лучше не прибегать вовсе, это плохой вариант, т.к. дальше будет путаница, думаешь что должны работать одни стили, а работают другие. Пишите ваши стили правильно!