В прошлых уроках и упражнениях мы использовали достаточно простые селекторы. Они позволяли выбрать элементы, к которым будут применены CSS правила. Вы уже умеете выбирать элемент по его тегу, классу, идентификатору и найти вложенный элемент.
CSS дает намного большие возможности по выбору элементов. В этом уроке мы изучим самые популярные селекторы второго и третьего уровня спецификации W3C. В конце урока будут оставлены ссылки на спецификации, в которых вы сможете узнать и о других селекторах.
Выбор соседнего элемента
Ранее использование селекторов указывало, какой конкретно элемент мы хотим выбрать и где он находится относительно своих родительских блоков. В большинстве случаев этого достаточно для точного указания элемента, но бывают случаи, когда нужно выбрать соседний элемент, а не вложенный. Например,
<section>
<div class="time">...</div>
<div class="timer">...</div>
</section>
По условию нашей задачи элемент timer
полностью зависит от блока time
. Предположим, что стиль таймера меняется в зависимости от наличия элемента с классом time
. Есть несколько путей решения такой задачи:
- Положить оба элемента в единого родителя и дать им уникальные классы для разных ситуаций.
- Воспользоваться селектором соседнего элемента.
Чаще всего, именно первый вариант будет предпочтительным. При этом вы не раз столкнетесь с ситуациями, когда это невозможно. Такое может происходить при динамическом добавлении элементов на страницу. И тут на помощь приходят селекторы.
В CSS существует два селектора для выбора элемента, который лежит рядом с другим элементом:
A + B
— выбор элемента B, который находится непосредственно после элемента A. Такой селектор называется смежным или соседнимA ~ B
— выбор элемента B, который находится на том же уровне вложенности, что и A. При этом они имеют общего родителя и все элементы B находятся после элемента A в HTML. Такой селектор называется родственным.
Для примера выше отлично подойдет смежный селектор. Элементы time
и timer
идут друг за другом и являются дочерними элементами одного и того же родителя. Стилизуем элемент timer
в зависимости от существования элемента time
:
Родственный селектор позволяет немного усложнить ситуацию. Ведь теперь будет возможность не просто выбрать соседний элемент, а элемент, лежащий на том же уровне. Изменим пример, который позволит наглядно продемонстрировать возможность родственного селектора.
<section>
<h2>...</h2>
<div class="time">...</div>
<h3>...</h3>
<div class="timer">...</div>
</section>
Схематически CSS будет выглядеть следующим образом:
.time ~ .timer {
/* Стили элемента */
}
Селекторы по атрибуту
Атрибуты — неизменная часть работы верстальщика и фронтенд-разработчика. Они не всегда несут в себе семантический смысл как, например, атрибуты alt
, title
, class
, id
и так далее.
HTML позволяет добавлять любые пользовательские атрибуты и работать с ними. Пользовательскими считаются такие атрибуты, которые мы определяем сами. Их не существует в документациях, спецификациях. Они нужны для разработчиков, чтобы удобнее обращаться к элементам или отделять похожие элементы. Целей может быть много и, с приобретением опыта, особенно при работе с языком JavaScript, вы заметите, что пользовательские атрибуты используются не так редко, как может показаться с самого начала.
Для стилизации таких элементов в CSS существуют специальные селекторы.
Самый простой селектор по атрибуту просто выбирает элемент по его атрибуту. В CSS атрибут записывается внутри квадратных скобок, это и будет самым простым селектором по атрибуту. Для демонстрации создадим свой атрибут data-full-screen
— это будет пользовательский атрибут и вы его не найдете в документациях. Для тренировки можете его назвать совершенно другим образом — смысл действий от этого не изменится:
<section data-full-screen></section>
section[data-full-screen] {
width: 100vw;
height: 100vh;
background: #2196f3;
}
Атрибут может указываться в сочетании с другими селекторами. Например, выше мы указали атрибут data-full-screen
с элементом section
. Такой селектор указывает на все элементы section
с атрибутом data-full-screen
. Если указать только атрибут, то такой селектор будет указывать на любые элементы с этим атрибутом:
[data-full-screen] {
width: 100vw;
height: 100vh;
background: #2196f3;
}
Можно выбирать не только по названию атрибута, но и по его значению. В этом случае рядом с именем атрибута указывается его значение в следующем синтаксисе:
<section data-full-screen="true"></section>
section[data-full-screen="true"] {
width: 100vw;
height: 100vh;
background: #2196f3;
}
С опытом вы заметите, что многие JavaScript-библиотеки работают именно с пользовательскими атрибутами. Это позволяет добиться изолированности компонентов и их удобного переиспользования.
Бывают ситуации, когда в HTML есть группа элементов с одинаковыми именами атрибутов, но с разными значениями. Причем некоторые из них могут быть похожи друг на друга, составляя части одного компонента. Например,
<section data-nm-section="catalog"></section>
<section data-nm-section="catalog-popular"></section>
<section data-nm-section="catalog-new"></section>
Все три секции, по своей логике, будут иметь похожее оформление. Можно добавить всем одинаковый класс, но существует одна проблема: если элементы добавляются динамически, с помощью JS, то есть вероятность существования такого же класса внутри проекта. Это приведет к коллизии, когда один селектор перебьет свойства другого. Поэтому и используются атрибуты.
Все три секции имеют одинаковую приставку catalog. Это поможет отделить их от остальных названий секций с помощью конструкции [data-nm-section^="catalog"]
. Такой селектор выберет все элементы с атрибутом data-nm-section
, значение которого начинается с catalog
.
[data-nm-section^="catalog"] {
width: 50px;
height: 50px;
margin-bottom: 10px;
background: #2196f3;
}
Есть еще несколько похожих конструкций, которые ищут «вхождение» подстроки в строку:
[data-nm-section$="catalog"]
— вхождение подстроки в конце значения атрибута.[data-nm-section*="catalog"]
— вхождение подстроки в любом месте значения атрибута.
Выражение «вхождение подстроки в строку» стоит понимать следующим образом: строка b
является частью строки a
. Например, возьмем фразу «Съешь еще этих мягких французских булок, да выпей чаю» и фразу «французских булок». Фраза «французских булок» входит в предложение «Съешь еще этих мягких французских булок, да выпей чаю», поэтому говорится, что подстрока входит в строку.
Самостоятельная работа
Возьмите примеры из прошлых уроков. Используя селекторы по атрибуту и селекторы по соседнему элементу, повторите верстку
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.