Селекторы в CSS. Приоритет селекторов

От автора: представьте специфичность в виде оценки или степени, которая решает, какие стили применить к элементу. Универсальный селектор (*) имеет низкую специфичность. Селектор id – высокую. Родительские селекторы типа p img и дочерние селекторы типа.panel > h2 имеют более высокую специфичность, чем типовые селекторы p, img и h1.

По началу, кажется, сложно вычислить точное значение специфичности. В спецификации Selectors Level 3 говорится, что для этого вам необходимо:

проигнорировать универсальный селектор.

Значения А, В и С вместе дают конечное значение специфичности. ID селектор типа #foo имеет специфичность 1,0,0. Селекторы атрибутов типа и классы типа.chart имеют специфичность 0,1,0. Если добавить псевдокласс типа:first-child (например, .chart:first-child), специфичность станет 0,2,0. А простые типовые или элементные селекторы типа h1 и p дают всего лишь 0,0,1.

Заметка: вычисление специфичности

Выучить и вычислить специфичность селектора можно с помощью ресурсов Specificity Calculator от Keegan Street и CSS Explain от Joshua Peek.

Сложные селекторы и комбинаторы дают, естественно, большую специфичность. Разберем пример CSS:

ul#story-list > .book-review { color: #0c0; } #story-list > .book-review { color: #f60; }

ul #story-list > .book-review {

color : #0c0;

#story-list > .book-review {

color : #f60;

Эти правила похожи, но не одинаковы. В первом селекторе ul#story-list > .bookreview находится типовой селектор (ul), ID селектор (#story-list) и класс (.bookreview). Специфичность равна 1,1,1. Во втором селекторе #story-list > .book-review хранятся только ID и класс. Специфичность равна 1,1,0. Несмотря на то, что #story-list > .book-review объявлен ниже ul#story-list > .bookreview, высокая специфичность последнего заставить элементы с классом.book-review окраситься в зеленый, а не оранжевый цвет.

Псевдоклассы:link и:invalid имеют ту же специфичность, что и классы. У a:link и a.external будет одна специфичность, равная 0,1,1. Точно так же псевдоэлементы типа::before и::after имеют одинаковую специфичность с типовыми и элементными селекторами. Если два селектора имеют одинаковую специфичность, в дело вступает каскадирование. Пример:

a:link { color: #369; } a.external { color: #f60; }

a : link {

color : #369;

a . external {

color : #f60;

Поддержание низкой специфичность помогает не допустить ползучести селекторов или тенденции постоянного роста специфичности. Такое часто происходит, когда в команде появляются новые разработчики, или когда на сайт добавляются новые формы контента. Ползучесть селекторов также прибавляет головной боли с долгосрочным обслуживанием. Вы либо будете использовать все более специфичные селекторы, чтобы переписывать правила, либо вам придется рефакторить код. Длинные селекторы увеличивают вес CSS файлов.

В главе 2 мы обсудим, как поддерживать низкую специфичность.

Заключение

После прочтения этой главы у вас должно сложиться четкое понимание CSS селекторов. В частности вы должны знать:

как использовать селекторы и применять стили к конкретным элементам, псевдоэлементам и псевдоклассам;

понимать различия между псевдоэлементами и псевдоклассами;

использовать новые псевдоклассы, представленные в спецификациях Selectors Level 3 и 4;

вычислять специфичность.

В следующей главе мы расскажем про золотые правила написания обслуживаемого и масштабируемого CSS кода.

Любой профессионал своего дела должен владеть терминологией. Если Вы занимаетесь версткой, можете ли без раздумий ответить на вопрос в заголовке статьи?

Возможно сейчас вы откроете для себя что-то новое. Давайте сделаем решительный шаг на пути к профессионализму:)

Наследование

Начнем с самой простой для понимания концепции CSS. Суть ее состоит в том, что стили, присвоенные некоторому элементу, наследуются всеми потомками (вложенными элементами), если они не переопределены явно. Например, размер шрифта и его цвет достаточно применить к дескриптору body чтобы все элементы внутри имели те же свойства. Но, для заголовков h1-h6 размер шрифта не будет присвоен, потому что у браузера для них есть своя таблица стилей по умолчанию, а наследованные стили имеют самый низкий приоритет. Аналогичная ситуация с цветом ссылок.

Таким образом, наследование позволяет сократить таблицу CSS. Но в то же время если стилей много, то отследить какой родительский элемент установил некоторое свойство, становится довольно сложно.

Каскадирование

Правила каскадирования позволяют разрешать ситуации, когда для одного элемента прописано несколько стилей. Каскадирование основано на присвоении некоторого приоритета каждому правилу. Авторские таблицы стилей имеют самый большой приоритет, меньший — пользовательские, самый низкий — таблицы стилей по умолчанию браузера. У пользователя есть возможность переопределить авторское правило путем добавления флага!important к своему.

Правила каскадирования определяют следующие приоритеты:

  1. пользовательские стили, отмеченные!important
  2. авторские стили, отмеченные!important
  3. авторские стили
  4. пользовательские стили
  5. стили по умолчанию

После каскадирования правила упорядочиваются на основе специфичности селекторов.

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

Специфичность — это некоторое число в системе с неопределенно высоким основанием, которое является отражением приоритета какого-либо правила. Вычисляется оно на основе специфичности каждого из селекторов, входящих в правило CSS.

Специфичность селектора разбивается на 4 группы — a b c d:

  • если стиль встроенный, т.е. определен как style="", то а=1
  • значение b равно количеству селекторов идентификаторов
  • значение c равно количеству классов, псевдоклассов и селекторов атрибутов
  • значение d равно количеству селекторов типов

Пример вычисления специфичности:

Селектор Специфичность Специфичность в системе
с основанием 10
Style="" 1,0,0,0 1000
#wrapper #content {} 0,2,0,0 200
#content .datePosted {} 0,1,1,0 110
div#content {} 0,1,0,1 101
#content {} 0,1,0,0 100
p.comment .datePosted {} 0,0,2,1 21
p.comment {} 0,0,1,1 11
div p {} 0,0,0,2 2
p {} 0,0,0,1 1

Неопределенно высокое основание системы счисления является следствием того, что неизвестно заранее, насколько большими будут числа a, b, c, d. Если они меньше 10, то удобно использовать десятичную СС.

HTML — основа всех веб-сайтов, служит для размещения основного контента на сайте. Если запустить HTML код в браузере, то можно увидеть текст, картинки и ссылки, которые не особо радуют глаз. Чтобы сделать красивые элементы и создать хороший дизайн веб-страницы нужно воспользоваться CSS

CSS — язык стилизации веб-элементов. Он берет отдельную часть контента или всю страницу целиком, изменяя её визуальную составляющую. Чтобы свойства CSS применялись, им нужно на что-то ссылаться. Для этого используются селекторы, которых существует огромное множество.

Селекторы. CSS

Селекторов существует огромное количество, от общих(ссылающихся на все элементы веб-страницы) до тегов, классов и идентификаторов.

Общие селекторы

"*" — основной селектор в CSS. Он ссылается на каждый элемент веб-страницы находящийся в теге {body}. Чаще всего используется для обнуления отступов на странице:

CSS

Скопировать

Селекторы тегов. CSS

Данный селектор ссылается на каждый указанный тег. Например, если задать изменение шрифта для тегов p, то каждый параграф будет иметь этот стиль. Классы и идентификаторы используются чаще, но теги тоже имеют широкое применение. Например, когда нужно задать общие стили для тега body — шрифт, фон, отступы и т.д.

CSS

body {

font-family: "Tahoma", serif;

Скопировать

Селекторы id. CSS

Идентификаторы используются чаще чем обращение ко всем тегам. В основном, они используются для уникального элемента веб-страницы, который имеет индивидуальный дизайн. Это обусловлено тем, что один идентификатор можно задавать только для одного элемента страницы.

Через id можно обращаться и к другим элементам, используя его как родительский селектор. Об этом позже.

Чтобы использовать селектор идентификатора, задайте его в html, с помощью атрибута id. Введите его в css документе с решеткой вначале, без пробелов.

HTML

Тестовая страница

Hello World!

Любой тестовый текст

Скопировать

В CSS выглядит как:

CSS

body {

font-family: "Tahoma", serif;

background-color: rgba(235, 52, 52, 0.52);

color: rgba(255, 255, 255, 0.71);

#head {

font-size: 1.8rem;

text-align: center;

padding: 15px 0;

Скопировать

Селекторы Классов. CSS

Классы используются чаще всех остальных селекторов. Они имеют более широкий функционал чем id, так как могут задаваться до нескольких элементов.

С помощью этого селектора можно выделить несколько элементов для определенного стиля. Например, чтобы отличить кнопочные ссылки от обычных.

Для начала задайте имя класса для элемента, через атрибут class. После этого можно обратиться к нему через css. Введите его название, с точкой вначале.

HTML файл остаётся прежним в основе, но к нему добавляется новый атрибут из CSS:

В CSS это выглядит как:

CSS

Text {

font-size: 1.1rem;

text-align: center;

padding: 10px 0;

Скопировать

Родительские и селекторы. CSS

Эти указатели немного отличаются от предыдущих и имеют свои уникальные функции.

Контекстные селекторы позволяют обратиться не ко всему контенту, который находится внутри элемента, а к некоторым его частям. Может послужить заменой классам. Существует несколько типов родительских селекторов, которые применяются ко всем потомкам и только к прямым.

Чтобы обратиться к прямым потомкам элемента используйте запись X Y. Например, чтобы стилизовать все ссылки внутри параграфов, используем селектор "a"

CSS

color: rgba(255, 255, 255, 0.65);

font-weight: bold;

Скопировать

Второй способ обращения к потомкам более конкретный. Например, если в теге

содержится многоуровневый список, а нужно обратиться только к элементам первого уровня. Для этого используйте запись
>
    .

    Стили применяются только к тем тегам

      , которые находятся внутри самого элемента
      . К элементам, которые находятся внутри
    • , стили применяться не будут.

      Соседние селекторы применяются к тем элементам, которые находятся рядом с указателем. Допустим у вас на странице такой текст:

      Тег span находится по соседству с тегом . Поэтому, чтобы обратиться к нему, используем запись + .

      Селекторы атрибутов. CSS

      Дают возможность обратиться не ко всем элементам страницы, а лишь к тем, которые имеют определенный атрибут.

      В HTML это выглядит как:

      HTML

      Скопировать

      В CSS это выглядит как:

      CSS

      color: darkblue;

      text-decoration: none;

      Скопировать

      Можно сослаться на атрибут с определенным значением. Таким образом, для того, чтобы сослаться на ссылки, которые открываются в новой вкладке, необходимо сделать следующую запись:

      Приоритеты

      По приоритету селектору располагаются следующим образом.

      1. #id:not — id c псевдо-классом отрицания. Специфичность — 101.
      2. #id — простой идентификатор. Специфичность — 100.
      3. p.green.bold — тег с двумя классами. Специфичность — 21.
      4. body section div.header — третий потомок тега с классом. Специфичность -13.
      5. body section div — третий потомок тега. Специфичность — 11.
      6. div p — второй потомок. Специфичность — 2.
      7. p — обращение к тегу элемента. Специфичность — 1.
      8. * — обращение ко всем элементам. Специфичность — 0.

      Чем выше специфичность, тем выше приоритет.

      Свойства селекторов. CSS

      В языке CSS существует огромное количество свойств, которые и задают стили элементов. Для создания нужно указать селектор, а затем уже свойство, в фигурных скобках.

      Заключение

      Знание работы селекторов и их приоритетов позволит избежать множества ошибок при разработке веб-сайтов. Чтобы закрепить знания на практике, создайте страницу с заголовками, параграфами и списками. Измените их шрифт, цвет и отступы. Для отступов используйте общие селекторы, а для цвета и шрифтов используйте обращения к тегам элементов.

      Теги:

      Аббревиатура CSS расшифровывается как Cascading Style Sheets (каскадные таблицы стилей), где одним из ключевых слов выступает «каскад». Под каскадом в данном случае понимается одновременное применение разных стилевых правил к элементам документа - с помощью подключения нескольких стилевых файлов, наследования свойств и других методов. Чтобы в подобной ситуации браузер понимал, какое в итоге правило применять к элементу, и не возникало конфликтов в поведении разных браузеров, введены некоторые приоритеты.

      Ниже приведены приоритеты браузеров, которыми они руководствуются при обработке стилевых правил. Чем выше в списке находится пункт, тем ниже его приоритет, и наоборот.

      1. Стиль браузера.
      2. Стиль автора.
      3. Стиль пользователя.
      4. Стиль автора с добавлением!important.
      5. Стиль пользователя с добавлением!important.

      Самым низким приоритетом обладает стиль браузера - оформление, которое по умолчанию применяется к элементам веб-страницы браузером. Это оформление можно увидеть в случае «голого» HTML, когда к документу не добавляется никаких стилей.

      Как задавать пользовательский стиль рассказывалось в (см. рис. 1.3 и 1.4).

      !important

      Ключевое слово !important играет роль в том случае, когда пользователи подключают свою собственную таблицу стилей. Если возникает противоречие, когда стиль автора страницы и пользователя для одного и того же элемента не совпадает, то !important позволяет повысить приоритет стиля или его важность, иными словами.

      При использовании пользовательской таблицы стилей или одновременном применении разного стиля автора и пользователя к одному и тому же селектору, браузер руководствуется следующим алгоритмом.

      • !important добавлен в авторский стиль - будет применяться стиль автора.
      • !important добавлен в пользовательский стиль - будет применяться стиль пользователя.
      • !important нет как в авторском стиле, так и стиле пользователя - будет применяться стиль пользователя.
      • !important содержится в авторском стиле и стиле пользователя - будет применяться стиль пользователя.

      Синтаксис применения !important следующий.

      Свойство: значение!important

      Вначале пишется желаемое стилевое свойство, затем через двоеточие его значение и в конце после пробела указывается ключевое слово !important .

      Повышение важности требуется не только для регулирования приоритета между авторской и пользовательской таблицей стилей, но и для повышения специфичности определенного селектора.

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

      Если к одному элементу одновременно применяются противоречивые стилевые правила, то более высокий приоритет имеет правило, у которого значение специфичности селектора больше. Специфичность это некоторая условная величина, вычисляемая следующим образом. За каждый идентификатор (в дальнейшем будем обозначать их количество через a) начисляется 100, за каждый класс и псевдокласс (b) начисляется 10, за каждый селектор тега и псевдоэлемент (c) начисляется 1. Складывая указанные значения в определённом порядке, получим значение специфичности для данного селектора.

      * {} /* a=0 b=0 c=0 -> специфичность = 0 */ li {} /* a=0 b=0 c=1 -> специфичность = 1 */ li:first-line {} /* a=0 b=0 c=2 -> специфичность = 2 */ ul li {} /* a=0 b=0 c=2 -> специфичность = 2 */ ul ol+li {} /* a=0 b=0 c=3 -> специфичность = 3 */ ul li.red {} /* a=0 b=1 c=2 -> специфичность = 12 */ li.red.level {} /* a=0 b=2 c=1 -> специфичность = 21 */ #t34 {} /* a=1 b=0 c=0 -> специфичность = 100 */ #content #wrap {} /* a=2 b=0 c=0 -> специфичность = 200 */

      Встроенный стиль, добавляемый к тегу через атрибут style , имеет специфичность 1000, поэтому всегда перекрывает связанные и глобальные стили. Однако добавление !important перекрывает в том числе и встроенные стили.

      Если два селектора имеют одинаковую специфичность, то применяться будет тот стиль, что указан в коде ниже.

      В примере 19.1 показано, как влияет специфичность на стиль элементов списка.

      Пример 19.1. Цвет списка

      HTML5 CSS 2.1 IE Cr Op Sa Fx

      Список

      В данном примере цвет текста списка задан зелёным, а второй пункт списка с помощью класса two выделен красным цветом. Вычисляем специфичность селектора #menu ul li - один идентификатор (100) и два тега (2) в сумме дают значение 102, а селектор .two будет иметь значение специфичности 10, что явно меньше. Поэтому текст окрашиваться красным цветом не будет. Чтобы исправить ситуацию, необходимо либо понизить специфичность первого селектора, либо повысить специфичность второго (пример 19.2).

      Пример 19.2. Изменение специфичности

      /* Понижаем специфичность первого селектора */ ul li {...} /* Убираем идентификатор */ .two {...} /* Повышаем специфичность второго селектора */ #menu ul li {...} #menu .two {...} /* Добавляем идентификатор */ #menu ul li {...} .two { color: red !important; } /* Добавляем!important */

      Добавление идентификатора используется не только для изменения специфичности селектора, но и для применения стиля только к указанному списку. Поэтому понижение специфичности за счёт убирания идентификатора применяется редко, в основном, повышается специфичность нужного селектора.

      Вопросы для проверки

      1. Какая специфичность будет у селектора table.forum tr:hover p?

      2. Какая специфичность будет у селектора #catalog .col3 .height div?

      Итак, ты уже знаешь, что когда к одному и тому же элементу подходят сразу несколько противоречащих друг другу правил, между ними происходит соревнование — они меряются своими специфичностями . Правило с наибольшей специфичностью побеждает.

      Конечно, чтобы результат применения для тебя был предсказуем, ты должен научиться видеть, какое из правил одержит верх. Пришла пора разобраться, как рассчитывается специфичность.

      Как это выглядит

      Специфичность представляет собой группу из четырех чисел. Например, 0,0,0,0 или 0,0,1,2.

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

      Специфичность считается по селектору. Правила подсчета очень просты:

      • каждый присутствующий в селекторе идентификатор добавляет к специфичности 0,1,0,0;
      • каждый класс, псевдокласс или атрибут добавляет к специфичности 0,0,1,0;
      • каждый элемент или псевдоэлемент добавляет к специфичности 0,0,0,1;
      • универсальный селектор и комбинаторы не учитываются.

      Давай закрепим полученные знания и поупражняемся в расчете специфичности.

      P {/*какие-то определения */} div p {/*какие-то определения */} p.note {/*какие-то определения */} form.feedbackForm input {/*какие-то определения */} #conten a:hover {/*какие-то определения */}

      Превая строка — одинокий селектор типа. Специфичность 0,0,0,1.

      Вторая строка — два селектора типа. Специфичность 0,0,0,2.

      Теретья строка — селектор типа и класса. Специфичность 0,0,1,1.

      Четвертая строка — два селектора типа, один класса и один атрибута. Специфичность 0,0,2,2.

      Пятая строка — селектор идентификатора, типа и псевдокласс. Специфичность 0,1,1,1.

      Кто победил?

      Сравниваются специфичности очень просто. Какое число больше, то определение и выиграло.

      Например:
      0,0,1,4 больше, чем 0,0,1,2.
      0,1,2,0 больше, чем 0,0,2,1.

      Учти, что первые (те, которые левее) числа всегда возьмут верх над последующими (более правыми). Они как бы находятся в более старшем разряде.

      Например, 0,1,0,0 больше, чем 0,0,8,9.

      Если тебе так удобнее, можешь мысленно отбросить запятые и рассматривать предыдущий пример, как 100>89. Только не запутайся, если какой-то из разрядов специфичности будет больше девяти (что может быть при сильно навороченном селекторе). Например, если получилась специфичность 0,1,10,14, запятые отбрасывать нельзя, а то все разряды попутаются.

      Специфичность и объявления

      Специфичность относится как бы не ко всему правилу в целом, а к каждому конкретному объявлению. Поэтому, может получиться что правило «отработает» не полностью. Например:

      Подопытный текст

      Div { color: #0f0; /* Специфичность 0,0,0,1. */ font-weight: bold; /* Специфичность 0,0,0,1. */ } .box { font-weight: normal; /* Специфичность 0,0,1,0. */ }

      Объявление из строки 2 для элемента

      отработает нормально, а объявление из строки 3 будет перебито объявлением из строки 6 (так как у него больше специфичность). Текст внутри нашего div будет зеленым, но не жирным.

      Этот простейший пример показывает насколько важно уметь считать специфичности. Во первых, всегда можно составить правильный селектор, чтобы нужное мне объявление победило. Во-вторых, если какое-то объявление не отработало, ты сразу же поймешь, почему и сэкономишь массу времени на отладке.

      Обрати внимание, что специфичность селектора идентификатора (0,1,0,0) всегда выше, чем селектора атрибута (0,0,1,0). Даже если этот атрибут — ! Поэтому:

      Form.feedback input { color: #f00; /* Специфичность 0,0,2,2. */ } #name { color: #0f0; /* Специфичность 0,1,0,0. - победа! */ }

      Встроенные стили

      По идее, кто-то уже давно должен был спросить, а зачем, собственно, в специфичности самая первая цифра? Ведь мы ее до сих пор никак не использовали!

      Все верно. Первая цифра зарезервирована для встроенных стилей. Считается, что их специфичность равна 1,0,0,0. Таким образом, встроенный стиль всегда перебивает стиль заданный во внешней или вложенной таблице стилей. Например:

      Этот текст будет зеленым

      Даже использовав селектор идентификатора, мы не перебъем встроенный стиль.

      Div#box { color: #00f; /* Специфичность 0,1,0,1. - маловато */ }

      Это что же получается? На встроенные стили нет никакой управы?

      Не волнуйся. Конечно, есть способ перебить встроенные стили (а заодно и все остальные объявления).

      Объявление!important

      Если очень нужно, можно пометить какое нибудь объявление, как важное (important). Такое объявление будет считаться заведомо победившим при сравнивании специфичностей. Да, да, в том числе победившем и встроенные стили. Давай немного изменим CSS для предыдущего примера:

      Div { color: #00f !important; /* важное объявление - сразу победа! */ }

      Даже слабенький по специфичности (0,0,0,1) селектор типа перебил встроенный стиль, ведь его объявление теперь стало важным!

      Детали применения!important хорошо описаны в нашем CSS-справочнике . Если хочешь узнать подробности — перейди по ссылке .

      Теперь, вооружившись знанием о расчете специфичности можно продолжить изучение наследования в CSS.



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: