Разное

Специфичность css: Как CSS специфичность работает в браузере / Хабр

Содержание

Как CSS специфичность работает в браузере / Хабр

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

Что такое CSS специфичность?

Вы когда-нибудь писали стиль, а он не работает, потом вы добавляете !important (или нет), и все же он не работает? Затем вы смотрите на Devtools и понимаете, что другой стиль где-то перекрывает ваш?

В этом и заключается специфичность CSS! Именно так браузер выбирает, какой из конкурирующих селекторов применить к элементу. Когда браузер видит, что два или более селектора совпадают с одним и тем же элементом, и у селекторов есть конфликтующие правила, ему нужен способ выяснить, какое из правил применить к этому элементу. То, как это происходит, называется «значение специфичности CSS».

Прежде чем мы углубимся в CSS специфичность, запомните эти вещи:

  1. Специфичность CSS важна только тогда, когда несколько селекторов влияют на один и тот же элемент. Браузеру нужен способ выяснить, какой стиль применять к соответствующему элементу, когда существуют противоречивые значения свойств.
  2. Когда два или более совпадающих селектора имеют одно и то же значение (вес) специфичности, браузер выбирает «самый последний» совпадающий селектор, который появляется ближе к нижней части списка совпадающих селекторов. Следующий пункт объясняет, что такое «список подходящих селекторов».
  3. Браузер формирует «список подходящих селекторов», комбинируя все стили на веб-странице и отфильтровывая те, которые не соответствуют элементу «currently-being-styled». Первые селекторы в таблице стилей находятся вверху списка, а последние селекторы — внизу.
  4. Свойство style для элемента имеет большее значение специфичности, чем селекторы в таблицах стилей, за исключением случаев, когда есть !important в селекторе таблиц стилей.
  5. Использование !important (что в некоторых случаях считается плохой практикой) изменяет специфичность селектора. Когда два селектора имеют одинаковую специфичность, выигрывает селектор с !important. И когда они оба имеют !important, «самый последний» селектор выигрывает.

Значение специфичности

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

Специфичность селектора может быть представлена в виде трехзначной строки, разделенной дефисом (или чем угодно): «2–4–1». Первая цифра — это количество присутствующих селекторов ID, вторая — это количество селекторов классов, селекторов атрибутов и псевдоклассов, а третья — количество имеющихся селекторов типов и псевдоэлементов. Например:

#red.blue // 1-1-0
#green // 1-0-0
div.yellow#red // 1-1-1
.red.blue.yellow // 0-3-0
Определение самого “специфичного”

Чтобы определить, какой селектор обладает большей специфичностью, вы можете сравнить каждое из трех значений.

Скажем, у вас есть 1-1-1 и 0-3-0, как в двух последних примерах, и вам нужно определить, какой из них имеет большую специфичность. Сначала вы сравниваете последние значения 1 и 0, и в этом случае выигрывает 1. Это означает, что на данный момент div.yellow#red имеет большее значение специфичности… но мы еще не закончили сравнение значений.

Далее сравниваем значения 1 и 3, 3 выигрывает. На данный момент .red.blue.yellow имеет большее значение специфичности.

Наконец, сравниваем первые значения, 1 и 0, и выигрывает 1, так что div.yellow#red обладает большей специфичностью, чем .red.blue.yellow.

CSS-специфичность селектора и дает хорошее объяснение того, почему никакое количество селекторов классов не может переопределить селектор ID.

Небольшие предупреждения

3 “подводных камня”, о которых нужно знать:

  1. Выше я писал, что второе число в последовательности чисел, состоящей из трех, представляет собой «число селекторов классов, селекторов атрибутов и псевдоклассов». Это верно во всех случаях, кроме случаев, когда это: :not() псевдокласс. Когда это :not() псевдокласс, мы не считаем его, а просто игнорируем. Но селекторы внутри него не игнорируются, они считаются нормально.
  2. CSS специфичность понимает “форму” селектора. Это означает, что когда у вас есть *[id="yellow"] и #yellow, первый рассматривается как селектор атрибутов.
  3. Универсальный селектор * сам по себе не засчитывается в значение специфичности селектора. В пункте выше [id="yellow"] часть селектора — это то, что на самом деле имеет значение.

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

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

Перевод статьи: Specifics On CSS Specificity
Автор: Chris Coyier

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

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

<ul>
<li>Whiskey</li>
<li>Beer</li>
<li>Cola</li>
</ul>

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

<ul>
<li>Whiskey</li>
<li>Beer</li>
<li>Cola</li>
</ul>

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

.favorite {
color: olive;
font-weight: bold;
}

Осталось лишь посмотреть на результат работы этого кода. Но увы, мы не получили ожидаемого эффекта – текст выбранного нами напитка (Whiskey) не будет выделен и отображается также, как и остальные элементы списка. В чем же дело?

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

ul#drinks li {
color: black;
font-weight: normal;
font-size: 13px;
}

Именно это CSS правило содержит определения, препятствующие визуальному выделению желаемого элемента списка. В используемом документе находится два различных CSS селектора, применяемых к одному элементу (), которые предусматривают различные значения для цвета и толщины шрифта, содержащегося в нем текста. Что касается размерности шрифта, то здесь все понятно – рассматриваемый код содержит лишь одно выражение, определяющее его значение ( font-size: 13px), поэтому именно оно и будет использоваться. Проблема, в данном случае, заключается в том, что браузер должен определить, какому из конфликтующих правил отдать предпочтение в процессе обработки документа. Как раз для этих целей и предназначены значения CSS специфичности каждого из правил.

Большинство проблем возникает у начинающих веб-разработчиков, которые не понимают, по какому принципу производится выбор рабочего правила. Они, как правило, предполагают, что приоритетом должен обладать селектор .favorite, так как он находится ниже в структуре CSS кода или потому, что определение атрибута в HTML разметке документа находится ближе к текстовому содержимому интересующего нас элемента страницы (<li>). Но все это, конечно же, заблуждения.

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

.favorite {
color: olive;
}
.favorite {
color: black;
}

В этом случае цвет шрифта выбранного элемента списка будет черным (). Но мы немного отклонились от темы.

Здесь работает несколько иной принцип. Всякий раз, когда вы формируете селектор для CSS правила, всегда делайте его настолько специфичным (конкретным), насколько это возможно и оправданно. (). При рассмотрении простейшего примера, приведенного выше, вы, вероятно, сами догадались, что использование лишь имени класса .favorite для селектора, выбирающего требуемый напиток из списка, будет недостаточным. И это не позволит извлечь из общего списка «нужный напиток» для его дальнейшего форматирования. А если это все-таки каким-то образом сработало один раз, то нет никакой гарантии, что в будущем все пройдет так же гладко. Для достижения желаемого результата необходимо использовать более конкретный селектор:

ul#drinks li.favorite {
color: olive;
font-weight: bold;
}

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

html body div#content ul#dirnks li.favorite {
color: olive;
font-weight: bold;
}

Такой селектор тоже допусти́м, но он слишком «захламляет» CSS код, что значительно снижает его читабельность. К тому же от такой избыточности нет никакого толку. Существует и другой способ «вычленения» требуемого элемента, путем повышения значения CSS специфичности селектора .favorite при помощи декларации ! important:

.favorite {
color: olive! important;
font-weight: bold! important;
}

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

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

Один из классических примеров, которые я использую:

.last-block {
margin-right: 0! important;
}

Я применяю данный класс в тех случаях, когда на странице имеется несколько «плавающих» блоков (), которые размещаются в один ряд. При этом, назначая это имя класса для последнего в ряду блока (самого правого), я полностью исключаю ситуацию, когда он неплотно прилегает к границе контейнера, что в моем случае недопустимо. Даже если где-то в структуре CSS кода, в рамках правила с более специфичным (конкретным) селектором определены другие значения свойства margin-right для используемых блоков, то применение класса .last-block к крайним элементам позволит обнулить их. При этом мы не используем никаких дополнительных составляющих селектора, конкретизирующих его, что упрощает представление кода.

Подсчет значения CSS специфичности.

Рассматривая предыдущий пример, мы с вами выяснили, что наша первая попытка определения цвета и жирности шрифта для элемента списка провалилась из-за того, что мы использовали селектор лишь с одним именем класса, который имеет меньшее значение CSS специфичности и был переопределен селектором, выбирающим неупорядоченный список по его идентификатору ID, который имеет большее значение специфичности. Ключевыми значениями в данном случае являются имена классов (class) и идентификаторы элементов (ID). Очень важно знать, что CSS стандарты предусматривают существенные различия в весовых значениях специфичности для селекторов классов class и идентификаторов ID. Селекторы, использующие идентификаторы элементов, имеют безупречное преимущество над теми, в которых применяются лишь имена классов. При любом количестве имен классов в селекторе, он будет переопределен другим селектором, имеющим в своем составе один идентификатор элемента.

Теперь давайте схематически рассмотрим метод определения и записи значений CSS специфичности селекторов:

Другими словами:

  • Если в теге элемента предусмотрен атрибут style, то все определенные в его рамках свойства имеют максимальный приоритет (значение специфичности в этом случае получает высший разряд – 1,0,0,0).
  • Для каждого идентификатора элемента, используемого в рамках селектора прибавляется единица в соответствующий разряд специфичности – 0,1,0,0.
  • Каждое имя класса, а также псевдокласса или селектор атрибута (), присутствующий в селекторе правила добавляет единицу в следующий разряд специфичности – 0,0,1,0.
  • И последний, самый младший разряд, получает по единице за каждое, присутствующее в селекторе имя элемента – 0,0,0,1.

Вы можете избавиться от запятых и преобразовать значения CSS специфичности в более привычную для вас форму представления значений – обычные числа: 1,0,0,0 можно представить как 1000, что значительно больше значения 0,1,0,0 или 100. Используемые в этом случае запятые предназначены для четкого разделения значений различных разрядов специфичности. К примеру, если в CSS селекторе используется 13 имен классов, псевдоклассов и/или селекторов атрибутов (что маловероятно), то значение специфичности в этом случае может принять вид 0,1,13,4, что невозможно представить в десятичном виде.

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

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

Важные моменты.
  • Универсальный селектор * (звездочка) не имеет никакого значения специфичности.
  • Псевдоэлементы (к примеру, :first-line) относятся к классу элементов, то есть увеличивают последний разряд значения специфичности – 0,0,0,1 (в отличие от своих собратьев псевдоклассов, которые имеют больший вес – 0,0,1,0).
  • Псевдокласс :not сам по себе никак не влияет на значение специфичности, но его аргумент (значение в скобках) увеличивает соответствующий его типу разряд.
  • Директива ! important, следующая непосредственно за определенным CSS свойством, априори придает максимальное значение его специфичности. Она отменяет действие даже тех свойств, которые указаны в inline-атрибуте ‘class’ тега элемента. Единственный способ переопределения свойства с директивой ! important — это создание нового правила, содержащего то же свойство и декларацию ! important, которое находится ниже в CSS коде. К тому же, второе правило должно иметь равное или большое значение специфичности, чем первое (которое необходимо отменить). Другими словами, для директивы ! important можно определить еще один разряд в значении специфичности – 1,0,0,0,0, хотя такой ее записи, конечно же, не существует.

Post Views: 937

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

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

Специфичность селекторов (selector’s specificity) определяет их приоритет в таблице стилей. Чем специфичнее селектор, тем выше его приоритет. Для вычисления специфичности селектора используются три группы чисел (a, b, c), расчёт производится следующим образом:

  • Считается число идентификаторов в селекторе (группа a)
  • Считается число селекторов классов, атрибутов и псевдо-классов в селекторе (группа b)
  • Считается число селекторов типа и псевдо-элементов в селекторе (группа c)
  • Селектор внутри псевдо-класса отрицания (:not) считается как любой другой селектор, но сам псевдо-класс отрицания не участвует в вычислении селектора
  • Универсальный селектор (*) и комбинаторы не участвуют в вычислении веса селектора

В примере ниже селекторы расположены в порядке увеличения их специфичности:


*               /* a=0 b=0 c=0 -> специфичность =   0 */
li              /* a=0 b=0 c=1 -> специфичность =   1 */
ul li           /* a=0 b=0 c=2 -> специфичность =   2 */
ul ol+li        /* a=0 b=0 c=3 -> специфичность =   3 */
h2 + *[rel=up]  /* a=0 b=1 c=1 -> специфичность =  11 */
ul ol li.red    /* a=0 b=1 c=3 -> специфичность =  13 */
li.red.level    /* a=0 b=2 c=1 -> специфичность =  21 */
#x34y           /* a=1 b=0 c=0 -> специфичность = 100 */
#s12:not(p)     /* a=1 b=0 c=1 -> специфичность = 101 */

Самый высокий приоритет имеет число из группы «a», число группы «b» имеет средний приоритет, число из группы «c» имеет наименьший приоритет. Числа из разных групп не суммируются в одно общее, т.е. возьмём из примера последнюю строку со специфичностью селектора «101» — это не означает число «сто один», это значит, что был использован один селектор из группы «a» (идентификатор) и один селектор из группы «c» (селектор типа).

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


<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Название документа</title>
    <style>
      #one { color: red; }
      #two { color: blue !important; }
    </style>
  </head>
  <body>

    <p>Первый абзац</p>
    <p>Второй абзац.</p>

  </body>
</html>

Попробовать »

С этой темой смотрят:

Специфичность селекторов CSS / Песочница / Хабр

Хотелось бы расставить некоторые точки над i на тему специфичности селекторов в CSS.

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

— тег имеет специфичность 0001

— класс, а также псевдокласс и псевдоэлемент имеют специфичность 0010

— id имеет специфичностью 0100

— инлайновый стиль имеет приоритет 1000

Сразу возникает вопрос: десять классов в селекторе заменяют один id? В теории нет, но на практике, как было правильно указано в другом посте, в браузерах Firefox и Chrome его заменяет 256 классов, а в Opera 65536.

Ещё одну «пачку» уровней специфичности добавляет ключевое слово !important. В частности (в теории), получается, что инлайновый стиль с !important средствами CSS перебить невозможно. На самом деле, возможно.

Например, у вас есть такая разметка:

<span>зелёный текст</span>

Как изменить цвет текста средствами CSS? Его просто нужно анимировать:

@-webkit-keyframes more_important {0%{color: red;} 100%{color: red;}}
@-moz-keyframes more_important {0%{color: red;} 100%{color: red;}}
@-o-keyframes more_important {0%{color: red;} 100%{color: red;}}
@keyframes more_important {0%{color: red;} 100%{color: red;}}

.some__class
{
	-webkit-animation: more_important 1s infinite;
	-moz-animation: more_important 1s infinite;
	-o-animation: more_important 1s infinite;
	animation: more_important 1s infinite;
}

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

Но есть одно исключение: системные CSS в браузерах Firefox и Opera, в которых присутствует !important, никакими методами перебить нельзя. Например, многим известен системный хардкод:

input
{
	line-height: normal !important;
}

Причём, в указанном примере, normal разный в Firefox и Opera.

Каскадирование | htmlbook.ru

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

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

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

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

Как задавать пользовательский стиль рассказывалось в главе 1 (см. рис. 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. Цвет списка

HTML5CSS 2.1IECrOpSaFx

<!DOCTYPE HTML>
<html>
 <head>
  <meta charset="utf-8">
  <title>Список</title>
  <style>
   #menu ul li {
    color: green;
   }
   .two {
    color: red;
   }
  </style>
 </head>
 <body>
  <div>
   <ul>
    <li>Первый</li>
    <li>Второй</li>
    <li>Третий</li>
   </ul>
  </div>
 </body> 
</html>

В данном примере цвет текста списка задан зелёным, а второй пункт списка с помощью класса 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?

  1. 14
  2. 22
  3. 23
  4. 32
  5. 41

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

  1. 301
  2. 203
  3. 121
  4. 40
  5. 31

Ответы

1. 23

2. 121

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

Если у вас есть два (или более) конфликтующих правила CSS, относящихся к одному и тому же элементу, то для определения более приоритетного, браузеры используют определенные критерии отбора.

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

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


p {
   color: red;
}

p {
   color: blue;
}

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

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


div p {
   color: red;
}

p {
   color: blue;
}

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

Реальная специфичность группы вложенных селекторов определяется на основании некоторых вычислений. По существу, каждому селектору идентификатора («#имя») присваивается значение 100, каждому селектору класса («.имя») – значение 10 и каждому HTML селектору («имя») – значение 1. Затем происходит сложение значений вложенных селекторов.

  • p – специфичность 1 (1 селектор имени)
  • div p — специфичность 2 (2 селектора имени; 1+1)
  • .tree – специфичность 10 (1 селектор класса)
  • div p.tree – специфичность 12 (2 селектора имени

Приоритетность селекторов в CSS (специфичность селекторов, selector’s specificity)

Введение в использование CSS селекторов

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


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

Открыв 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
li0-0-0-14
li:first-line0-0-0-24
ul li0-0-0-24
ul ol+li0-0-0-34
form + *[type=text]0-0-1-13, 4
table tr td.second0-0-1-33, 4
h3.block.title.0-0-2-13, 4
#xyz0-1-0-02
style=» »1-0-0-01
Пример специфичности — правило №1:

<head>
<style type="text/css">
    #summary { color: red }
</style>
</head>
<body>
    <p>content</p>
</body>

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

Правило №2:

<head>
    <style type="text/css">
        #second { color:green; }
        ul li.second { color:blue; }
    </style>
</head>
<body>
    <ul>
        <li>first</li>
        <li>second</li>
    </ul>
</body>

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

Правило №3:

<head>
    <style type="text/css">
       input[type=text] { font-weight:bold; }
       form input { font-weight:normal; }
    </style>
</head>
<body>
    <form action="" method="post">
        <input type="text" name="Company" />
        <input type="submit" name="Ok" />
    </form>
</body>

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

Вернемся к первому примеру этой статьи — правило №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

Если Вам понравилась статья, проголосуйте за нее

Голосов: 35
Голосовать  

Специфика CSS


Что такое специфичность?

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

Думайте о специфичности как о балле / ранге, который определяет, какие декларации стиля
в конечном итоге применяются к элементу.

Универсальный селектор (*) имеет низкую специфичность, в то время как селекторы ID очень
конкретный!

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


Иерархия специфичности

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

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

.

ID — ID — это уникальный идентификатор для элементов страницы, таких как
#navbar.

Классы, атрибуты и псевдоклассы — Эта категория
включает .классы, [атрибуты] и псевдоклассы, такие как: hover,: focus и т. д.

Элементы и псевдоэлементы — В эту категорию входят
имена элементов и псевдоэлементы, такие как h2, div,: before и: after.


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

Запомните, как рассчитывать специфичность!

Начать с 0, добавить 1000 для стиля
атрибут, добавьте 100 для каждого идентификатора, добавьте 10 для каждого атрибута, класса или
псевдокласс, добавьте 1 для каждого имени элемента или псевдоэлемента.

Рассмотрим эти три фрагмента кода:

Пример

A: h2
B: #content h2
C:

Заголовок

Специфичность A равна 1 (один элемент)
Специфичность B равна
101 (одна ссылка ID и один элемент)
Специфичность C — 1000 (встроенный стиль)

Поскольку 1 <101 <1000, третье правило (C) имеет больший уровень специфичность, и поэтому будет применяться.



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

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

последнее правило применяется всегда.


Селекторы ID имеют более высокую специфичность, чем селекторы атрибутов
— Посмотрите на следующие три строки кода:

Пример

div # a {background-color: green;}
#a {background-color: yellow;}
div [id = a] {background-color: blue;}

Попробуйте сами »

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


Контекстные селекторы более специфичны, чем отдельный элемент
selector —
Встроенная таблица стилей ближе к элементу, который нужно стилизовать. Так что в
следующая ситуация

Пример

Из внешнего файла CSS:
#content h2 {background-color: red;}


В файле HTML:

будет применяться последнее правило.


Селектор класса превосходит любое количество селекторов элементов — селектор класса, такой как .intro, превосходит h2, p, div и т. Д .:


Универсальный селектор и унаследованные значения имеют специфичность 0 — *,
body * и подобные имеют нулевую специфичность. Унаследованные значения также имеют
специфичность 0.

.Специфика CSS

— Standardista

Некоторых людей смущает специфика CSS, особенно со всеми (не очень) новыми селекторами CSS3. Изображение ниже может помочь понять специфику CSS. Скачать PDF

Легенда:

  • X-0-0: количество селекторов идентификаторов, представленных Sharks
  • 0-Y-0: количество селекторов классов, селекторов атрибутов и псевдоклассов, представленных Fish
  • .

  • 0-0-Z: количество селекторов типов и псевдоэлементов, представленных Plankton a la Spongebob
  • *: универсальный селектор не имеет значения
  • +,>, ~: комбинаторы, хотя они позволяют более конкретное нацеливание элементов, они не увеличивают значения специфичности
  • : not (x): селектор отрицания не имеет значения, но переданный аргумент увеличивает специфичность

CSS SpeciFISHity

Вы можете скачать PDF-файл с рыбной спецификой CSS здесь

Specificity определяет, какое объявление свойства CSS применяется, когда два или более объявления применяются к одному и тому же элементу с конкурирующими объявлениями свойств.Самый конкретный селектор имеет приоритет. Если специфичность равна, последнее объявление в исходном порядке имеет приоритет. Понимая специфику CSS, вы поймете, как браузер определяет, какое объявление является более конкретным и, следовательно, будет иметь приоритет. Возьмем для примера этот абзац:

 

Если вы знакомы с CSS, вы, вероятно, хорошо знакомы с CSS и особенностями этих трех строк:

 #myDiv {color: red;} 1-0-0
.myClass {color: blue;} 0-1-0
p {color: yellow;} 0-0-1 

Блок стиля содержит три правила стиля, у которых есть селектор, соответствующий абзацу. Если бы единственной проблемой были каскад или порядок источников, абзац был бы желтым. Однако разные селекторы имеют разный вес. Идентификатор имеет приоритет перед селектором класса, имеет приоритет перед селектором типа. Итак, абзац будет красным.

С селекторами CSS3 порядок еще более важен, как и понимание специфики:

 с.= 'мой'] {color: blue;} 0-1-1
p: nth-of-type (1n) {color: yellow;} 0-1-1 

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

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

  1. ! Important: Любое объявление свойства с термином! Important имеет наивысший приоритет, даже по сравнению со встроенными стилями. Если! Important объявлено более одного раза в конфликтующих свойствах, нацеленных на один и тот же элемент, вы, автор CSS, будете застрелены, и будут действовать другие правила приоритета.Это как если бы вес селектора с объявлением! Important был 1-X-A-B-C, только для этого свойства (где A, B и C — фактические значения родительского селектора, как описано ниже). Из-за этого не следует использовать important, но он может быть полезен при отладке.
  2. style = ”” : если автор включает в элемент атрибут style , встроенный стиль будет иметь приоритет над любыми стилями, объявленными во внешней или встроенной таблице стилей, кроме объявлений! Important.Просто скажи, что любого, кто использует в производстве style , тоже следует застрелить. Обратите внимание, что стили, добавленные с помощью свойства JavaScript style (т.е. document.getElementById ('myID'). Style.color = 'purple'; ), фактически создают встроенный стиль ( ...... ) . Вес style = ”” равен 1-0-0-0.
  3. id: Среди селекторов, которые вы фактически включите в свою таблицу стилей, идентификаторы имеют наивысшую специфичность. Вес селектора идентификатора составляет 1-0-0 на каждый идентификатор.
  4. класс / псевдокласс / атрибуты : Как показано во втором блоке кода выше, все селекторы классов, селекторы атрибутов и псевдоклассы имеют одинаковый вес 0-1-0.
  5. type : Селекторы типа элемента и псевдоэлементы, например: first-letter или: after, имеют наименьшее значение с точки зрения специфичности с 0-0-1 для каждого элемента.

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

Расчет специфичности

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

Используя выражение X-Y-Z

  • Чтобы вычислить X, подсчитайте количество атрибутов ID в селекторе.
  • Чтобы вычислить Y, подсчитайте количество классов, селекторов атрибутов и псевдоклассов в селекторе. Не считать: нет, но подсчитывать селекторы, переданные в качестве аргумента в селекторе: not (X-Y-Z).
  • Для вычисления Z подсчитайте количество имен элементов и псевдоэлементов в селекторе.

Например, если у вас есть 1 идентификатор, 12 класс / псевдокласс / атрибуты и 5 типов, вы больше не объявляете свои селекторы, но значение будет 1-12-5. Обратите внимание, что окончательное значение X-Y-Z — это не число, а матрица. Независимо от того, сколько у вас есть селекторов классов, атрибутов и псевдоклассов, один идентификатор превзойдет их. Если вы воспользуетесь примером speciFISHity, никакое количество планктона (элементов) никогда не побьет рыбу (класс).Никакая рыба не победит акулу (id). Not Shark может победить нефтяной танкер (встроенный), и даже нефтяной танкер погибнет от ядерного взрыва. Да, я на тебя напал!

Менее очевидные вещи:

  • Селектор * или глобальный селектор не имеет значения. * .myClass будет перезаписан p.myClass, даже если он будет последним в каскаде.
  • Комбинаторы, такие как ~,> и +, не имеют значения при взвешивании селекторов. Да, они помогают более точно определить, на что вы нацелены, но могут быть заменены другим селектором с таким же весом.
     ul> li {color: red;} 0-0-2
    ul li {color: blue;} 0-0-2 

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

  • : не имеет значения, но селекторы без селектора отрицания имеют
     li.myClass {color: red;} 0-1-1
    li: not ([title]) {color: blue;} 0-1-1 

    Оба вышеуказанных элемента имеют одинаковый вес, потому что мы считаем селектор атрибутов, а не: not в синем объявлении.

  • Специфичность не передается по наследству. Если вы объявите 27 значений в родительском элементе абзаца и даже добавите! Important, но объявите абзац отдельно, будет применено свойство, объявленное для элемента. Наследование не отменяет таких заявлений.
     & ltldiv> 

    Hi & lt / p>

    div # y.y {цвет: красный;} 1-1-0 p {color: blue;} 0-0-1

    Абзац будет синим, а не красным, так как, хотя первое объявление является более конкретным и цвета наследуются, второе объявление фактически применяется к элементу, тогда как первое применяется к родительскому элементу.Цвет наследуется только в том случае, если он специально не объявлен для потомка. И в этом случае он декларируется.

.

селекторов CSS — специфика CSS или наследование?

Переполнение стека

  1. Около
  2. Продукты

  3. Для команд
  1. Переполнение стека
    Общественные вопросы и ответы

  2. Переполнение стека для команд
    Где разработчики и технологи делятся частными знаниями с коллегами

  3. Вакансии
    Программирование и связанные с ним технические возможности карьерного роста

  4. Талант
    Нанимайте технических специалистов и создавайте свой бренд работодателя

  5. Реклама
    Обратитесь к разработчикам и технологам со всего мира

.

Инструмент для проверки специфики CSS

Переполнение стека

  1. Около
  2. Продукты

  3. Для команд
  1. Переполнение стека
    Общественные вопросы и ответы

  2. Переполнение стека для команд
    Где разработчики и технологи делятся частными знаниями с коллегами

  3. Вакансии
    Программирование и связанные с ним технические возможности карьерного роста

  4. Талант
    Нанимайте технических специалистов и создавайте свой бренд работодателя

  5. Реклама
    Обратитесь к разработчикам и технологам со всего мира

  6. О компании

Загрузка…

  1. Авторизоваться
    зарегистрироваться

  2. текущее сообщество

.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *