Селекторы в CSS: что это такое, как они работают и какие бывают
Большой гайд для тех, кто хочет правильно находить и выбирать элементы при вёрстке.
Иллюстрация: Оля Ежак для Skillbox Media
Удачный выбор селектора не только позволяет избежать ошибок в коде, но и упрощает вёрстку, поэтому желательно знать разновидности селекторов и хорошо в них ориентироваться. Эта статья будет полезна как новичкам, так и опытным фронтенд-разработчикам и верстальщикам, которые хотят освежить знания.
Содержание
- Что такое CSS-селекторы
- Основные виды селекторов
- Селекторы отношений
- Селекторы по атрибуту
- Немного о псевдоклассах
- Как определить приоритет селектора
Что такое селекторы в CSS
Селектор (от англ. select — выбирать) — это шаблон, который позволяет обратиться к элементу или группе элементов веб-страницы, чтобы применить к ним стили CSS. Его указывают перед блоком со свойствами:
В примере выше селектор указывает на тег <a> (гиперссылка). Так мы говорим браузеру отключить подчёркивание у всех ссылок на странице, устанавливая для свойства text-decoration значение none.
Подключим CSS-стили к следующему HTML-файлу:
Вот как она выглядит в браузере:
Есть ненумерованный список со ссылками, которые браузер по умолчанию выделяет синим цветом и подчёркивает. Если подключить стили, которые мы написали выше, то подчёркивание исчезнет:
CSS-селектор работает! Но это, конечно, далеко не единственный способ обращения к элементам.
О том, как подключить CSS к HTML, читайте в другой нашей статье.
Виды селекторов
Структура реальных проектов гораздо сложнее. Веб-страницы интернет-магазинов, корпоративных сайтов и блогов наполнены множеством вложенных и однотипных элементов — всем нужно задать уникальный дизайн. Если бы мы могли обращаться к ним только по названию, то даже с CSS веб оставался бы хранилищем скучного гипертекста.
К счастью, есть около 20 способов выбрать нужный элемент. Рассмотрим основные.
Универсальный селектор
Он применяет стили ко всем элементам страницы и обозначается символом * (звёздочка). С его помощью удобно сбрасывать отступы и задавать значение box‑sizing для всех блочных элементов:
Селектор по тегу (элементу)
Этот селектор CSS применяет стили ко всем элементам с одинаковым тегом. Например, для всех <div>, <h2>, <p> и так далее.
Мы уже познакомились с ним, когда убирали подчёркивание у ссылок:
Селектор по идентификатору (id)
Селектор по идентификатору обозначается символом # (решётка) и применяет стили к элементу, для которого задан атрибут id с соответствующим значением. При этом у элемента может быть только один id, и этот id должен быть уникальным в пределах веб-страницы.
CSS-код:
Текст в блоке p с идентификатором intro окрасится в красный, а текст с идентификатором article_content выделится жирным и получит шрифт без засечек:
Селектор по классу (class)
CSS-селектор по классу выбирает элементы, для которых назначен атрибут class с соответствующим значением. При этом один элемент может принадлежать нескольким классам — в таком случае их перечисляют через пробел:
Абзац входит в классы plain_text и article. Значит, к нему применяются стили обоих классов:
Группа селекторов
CSS-селекторы можно сгруппировать, чтобы применить стили к нескольким группам и/или классам элементов. Для этого достаточно перечислить их через запятую:
Выбор элементов по отношению и расположению
Есть группа селекторов, которые позволяют выбрать элемент по его отношению к другим элементами (родитель — потомок) и по расположению в DOM (Document Object Model).
Выбрать всех потомков
Чтобы обратиться ко всем потомкам В элемента A, независимо от уровня их вложенности, используют конструкцию A B (селекторы разделяют пробелом):
В примере выше мы устанавливаем всем изображениям внутри элемента figure значение нижних отступов 20 пикселей.
Выбрать потомков первого уровня
Если нужно применить CSS-стили к потомкам B элемента A только на первом уровне вложенности, то вместо пробела пишут символ >:
Здесь мы задали изображениям внутри контейнера с классом .container значение нижних отступов 40 пикселей.
Выбрать все следующие элементы
Селектор A ~ B выбирает все элементы B, которые идут после A. Обратите внимание: «идут после», а не вложены в него. Например, так мы задали цвет фона #f2f3f5 всем карточкам, которые идут после блока из класса .about_us:
Выбрать первый следующий элемент
Селектор A + B выбирает только первый элемент B, который следует за A:
В этом примере цвет фона #f2f3f5 установится только для той карточки, которая идёт сразу после .about_us.
CSS-селекторы по атрибуту
Ещё один полезный инструмент — селекторы по атрибуту. Они позволяют выбрать элемент по имени атрибута, его значению или части значения. Кратко расскажем обо всех.
[attr]
Применяет стили к элементам, для которых задан этот атрибут:
[attr=value]
Работает по имени и значению атрибута:
[attr^=value]
Находит элементы с заданным атрибутом, значение которого начинается с value:
[attr|=value]
Ищет по названию атрибута и значению, которое равно или начинается с value:
[attr$=value]
Применяет CSS-стили к элементам, у которых значение заданного атрибута оканчивается на value:
[attr*=value]
Селектор по названию атрибута и значению, которое должно содержать value:
[attr~=value]
Этот шаблон выбирает элементы с атрибутом attr, значение которого состоит из нескольких слов, разделённых пробелом, одно из которых — value:
Псевдоклассы и псевдоэлементы
Псевдокласс выбирает элементы, находящиеся в определённом состоянии или положении в иерархии DOM.
Вот несколько примеров таких состояний:
- на кнопку наведён курсор мыши;
- пользователь перешёл или не перешёл по ссылке;
- курсор установлен на поле ввода.
Например, так с помощью CSS можно увеличить размер ссылок, на которые пользователь навёл курсор:
Вот как это выглядит в браузере:
А в следующем примере мы добавляем нижний отступ последнему параграфу-потомку контейнера («Параграф 3»).
CSS-код:
Если зайти в DevTools, то можно увидеть, что под третьим элементом p появилось поле margin (подсвечивается бежевым цветом):
Вот список основных псевдоклассов:
Название | Состояние элемента |
---|---|
:hover | Наведён курсор |
:focus | Элемент находится в фокусе (например, по нему кликнули мышью или его выбрали клавишей Tab) |
:visited | Ссылка, которая была посещена |
:active | Активный элемент (в промежутке времени между нажатием и отпусканием кнопки мыши) |
:checked | Элементы radio, checkbox или option, которые были выбраны |
:first-child | Первый потомок элемента |
:last-child | Последний потомок элемента |
:nth-child() | Каждый n-й потомок — число n передаётся в качестве аргумента |
:last-nth-child() | Последние n потомков — число n передаётся в качестве аргумента |
:read-write | Элементы, доступные для редактирования |
Посмотреть другие псевдоклассы можно на сайте Mozilla.
Вес CSS-селектора, или специфичность
Для одного и того же элемента веб-страницы можно прописать сколько угодно стилей. Если в разных местах CSS-файла какому-то его свойству заданы разные значения, то браузер должен выбрать одно из них.
Обычно подключается правило, которое определено последним, но так происходит не всегда. Дело в том, что одни селекторы обладают более высокой специфичностью, чем другие.
Специфичность — это показатель, по которому браузер определяет, какие стили применить к элементу. Её можно представить в виде четырёх чисел 0.0.0.0, где каждый разряд — это вес, определяемый специальными правилами.
Вот эти правила:
- Наивысший приоритет — у стилей, прописанных в атрибуте style (1.0.0.0).
- На втором месте — селекторы по идентификатору (0.1.0.0).
- Затем идут три равноправные группы: селекторы по классу, атрибуту и псевдоклассы (0.0.1.0).
- На четвёртом месте — селекторы по тегу и псевдоэлементы (0.0.0.1).
- Комбинаторы ~, >, + и универсальный селектор * веса не добавляют.
- Вес псевдоклассов :is(), :has() и :not() равен весу самого специфичного селектора внутри скобок.
Чтобы определить самый «тяжёлый» селектор, браузер сначала взвешивает каждый, а затем сравнивает их поразрядно.
Попробуем порассуждать как браузер. Допустим, на странице есть элемент, на который указывают два CSS-селектора:
Рассчитаем их вес:
- Класс .container добавляет 1 в третий разряд, а div и ul — по единице в четвёртый. Результат: 0.0.1.2.
- Идентификатор our_team добавляет 1 во второй разряд, тег div — 1 в четвёртый разряд, а класс .developers — 1 в третий. Получаем 0.1.1.1.
Браузер применит стили селектора #our_team div.developers, потому что он указывает на идентификатор (см. правило №2 в списке).
А если бы исследуемый элемент обладал атрибутом style, то и считать ничего бы не пришлось. Ведь, как мы уже знаем, style обладает наивысшим приоритетом:
А теперь секретный приём. Вы можете перебить любое правило, если добавите к нему ключевое слово !important. В таком случае стили намертво приклеятся к элементу:
После этого изменить начертание текста в ссылках можно будет, только если использовать !important в более специфическом селекторе. Например, таком:
Опытные разработчики не рекомендуют использовать !important, потому что это усложняет поддержку кода и ломает каскад. Поэтому просто помните о его существовании во время дебаггинга: возможно, это словечко спряталось где-то в документе styles.css.
Итог
CSS предоставляет большое количество селекторов для удобной стилизации веб-страниц. Запомните их и используйте всё разнообразие, чтобы писать понятный и легко поддерживаемый код. А закрепить знания можно в замечательной браузерной игре CSS Dinner.