CSS
Каскадирование и специфика
Поиск…
замечания
Специфика CSS намеревается продвигать краткость кода, позволяя автору определять некоторые общие правила форматирования для широкого набора элементов, а затем переопределять их для определенного подмножества.
Каскадный
Каскадирование и специфичность используются вместе для определения конечного значения свойства стилизации CSS. Они также определяют механизмы разрешения конфликтов в наборах правил CSS.
Порядок загрузки CSS
Стили считываются из следующих источников, в следующем порядке:
- Таблица стилей User Agent (стили, предоставленные поставщиком браузера)
- Пользовательская таблица стилей (дополнительный стиль, который пользователь установил в своем браузере)
- Авторская таблица стилей (автор здесь означает создателя веб-страницы / веб-сайта)
- Возможно, один или несколько файлов
.css
- В элементе
<style>
документа HTML
- Возможно, один или несколько файлов
- Встроенные стили (в атрибуте
style
для HTML-элемента)
Браузер будет искать соответствующий стиль (ы) при рендеринге элемента.
Как разрешаются конфликты?
Когда только один набор правил CSS пытается установить стиль для элемента, тогда конфликта нет, и этот набор правил используется.
Когда несколько наборов правил находятся с конфликтующими настройками, сначала устанавливаются правила Спецификации, а затем каскадные правила используются для определения того, какой стиль использовать.
Пример 1 - Правила специфичности
.mystyle { color: blue; } /* specificity: 0, 0, 1, 0 */
div { color: red; } /* specificity: 0, 0, 0, 1 */
<div class="mystyle">Hello World</div>
Каким будет цвет текста? (наведите указатель мыши на ответ)
синий
Сначала применяются правила специфичности, и тот, который обладает наивысшей спецификой «выигрывает».
Пример 2 - Каскадные правила с идентичными селекторами
Внешний файл css
.class {
background: #FFF;
}
Внутренний css (в HTML-файле)
<style>
.class {
background: #000;
}
<style>
В этом случае, когда у вас одинаковые селектор, каскад срабатывает и определяет, что последний загружается «выигрывает».
Пример 3 - Правила каскада после правил специфичности
body > .mystyle { background-color: blue; } /* specificity: 0, 0, 1, 1 */
.otherstyle > div { background-color: red; } /* specificity: 0, 0, 1, 1 */
<body class="otherstyle">
<div class="mystyle">Hello World</div>
</body>
Каким будет цвет фона?
красный
После применения правил специфики все еще существует конфликт между синим и красным, поэтому каскадные правила применяются поверх правил специфичности. Каскадирование смотрит на порядок загрузки правил, будь то внутри того же .css
файла или в коллекции источников стиля. Последний загруженный переопределяет любые предыдущие. В этом случае .otherstyle > div
правило .otherstyle > div
.
Заключительная записка
- Селекторная специфика всегда имеет приоритет.
- Таблицы разборки стилей.
- Встроенные стили козырьки все.
Важное заявление!
!important
объявление используется, чтобы переопределить обычную специфику в таблице стилей, указав более высокий приоритет правилу. Его использование: property : value !important;
#mydiv {
font-weight: bold !important; /* This property won't be overridden
by the rule below */
}
#outerdiv #mydiv {
font-weight: normal; /* #mydiv font-weight won't be set to normal
even if it has a higher specificity because
of the !important declaration above */
}
Настоятельно рекомендуется избегать использования !important
(если это абсолютно необходимо), потому что это нарушит естественный поток правил CSS, который может привести к неопределенности в вашей таблице стилей. Также важно отметить, что, когда к одному и тому же правилу применяются несколько !important
деклараций для одного элемента, тот, который имеет более высокую специфичность, будет применен.
Вот несколько примеров, где использование !important
объявления может быть оправдано:
- Если ваши правила не должны быть переопределены любым встроенным стилем элемента, который написан внутри атрибута
style
элемента html. - Чтобы предоставить пользователю больше контроля над доступностью веб-страниц, например, увеличивать или уменьшать размер шрифта, переопределяя стиль автора, используя
!important
. - Для тестирования и отладки с использованием элемента проверки.
Смотрите также:
Вычисление специфики выбора
Каждый отдельный CSS-селектор имеет свое значение специфичности. Каждый селектор в последовательности увеличивает общую специфичность последовательности. Селекторы попадают в одну из трех различных групп специфичности: A , B и c . Когда несколько селекторных последовательностей выбирают данный элемент, браузер использует стили, применяемые последовательностью с наивысшей общей спецификой.
группа | Состоящий из | Примеры |
---|---|---|
селекторы id | #foo | |
В | селекторы классов Селекторы атрибутов псевдоклассы | .bar [title] , [colspan="2"] :hover :nth-child(2) |
с | селектор типа псевдо-элементы | div , li ::before , ::first-letter |
Группа А является наиболее конкретной, за ней следует группа B , а затем группа c .
Универсальный селектор ( *
) и комбинаторы (например, >
и ~
) не имеют специфики.
Пример 1: Специфичность различных селекторных последовательностей
#foo #baz {} /* a=2, b=0, c=0 */
#foo.bar {} /* a=1, b=1, c=0 */
#foo {} /* a=1, b=0, c=0 */
.bar:hover {} /* a=0, b=2, c=0 */
div.bar {} /* a=0, b=1, c=1 */
:hover {} /* a=0, b=1, c=0 */
[title] {} /* a=0, b=1, c=0 */
.bar {} /* a=0, b=1, c=0 */
div ul + li {} /* a=0, b=0, c=3 */
p::after {} /* a=0, b=0, c=2 */
*::before {} /* a=0, b=0, c=1 */
::before {} /* a=0, b=0, c=1 */
div {} /* a=0, b=0, c=1 */
* {} /* a=0, b=0, c=0 */
Пример 2. Какая специфика используется браузером
Представьте себе следующую реализацию CSS:
#foo {
color: blue;
}
.bar {
color: red;
background: black;
}
Здесь мы имеем селектор идентификаторов, который объявляет color
как синий , и селектор классов, который объявляет color
красным и background
черным .
#foo
элемента с идентификатором #foo
и классом .bar
будут выбраны обоими декларациями. Селекторы идентификаторов имеют специфику группы А, а селекторы классов имеют специфику группы В. Селектор ID перевешивает любое количество селекторов классов. Из-за этого color:blue;
из селектора #foo
и background:black;
из селектора .bar
будет применен элемент. Более высокая специфичность селектора ID приведет к тому, что браузер игнорирует .bar
color
селектора .bar
.
Теперь представьте себе другую реализацию CSS:
.bar {
color: red;
background: black;
}
.baz {
background: white;
}
Здесь у нас есть два класса селекторов; один из которых объявляет color
красным и background
черным , а другой объявляет background
белым .
.bar
этими объявлениями будут влиять элементы с .bar
и .baz
, однако проблема, которую мы имеем сейчас, состоит в том, что оба .bar
и .baz
имеют идентичную специфичность группы B. Каскадный характер CSS разрешает это для нас: поскольку .baz
определяется после .bar
, наш элемент заканчивается красным color
с .bar
а на белом background
с .baz
.
Пример 3: Как управлять спецификой
Последний фрагмент из примера 2, приведенный выше, можно использовать, чтобы обеспечить, чтобы наше .bar
color
селектора класса .bar
использовалось вместо селектора классов .baz
.
.bar {} /* a=0, b=1, c=0 */
.baz {} /* a=0, b=1, c=0 */
Наиболее распространенным способом достижения этого было бы выяснить, какие другие селекторы могут быть применены к последовательности селектора .bar
. Например, если .bar
класс был только когда - либо применительно к span
элементы, мы могли бы модифицировать .bar
селектор span.bar
. Это придало бы ему новую специфику Group C , которая могла бы переопределить .baz
селектора .baz
:
span.bar {} /* a=0, b=1, c=1 */
.baz {} /* a=0, b=1, c=0 */
Однако не всегда возможно найти другой общий селектор, который разделяется между любым элементом, который использует класс .bar
. Из-за этого CSS позволяет нам дублировать селекторы для повышения специфичности. Вместо простого .bar
, мы можем использовать .bar.bar
вместо этого (см . Грамматику селекторов, рекомендацию W3C ). Это по-прежнему выбирает любой элемент с классом .bar
, но теперь имеет двойную специфику Group B :
.bar.bar {} /* a=0, b=2, c=0 */
.baz {} /* a=0, b=1, c=0 */
!important
и встроенные декларации стиля
Считается, что !important
флаг в объявлении стиля и стилях, объявленных атрибутом style
HTML, имеет большую специфичность, чем любой селектор. Если они существуют, декларация стиля, на которую они влияют, будет отменять другие объявления независимо от их специфики. То есть, если у вас есть более одного объявления, которое содержит флаг !important
Important для того же свойства, который применяется к одному и тому же элементу. Тогда нормальные правила специфичности будут применяться к этим свойствам в отношении друг к другу.
Поскольку они полностью переопределяют специфику, использование !important
в большинстве случаев недооценивается. Его следует использовать как можно меньше. Чтобы код CSS был эффективным и поддерживаемым в долгосрочной перспективе, почти всегда лучше повышать специфику окружающего селектора, чем использовать !important
.
Одно из тех редких исключений, где !important
не !important
, заключается в реализации общих вспомогательных классов, таких как .hidden
или .background-yellow
, которые должны всегда переопределять один или несколько свойств везде, где они встречаются. И даже тогда вам нужно знать, что вы делаете. Последнее, что вы хотите, при написании поддерживающего CSS, - иметь !important
флаги в вашем CSS.
Заключительная записка
Распространенным заблуждением о специфичности CSS является то, что значения группы A , B и c должны быть объединены друг с другом ( a=1, b=5, c=1
=> 151). Это не так. Если бы это было так, то 20 селекторов группы B или c было бы достаточно, чтобы переопределить один селектор группы A или B соответственно. Эти три группы следует рассматривать как индивидуальные уровни специфичности. Специфичность не может быть представлена одним значением.
При создании таблицы стилей CSS вы должны поддерживать самую низкую специфичность. Если вам нужно сделать специфика немного выше, чтобы перезаписать другой метод, сделайте его выше, но как можно ниже, чтобы сделать его выше. Вам не нужно иметь такой селектор:
body.page header.container nav div#main-nav li a {}
Это делает будущие изменения более жесткими и загрязняет эту страницу css.
Вы можете рассчитать специфику вашего селектора здесь
Более сложный пример специфичности
div {
font-size: 7px;
border: 3px dotted pink;
background-color: yellow;
color: purple;
}
body.mystyle > div.myotherstyle {
font-size: 11px;
background-color: green;
}
#elmnt1 {
font-size: 24px;
border-color: red;
}
.mystyle .myotherstyle {
font-size: 16px;
background-color: black;
color: red;
}
<body class="mystyle">
<div id="elmnt1" class="myotherstyle">
Hello, world!
</div>
</body>
Какими границами, цветами и размерами шрифта будет текст?
размер шрифта:
font-size: 24;
, так как#elmnt1
правил#elmnt1
имеет самую высокую специфичность для рассматриваемого<div>
, каждое свойство здесь задано.
граница:
border: 3px dotted red;
,red
цвет границы берется из#elmnt1
правил#elmnt1
, так как он имеет самую высокую специфичность. Другие свойства границы, границы и стиля границы - из набора правилdiv
.
фоновый цвет:
background-color: green;
,background-color
устанавливается в наборахdiv
,body.mystyle > div.myotherstyle
и.mystyle .myotherstyle
. Специфические значения (0, 0, 1) против (0, 2, 2) против (0, 2, 0), поэтому средний выигрывает.
цвет:
color: red;
, Цвет задается в.mystyle .myotherstyle
правилdiv
и.mystyle .myotherstyle
. Последняя имеет более высокую специфичность (0, 2, 0) и «выигрывает».