Открыть сервис

Селектор в веб-разработке

Селектор (от англ. selector — «выбирающий») — в языках разметки и стилизации, прежде всего в HTML и CSS, правило или шаблон, определяющий, к каким элементам веб-страницы будет применён заданный набор стилевых объявлений или скриптовых действий. Селектор является фундаментальной частью каскадных таблиц стилей (CSS) и технологии Document Object Model (DOM), позволяя разработчикам адресно воздействовать на структуру документа без необходимости изменять его разметку.

История возникновения

Понятие селектора возникло вместе с появлением CSS в 1994 году, когда норвежский программист Хокон Виум Ли предложил концепцию стилизации документов, отделённую от их содержания. Первая спецификация CSS1 (1996 год) включала простейшие селекторы: элементы, классы, идентификаторы и псевдокласс :link. Развитие стандарта CSS2 (1998 год) добавило атрибутные селекторы, псевдоэлементы и комбинаторы потомков. Современный уровень — CSS Selectors Level 3 (2011 год) и Level 4 (разрабатывается) — расширил возможности до псевдоклассов структурного положения (:nth-child), отрицания (:not) и логических комбинаций (:is, :where). Параллельно селекторы стали использоваться в JavaScript-библиотеках, наиболее известной из которых является jQuery, а затем и в нативных методах поиска элементов (querySelector, querySelectorAll).

Основные типы селекторов

Классификация селекторов строится по способу сопоставления с элементами документа.

Универсальный селектор

Символ * соответствует любому элементу без исключения. Применяется редко из-за низкой производительности и избыточности, но используется в некоторых техниках сброса стилей (CSS reset).

Селекторы по типу (тегу)

Простейший вид: имя HTML-элемента без угловых скобок. Например, p выбирает все абзацы, div — все блочные контейнеры. Обладает самой низкой специфичностью.

Селекторы по классу

Записываются с точкой перед именем класса: .menu-item. Выбирают все элементы, у которых в атрибуте class присутствует указанное значение. Классы могут комбинироваться: элемент с несколькими классами соответствует цепочке .class1.class2.

Селекторы по идентификатору

Записываются с решёткой: #header. Выбирают элемент с уникальным атрибутом id. Идентификатор должен быть единственным в пределах страницы, однако браузеры применяют стиль ко всем элементам с таким ID в случае нарушения спецификации.

Атрибутные селекторы

Заключают условие на атрибут в квадратные скобки. Разновидности:

  • [attr] — наличие атрибута;
  • [attr="value"] — точное совпадение значения;
  • [attr^="value"] — значение начинается с указанной строки;
  • [attr$="value"] — значение заканчивается указанной строкой;
  • [attr*="value"] — значение содержит подстроку;
  • [attr~="value"] — значение содержит слово из списка, разделённого пробелами.

Комбинаторы

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

Комбинатор потомков

Пробел между селекторами: div p. Выбирает все p, находящиеся внутри div на любом уровне вложенности.

Дочерний комбинатор

Символ >. Выбирает прямых детей: ul > li адресуется только к пунктам списка первого уровня.

Соседний комбинатор

Символ +. Выбирает элемент, непосредственно следующий за другим: h2 + p — абзац, идущий сразу после заголовка.

Общий соседний комбинатор

Символ ~. Выбирает все последующие элементы того же родителя: h2 ~ p — все абзацы после заголовка среди его сиблингов.

Псевдоклассы и псевдоэлементы

Псевдоклассы определяют состояние или положение элемента. Классические примеры — :hover (наведение курсора), :focus (получение фокуса), :active (активация). Структурные псевдоклассы — :first-child, :last-child, :nth-child(2n+1) — позволяют выбирать элементы по порядковому номеру. Логические псевдоклассы :not() и :is() принимают в качестве аргумента список селекторов.

Псевдоэлементы создают виртуальные элементы внутри документа. ::before и ::after вставляют контент до и после содержимого выбранного элемента, ::first-line и ::first-letter стилизуют фрагменты текста.

Специфичность и каскад

Специфичность — числовая мера приоритета селектора при конфликте правил. Вычисляется по трём компонентам: количество идентификаторов (a), классов, атрибутов и псевдоклассов (b), количество типов элементов и псевдоэлементов (c). Селектор с большей специфичностью побеждает независимо от порядка в коде. Инлайн-стили имеют приоритет выше любых селекторов, а правило с !important переопределяет даже инлайн-стили. Понимание специфичности критично для поддержки крупных проектов, так как хаотичное наращивание вложенности и идентификаторов приводит к «войне селекторов».

Применение в JavaScript

Методы document.querySelector() и document.querySelectorAll() принимают строку селектора и возвращают первый или все подходящие элементы соответственно. Это стандартизированный способ навигации по DOM, заменивший устаревшие методы getElementById и getElementsByClassName в большинстве сценариев. В библиотеке jQuery селекторы расширены собственными псевдоклассами (:visible, :checked), однако современная тенденция — использование нативных API браузера.

Производительность и оптимизация

Чтение селектора браузером происходит справа налево: сначала ищутся элементы, соответствующие самой правой части, затем проверяются условия слева. Поэтому правило div p span заставляет браузер перебирать все спаны, затем проверять их родителей. Оптимальная стратегия — минимизировать глубину вложенности, избегать универсального селектора в правой части и чрезмерного использования идентификаторов. Современные движки (Blink, Gecko, WebKit) используют кэширование и индексацию, что снижает остроту проблемы, но для анимаций и динамических обновлений DOM рекомендуется использовать классы вместо сложных селекторов.

Селекторы в смежных технологиях

Помимо CSS и JavaScript, селекторы применяются в языках разметки и запросов: XPath в XML использует собственный синтаксис путей, но концептуально решает схожие задачи. В CSS-фреймворках (Tailwind CSS, Bootstrap) селекторы скрыты за утилитарными классами, однако генерируемый код по-прежнему опирается на стандартные механизмы. Система именования классов BEM (Блок—Элемент—Модификатор) была создана для упрощения селекторов и снижения их специфичности за счёт плоской структуры классов.

Интересные факты

  • Селектор :has() (так называемый «родительский селектор») долгое время считался невозможным из-за архитектуры браузерных движков, однако в 2022 году он был реализован во всех основных браузерах, позволяя выбирать элемент по наличию определённых потомков.
  • В CSS нельзя выбрать элемент по текстовому содержимому напрямую; для этого требуются обходные манёвры с атрибутами или псевдоклассами.
  • Специфичность селектора * равна нулю, поэтому любое другое правило переопределит его действие.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →