Взвешиваем селекторы CSS. 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 кода.

Допустим, у Вас есть несколько селекторов которые ссылаются на один и тот же элемент:

Открыв HTML страницу где элемент span находится внутри элемента div мы увидим подчеркнутый текст. А если мы пойдем дальше и с помощью плагина Firebug посмотрим стили вложенного элемента, мы увидим следующее:

Div span { text-decoration:underline; } span { text-decoration:none; }

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

Правила специфичности

Специфичность селекторов (selector"s specificity) определяет их приоритетность в таблице стилей. Чем специфичнее селектор, тем выше его приоритет.

В спецификации по CSS 2.1 этой теме посвящен небольшой раздел. Существует 4 правила по которым вычисляется специфичность селекторов:

  1. Самый высокий приоритет имеет атрибут style . Это правило перекрывает все селекторы описанные в стилях.
  2. Второе место занимает присутствие ID в селекторе(#some-id).
  3. Далее идут все атрибуты(в том числе и атрибут class ) и псевдоклассы(pseudo-classes) в селекторе.
  4. Самый низкий приоритет у селекторов с именами элементов и псевдоэлементами(pseudo-elements).

Все 4 правила сводятся в одну систему a-b-c-d (где а - наивысший приоритет) и образуют специфичность.

Селектор Специфичность a-b-c-d Правило №
* 0-0-0-0 -
li 0-0-0-1 4
li:first-line 0-0-0-2 4
ul li 0-0-0-2 4
ul ol+li 0-0-0-3 4
form + * 0-0-1-1 3, 4
table tr td.second 0-0-1-3 3, 4
h2.block.title. 0-0-2-1 3, 4
#xyz 0-1-0-0 2
style=" " 1-0-0-0 1

Пример специфичности - правило №1:

content

Текст внутри элемента p будет отображаться синим цветом независимо от селектора с айди(id), где также указано свойство color со значением red . Правило номер 1 всегда перекрывает все селекторы и имеет наивысшую приоритетность.

Правило №2:

  • first
  • second

Несмотря на то что селектор с id указан в стилях сверху, именно он повлияет на отображение документа, так как более специфичен нежели селектор с классом second .

Правило №3:

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

Вернемся к первому примеру этой статьи - правило №4:

div span { text-decoration:underline; } span { text-decoration:none; }

Первый селектор выигрывает у второго потому что включает в себя 2 последних правила специфичности, в то время как второй - всего одно. Чтобы убрать декорирование текста в данном случае следует использовать класс или более специфичный селектор:

Div span { text-decoration:underline; } body span { text-decoration:none; }

Теперь селекторы имеют одинаковый вес(0-0-0-2 = 0-0-0-2) касательно специфичности. Второй селектор просто перекроет свойство первого так как описан ниже.

Уверен, что большинство верстальщиков точно знают 2 первых правила специфичности селекторов про id и style и эта статья не была для них чем-то новым. Но не стоит забывать о двух оставшихся, ведь это может существенно приостановить процесс создания верстки и увеличить время выявления возникшей ошибки.

Вот и все о чем я хотел рассказать. Надеюсь, что статья была вам интересна.

--
Владислав Razor Чапюк, апрель 2009

В данной главе подробно объясняется, почему каскадные таблицы стилей (Cascading Style Sheets, CSS) называются каскадными. Для начала давайте вспомним, какими способами можно добавить стиль на веб-страницу:

  • подключить внешнюю таблицу стилей;
  • добавить внутреннюю таблицу стилей в HTML-документ через тег . В итоге цвет тегов

    Будет красным.

    Это – один из способов управлять значимостью стилей. Еще один способ повысить приоритет – специально увеличить вес селектора, например, добавив к нему ID или класс.

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

    Если вы столкнулись с экстренным случаем и вам необходимо повысить значимость какого-либо свойства, можно добавить к нему объявление!important:

    P {color: red !important;} p {color: green;}

    Также!important перекрывает inline-стили. Слишком частое применение!important не приветствуется многими разработчиками. В основном, данное объявление принято использовать лишь тогда, когда конфликт стилей нельзя победить иными способами.

    Сброс стилей с помощью reset.css

    В предыдущей главе мы уже упоминали о том, что у каждого браузера есть свои встроенные стили HTML-документов, созданные для улучшения читабельности. Вы наверняка уже видели, как выглядит «голая» веб-страница в браузере: синие подчеркнутые ссылки, черный шрифт, полужирное начертание заголовков и т. д.

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

    Инструмент для сброса стилей – это, по сути, та же самая таблица CSS, где описаны правила, которые сбрасывают встроенные стили браузеров, устанавливая базовые значения свойств. Называется такая таблица reset.css и служит для того, чтобы вы могли начать создавать стиль «с нуля». Вот пример стандартной таблицы сброса:

    Html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { margin: 0; padding: 0; border: 0; font-size: 100%; font: inherit; vertical-align: baseline; } /* HTML5 display-role reset for older browsers */ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; } body { line-height: 1; } ol, ul { list-style: none; } blockquote, q { quotes: none; } blockquote:before, blockquote:after, q:before, q:after { content: ""; content: none; } table { border-collapse: collapse; border-spacing: 0; }

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

    Все материалы по таблицам каскадных стилей, которые уже были опубликованы на этом блоге, вы сможете найти в . Сегодня же мы поговорим сначала про то, как можно комбинировать и группировать селекторы, а затем подробно рассмотрим правил, которые применяются для одного и того же элемента в Html коде (Important, подсчет селекторов и запись правил в атрибуте style).

    Комбинации и группировка селекторов в CSS

    Итак, в предыдущих статьях мы успели рассмотреть 7 типов:

    Из этих семи возможных видов в языке CSS можно составлять комбинации. Все комбинации, которые мы будем составлять, имеют непосредственное отношение к (предки — потомки, родители — дети, братья — сестры).

    Первый вид комбинации называется контекстный селектор . Он учитывает взаимоотношение элементов Html кода по принципу «Предок — Потомок»:

    Отдельные селекторы в комбинации записываются через пробел , а читать ее нужно справа налево. Т.о. правила CSS будут применяться только к последнему этой комбинации (самому правому), а все, что стоит перед ним, лишь позволяет задать более точное применение (прицеливание) для наших правил (акцентировать).

    В первом примере говорится, что все элементы B (выделение жирным), у которых в предках есть элементы Div, будут окрашены в зеленый цвет.

    В приведенном коде только подчеркнутый фрагмент будет окрашен в зеленый цвет, т.к. в числе его предков имеется Div, а второй фрагмент кода, выделенный тегами B, останется того цвета, который выбран для него по умолчанию, ибо в числе его предков контейнера Div уже нет (только P и Body):

    Такие комбинации работают в любых браузерах.

    Следующим типом комбинаций будет дочерний селектор , который строится на принципах взаимоотношений элементов кода по типу «Родитель — Ребенок»:

    Записываются они с разделяющим знаком больше (>) :

    Данная запись будет трактоваться браузером так: для , «родителем» (ближайшим предком) которых является контейнер Div, будет использоваться выделение красным цветом.

    В приведенном примере только обведенные абзацы будут окрашены в красный цвет, ибо они заключены непосредственно в контейнер Div, который для них является родителем (ближайшим предком). Если видоизменить приведенный пример дочернего селектора на такой:

    Body > p {color:red}

    То красным уже будет выделен только последний абзац, т.к. его родителем является тег Body, а два первых параграфа останутся того цвета, который был предусмотрен для них по умолчанию (Body для них предок, но не родитель, которым является Div). Дочерние селекторы не работают в браузере Ie 6 .

    Как и для чего группируют селекторы в CSS коде

    Последняя комбинация называется соседние селекторы и отвечает принципам отношений между элементами Html кода по типу «Сестры — Братья». В качестве разделителя у них может использоваться либо «+», либо «~»:

    Данная запись означает, что содержимое элемента I (выделение курсивом) будет окрашено в красный цвет только тогда, если его ближайшим соседом слева (сверху по коду) является элемент B (выделение жирным). Например, данное условие будет соблюдено в этом примере:

    Если записать соседний селектор в Css коде в таком виде:

    H1 ~ p {color:red}

    То это будет означать, что все параграфы (P), у которых выше по коду расположен соседний элемент H1 (заголовок), будут окрашены в красный цвет. Имеются в виду именно соседние элементы (отношения вида «Сестры — Братья»). На приведенном ниже примере заданному селектору будут удовлетворять обведенные абзацы:

    Комбинации соседних селекторов в браузере Ie 6 тоже, к сожалению, не поддерживаются. В Ie 6 поддерживается только первый вид комбинации, а в Ie 7 и выше поддерживаются все остальные. В остальных браузерах никаких проблем возникать не должно.

    Селекторы в Css можно еще и группировать . Например, если у каких-то из них используется одно или несколько одинаковых правил, то их можно объединить в группу для уменьшения объема Css кода.

    В приведенном на скриншоте примере, повторяется для каждого селектора заголовка (h1-3), что может вызвать сложности (многократная работа) при желании поменять значение этого свойства. Поэтому второй вариант сгруппированной записи выглядит немного предпочтительнее.

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

    Приоритеты Css свойств (с important и без него)

    Теперь давайте подумаем, а какое стилевое оформление будет использовать браузер, если никаких стилей для данного элемента Html кода не задано? А для этого существует соответствующая спецификация , где все это описано.

    Как вы можете видеть, сейчас произошло уже окончательное разделение Html и Css. Т.е. даже для чистого ХТМЛ кода браузер все равно будет использовать дефолтные свойства таблиц стилей. Так вот свойства, принятые по умолчанию, имеют самый низший приоритет .

    Более высокий приоритет имеют свойства, которые назначит пользователь в настройках своего браузера. Эти стили будут применены к любым документам, которые он просматривает в этом обозревателе.

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

    Например, в Ie для этого нужно выбрать из верхнего правого меню «Сервис» — «Свойства обозревателя», а затем на первой вкладке «Общие» щелкнуть по нижней кнопке «Оформление». В открывшемся окне вам нужно поставить галочку в поле «Оформлять, используя пользовательский стиль», и с помощью кнопки «Обзор» найти на своем компьютере нужный вам файл стилевой разметки CSS:

    Т.е. у пользователя есть возможность заставить любой открываемый в браузере сайт выглядеть в соответствии с его требованиями, описанными в файле CSS. Это называется «пользовательские стили» и они имеют приоритет выше, чем стили, которые определены в спецификации по умолчанию. Но еще больший приоритет будут иметь так называемые авторские стили.

    Т.е., если я (разработчик сайта) захотел использовать в оформлении какого-либо элемента Html кода стили отличные от дефолтных (помните, они в спецификации описаны), то пользователь своим собственным файлом Css перебить мое оформление не сможет.

    Пользователь будет вынужден смириться? Нет. Есть у него возможность повысить приоритет своих свойств CSS с помощью добавления Important в конце каждого из них. Пишется это слово через пробельный символ и перед ним ставится восклицательный знак:

    P {color:red !important;}

    Если у пользователя в его собственном файле стилей, который он подключил к браузеру, будет прописано это же свойство с Important, то все абзацы он будет видеть в красном цвете. Но ведь и автор (разработчик) сайта мог использовать Important для этого свойства. Кто же тогда победит и чей приоритет окажется выше?

    Решили, что пользовательские стили с Important будут иметь по-любому более высокий приоритет, чем авторские стили, что с Important, что без него.

    Давайте обобщим в виде списка всю изложенную информацию по поводу приоритетов стилевых свойств. Приоритет будет убывать сверху вниз:

    1. Пользовательские с Important
    2. Авторские с Important
    3. Авторские
    4. Пользовательские
    5. Стили, принятые для Html элементов в спецификации по умолчанию (когда ни автор, ни пользователь ничего другого не задали)

    Т.е. без Important авторские стили важнее, а с них уже пользовательские стили самые важные и приоритетные. Ну, а теперь давайте разбираться именно с авторскими таблицами, ибо про то, что делает пользователь, нам не ведомо и покрыто мраком.

    Как повышают приоритеты Css свойств в авторских стилях

    Именно сейчас мы с вами и переходим к вопросу каскадности таблиц стилей CSS . Давайте рассмотрим это на примере, чтобы было нагляднее. Допустим, что у нас имеется фрагмент кода со следующими Html элементами (параграф внутри контейнера Div):

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

    Давайте сначала пропишем такие свойства:

    P {color:red} .sbox {background:#f0f0f0}

    В результате будет применено и первое из них к параграфу (ибо он образован тегом P), и свойство, задающее серый фон для элемента с классом «sbox», который опять же имеется у этого параграфа:

    А теперь давайте добавим ко второму селектору (класса) еще одно свойство, которое будет конфликтовать с первой строчкой (в них обоих задается , но значения при этом используются разные):

    P {color:red} .sbox {background:#f0f0f0;color:blue}

    В результате цвет текста параграфа станет синим вместо красного.

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

    Кроме этого сами селекторы имеют градацию по приоритетам . Самый высокий приоритет у ID. В этом примере цвет текста будет синим именно потому, что приоритет Id (#out) будет выше, чем у селектора тега (p):

    P {color:red} #out {color:blue}

    Дальше по лесенке приоритетов, направленной вниз, следуют селекторы классов, псевдоклассов и атрибутов. В следующем примере опять проиграет тег (p) и цвет текста абзаца будет синим, ибо тягается он с селектором более высокого приоритета (класса):

    P {color:red} .sbox {color:blue}

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

    Div p {color:red} p {color:blue}

    Какого цвета в результате получится текст параграфа? Правильно, именно красного, т.к. у этого свойства больше селекторов тегов (два против одного). О как. Т.е. сначала считаются Id. Если победитель не выявлен, то считаются классы, псевдоклассы и атрибуты. Ну, а если и там ничего не решилось или таких не было найдено, то считаются селекторы тегов и псевдоэлементов.

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

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

    Вполне можно будет написать такой кусок Css кода:

    Div.box #out{color:red} #in p.sbox{color:blue}

    И какого же цвета должен быть текст параграфа? Обе комбинации описывают именно наш параграф. Первую следует, как и водится, читать справа налево: применить данные свойства (color:red) для элемента с Id #out, который стоит где-то внутри (иметь его среди «предков») контейнера Div с классом.box (div.box). Полностью подходит к нашему абзацу.

    Вторая комбинация: применить данные свойства (color:blue) для элемента параграфа с классом sbox (p.sbox), который стоит внутри любого элемента с Id #in. Опять же, она полностью описывает именно наш параграф. Давайте считать селекторы.

    С ID в обоих комбинациях встречаются по одному разу, тоже самое можно сказать и о классах. Остается только посчитать селекторы тегов, но их тоже в обоих комбинациях используется одинаковое число раз (один). Засада.

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

    Тут будет действовать правило — кто последний , тот и прав. Поэтому в моем примере цвет текста параграфа будет синим, ибо это свойство (color:blue) расположено ниже в коде. Если эти правила поменять местами:

    #in p.sbox{color:blue} div.box #out{color:red}

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

    Body #in p.sbox{color:blue} div.box #out{color:red}

    В этом случае цвет параграфа измениться на синий. Универсальный селектор «*» вообще никакого влияния на подсчет приоритетов не оказывает. Кстати, чуть выше мы рассмотрели способ повышения приоритета Css правил с помощью добавления Important. В нашем примере это может выглядеть так:

    P {color:green !important} #in p.sbox{color:blue} div.box #out{color:red}

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

    Но Important не является единственным способом безоговорочного повышения приоритета свойства. Второй способ повышения может заключаться в использовании стилевых свойств в атрибуте Style нужного вам Html элемента.

    Т.е. прописываете внутри того же многострадального тега P атрибут Style с заданием любого цвета:

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

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

    Но вот свойства с Important он перебить не сможет. Т.е. в последнем примере, где мы добавили правило «p {color:green !important}», цвет текста по-прежнему будет зеленым, даже несмотря на style="color:yellow".

    На самом деле приоритет двух правил (с Important во внешнем файле таблицы стилей и в атрибуте style) равный, а значит нужно переходить к подсчету селекторов. А разве они могут быть внутри атрибута style?

    Да никаких не может быть, а это значит, что правило, прописанное в атрибуте style, всегда проиграет правилу с Important только за счет меньшего числа селекторов (ноль будет меньше любого числа).

    Ну, а что же тогда даст наибольший приоритет Css свойству ? Правильно, его оно будет прописано в атрибуте style да еще с Important:

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

    В этом случае цвет текста параграфа будет желтым и перебить это уже ничем в авторских стилях будет невозможно. Мы нашли абсолютный способ задания стилей. Его сможет перебить только пользователь со своим собственным файлом стилей и прописанным для этого свойства Important.

    Итак, давайте попробует составить список факторов, влияющих на приоритет свойства в авторских стилях по мере их убывания:

    1. Прописывание свойства в атрибуте style нужного тега вместе с Important
    2. Добавление Important к свойству во внешнем файле таблиц стилей или же в теге style прямо в Html коде
    3. Простое прописывание этого свойства в атрибуте style нужно элемента
    4. Использование бОльшего числа Id для данного свойства
    5. Использование большего числа селекторов классов, псевдоклассов или атрибутов
    6. Использование большего числа селекторов тегов и псевдоэлементов
    7. Более низкое расположение свойства в Css коде, при прочих равных условиях

    На самом деле правила в атрибуте style используются крайне редко (представьте себе, как трудно будет в этом случае вносить изменения во всем коде сайта, а не в отдельном файле CSS).

    Этот атрибут в основном используют, когда только нужно что-то быстро протестировать. Ну, и еще это удобно, если вы вставляете свой код в чужие Html странички, которые имеют свое стилевое оформление и которое может унаследоваться () и для ваших вставляемых элементов.

    А зачем и как вставлять свой код на чужие страницы? Нам может и незачем, а Яндекс и Гугл это делают, когда или на чужих площадках (наших с вами сайтах).

    Добавив во все элементы кода рекламных блоков атрибут style, с прописанными в нем свойствами и добавленным Important, можно уже не беспокоиться о том, что код объявлений будет изменен каким-либо образом (хотя объявления Яндекса все же можно менять за счет CSS и Important, видимо они не использовали этот метод).

    Удачи вам! До скорых встреч на страницах блога сайт

    посмотреть еще ролики можно перейдя на
    ");">

    Вам может быть интересно

    Селекторы тега, класса (class), Id и универсальные, а так же селекторы атрибутов в современном CSS
    Селекторы псевдоклассов и псевдоэлементов в CSS (hover, first-child, first-line и другие), отношения между тегами Html кода
    List style (type, image, position) - Css правила для настройки внешнего вида списков в Html коде
    Для чего нужен CSS, как подключить каскадные таблицы стилей к Html документу и основы синтаксиса этого языка

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

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

    Селектор - это строка, представляющая собой формальное описание структуры, на основе которого выбирается элемент или группа элементов в дереве документа и применяется объявленный блок свойств.

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

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

    Вес селекторов

    Нет, здесь не идёт речь об их реальном весе (его нет), а также о количестве символов. Такой вес нельзя измерить весами, так как он не вещественен в обычном понимании и вообще не существует в нашем с вами мире людей. Зато он есть в виде нулей и единиц. Получается, что селектор можно взвесить, используя некую систему, о которой мы и будем говорить дальше.

    Что такое вес селектора?

    Вес селектора - это условные четыре позиции x, x, x, x , которые заполняются нулями и единицами в соответствии с содержимым селектора. Каждая из позиций имеет своё содержимое:

    • Инлайн стили
    • Идентификаторы
    • Классы, атрибуты и псевдоклассы
    • Теги и псевдоэлементы

    Как это читать?

    Очень просто. Справа налево. Слева идут числа старшего разряда, поэтому они имеют больший вес, числа, идущие справа, наоборот, имеют наименьший вес. Всё это станет понятным дальше, поэтому можно даже не вдумываться в смысл этого абзаца.

    Как заполнять?

    H1 { color: #777; }

    В этом примере селектором выступает заголовок h1 , который состоит из одного тега. Получается, что напротив столбца «тег» мы ставим единичку. Получается следующая картина: 0, 0, 0, 1 .

    Всё это замечательно, но в реальных проектах встречается разве что в ядре стилей или normalize , а это значит, что нужно усложнить задачу.

    #main .container article.post > header h1.giga { color: #777; }

    Пример получился хардкорнее, чем предыдущий и в реальной жизни достоин премии «самого избыточного селектора». Такая избыточность должна преследоваться по закону, но подробнее на эту тему мы поговорим в отдельной части статьи. Окей, вернёмся к примеру и немного поработаем весами.

    Давайте начнём слева, так как в начале стоит единственный идентификатор #main . Далее мы видим три класса.container , .post и.giga , а также три тега article , header и h1 . Для ещё большей наглядности я распишу это в виде этапов:

    // Селектор #main .container article.post > header h1.giga // Начальный вес 0, 0, 0, 0 // Идентификаторы #main 0, 1, 0, 0 // Классы, атрибуты и псевдоклассы.container 0, 1, 1, 0 .post 0, 1, 2, 0 .giga 0, 1, 3, 0 // Теги и псевдоэлементы article 0, 1, 3, 1 header 0, 1, 3, 2 h1 0, 1, 3, 3 // Итог #main .container article.post > header h1.giga => 0, 1, 3, 3

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

    // Селектор body.page-posts #main .container article.post ul.list-unstyled > li:first-child h2.article-title:hover { color: #333; } // Начальный вес 0, 0, 0, 0 // Идентификаторы #main 0, 1, 0, 0 // Классы, атрибуты и псевдоклассы.page-posts 0, 1, 1, 0 .container 0, 1, 2, 0 .post 0, 1, 3, 0 .list-unstyled 0, 1, 4, 0:first-child 0, 1, 5, 0 .article-title 0, 1, 6, 0:hover 0, 1, 7, 0 // Теги и псевдоэлементы body 0, 1, 7, 1 article 0, 1, 7, 2 ul 0, 1, 7, 3 li 0, 1, 7, 4 h2 0, 1, 7, 5 // Итог body.page-posts #main .container article.post ul.list-unstyled > li:first-child h2.article-title:hover => 0, 1, 7, 5

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

    // Селектор.main:before { content: "3 .column.size-1of3"; } // Начальный вес 0, 0, 0, 0 // Идентификаторы 0, 0, 0, 0 // Классы, атрибуты и псевдоклассы.main 0, 0, 1, 0 0, 0, 2, 0 // Теги и псевдоэлементы:before 0, 0, 2, 1 // Итог.main:before => 0, 0, 2, 1

    Вот такие вот дела.

    На самом деле, тема очень простая, но очень важная на практике для посредственного (минимального) понимания того, как браузер определяет какой блок объявлений необходимо применить к тому или иному элементу на странице.

    А что, если вес селекторов одинаковый?

    Допустим, что у вас есть два или несколько селекторов так или иначе указывающих на один и тот же элемент. И вот так сложилось, что вы посчитали или просто взглянули на них, и вес оказался одинаковым. Не стоит отчаиваться, просто блок объявлений последнего селектора в вашем CSS-коде из этой группы и будет применяться к элементу. Как-то так. Мне кажется это логичным. Прямо как в поговорке «кто не успел, тот опоздал», но наоборот: «кто опоздал, тот и успел».

    Зачем это нужно?

    Это очень интересный момент, ибо понять какой блок объявлений будет применяться к элементу, можно и без расчёта веса селектора, то есть просто посмотрев на него и слегка подумав. Однако, глазомер может подвести, а вот машина не подведёт, посчитает вес и испортит вёрстку. Ошибка, конечно, не машины, а прослойки между компьютером и стулом, но это уже совсем другая история.

    Ещё одним применением такого вот расчёта являются сервисы или скрипты, которые строят диаграммы специфичности CSS. Это может быть очень удобно для анализа и оценки избыточности вашего кода.

    Интересным фактом будет то, что единственный раз, когда мне приходилось считать вес селектора, был тестом от Mail.ru на какой-то сертификат. Если интересно, то я поищу этот тест у себя в истории.

    Ох, специально для вас у меня есть сервис, на который я наткнулся при подготовке к изложению этого материала: Specificity Calculator - это простой и эффективный калькулятор веса селекторов.

    Специфичность селекторов

    Раз уж зашла речь про вес CSS-селекторов, то неизбежно задумываешься о том, как бы его оценить: когда нужно ему худеть, а когда наоборот - поправляться. Как и у человека, у селекторов всё таки есть оптимальный вес.

    Так сложилось, что многие веб-разработчики считают оптимальной специфичностью селекторов три вложения. Максимальной специфичностью селекторов называется пять вложений и рекомендуется стараться это число не превышать. Разумеется, вложений может быть и больше, так как в жизни всякое бывает. Хотя, лучше всего, если вы всё таки будете соблюдать эту рекомендацию хотя бы косвенно. Такой подход вам поможет сэкономить время в будущем.

    Хорошо, всё это замечательно, но причём тут вес? - да очень просто, он напрямую от этого зависит. Чем больше вложений, тем больше вес. Логично, однако.

    Оценить ваш CSS-код можно с помощью ресурса CSS Specificity Graph Generator . По предложенному вами CSS-коду строится интерактивный график специфичности вашего кода, на котором можно визуально определить проблемные участки ваших стилей.

    Выводы

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

  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то