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

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

Под наследованием в CSS понимается передача CSS-свойств, применённых к одному тегу, его дочерним тегам. Рассмотрим следующую HTML-структуру:

<div>
    <p></p>
</div>

Если<div>имеет свойствоcolor: red, то это свойство будет<p>унаследовано, то есть<p>также имеет свойствоcolor: red。

Как видно из вышесказанного, когда веб-страница относительно сложна, а HTML-структура глубоко вложена, на стиль тега сильно влияют стили его тегов-предков. Правило влияния таково:

Правило приоритета CSS 1:Стиль ближайшего предка имеет более высокий приоритет, чем стили других предков.

Пример 1:

<!-- 类名为 son 的 div 的 color 为 blue -->
<div style="color: red">
    <div style="color: blue">
        <div class="son"></div>
    </div>
</div>

Если мы назовём свойства, которые тег наследует от своих предков, но не имеет сам, «стилями предков», то «прямые стили» — это свойства, которыми тег владеет непосредственно. Существует также следующее правило:

Правило приоритета CSS 2:«Прямые стили» имеют более высокий приоритет, чем «стили предков».

Пример 2:

<!-- 类名为 son 的 div 的 color 为 blue -->
<div style="color: red">
    <div class="son" style="color: blue"></div>
</div>

Приоритет селекторов

Выше мы обсудили свойства, которые тег наследует от предков; теперь давайте обсудим свойства, которые тег имеет сам. Прежде чем обсуждать приоритет CSS, сначала поговорим о 7 основных селекторах CSS:

  • Селектор ID, например, #id{}

  • Селектор класса, например, .class{}

  • Селектор атрибута, например, a[href="segmentfault.com.html"]{}

  • Селектор псевдокласса, например, :hover{}

  • Селектор псевдоэлемента, например, ::before{}

  • Селектор тега, например, span{}

  • Универсальный селектор, например, *{}

Правило приоритета CSS 3:Соотношение приоритетов: встроенные стили > селекторы ID > селекторы классов = селекторы атрибутов = селекторы псевдоклассов > селекторы тегов = селекторы псевдоэлементов

Пример 3:

// HTML
<div class="content-class" id="content-id" style="color: black"></div>

// CSS
#content-id {
    color: red;
}
.content-class {
    color: blue;
}
div {
    color: grey;
}

Итоговый цвет — чёрный, потому что встроенные стили имеют более высокий приоритет, чем другие селекторы.

Все CSS-селекторы состоят из вышеперечисленных 7 базовых селекторов или их комбинаций. Существует 3 способа их объединения:

  • Селектор потомка: .father .child{}

  • Дочерний селектор: .father > .child{}

  • Селектор смежного родственного элемента: .bro1 + .bro2{}

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

Правило приоритета CSS 4:Подсчитайте количество ID-селекторов в селекторе (a), подсчитайте сумму количества селекторов классов, селекторов атрибутов и селекторов псевдоклассов в селекторе (b), а также подсчитайте сумму количества селекторов тегов и селекторов псевдоэлементов в селекторе (c). Сравните значения в порядке a, b и c; большее значение имеет более высокий приоритет, а если они равны, сравните следующее. Если у двух селекторов в итоге значения a, b и c равны, то судите по «принципу ближайшего».

Пример 4:

// HTML
<div id="con-id">
    <span class="con-span"></span>
</div>

// CSS
#con-id span {
    color: red;
}
div .con-span {
    color: blue;
}

Как видно из правила 4, цвет <span> — красный.

Что произойдет, если стили во внешней и внутренней таблицах стилей конфликтуют? Это связано с положением таблицы стилей в HTML-файле. Чем ниже позиция, в которой применяется стиль, тем выше его приоритет; фактически это всё ещё можно объяснить правилом 4.

Пример 5:

// HTML
<link rel="stylesheet" type="text/css" href="style-link.css.html">
<style type="text/css">
@import url(style-import.css); 
div {
    background: blue;
}
</style>

<div></div>

// style-link.css
div {
    background: lime;
}

// style-import.css
div {
    background: grey;
}

С точки зрения порядка, внутренний стиль находится внизу и подключается последним, поэтому цвет фона <div> — синий.

В приведенном выше коде@import-директива должна стоять перед внутренним стилем, иначе импорт файла недействителен. Конечно, не рекомендуется использовать@importМетоды импорта CSSМетоды импорта CSS。

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

Правило приоритета CSS 5:Если после свойства указано!important, то свойство имеет наивысший приоритет. Если в оба вставлено!important, то для определения приоритета используйте правила 3 и 4.

Пример 6:

// HTML
<div class="father">
    <p class="son"></p>
</div>

// CSS
p {
    background: red !important;
}
.father .son {
    background: blue;
}

Хотя .father .son имеет больший вес, в свойстве background селектора p вставлено !important, поэтому фон <p> — красный.

Неверные утверждения

В процессе изучения CSS вы могли слышать выражение «весовое значение селектора»: вес ID-селектора равен 100, селектора класса — 10, селектора тега — 1, а затем их складывают и сравнивают. Хотя такой способ понимания на первый взгляд легко запомнить, на самом деле он неверен.

Например, есть два селектора:

.class1.class2.class3 ... (共11个类)
#id

Если вычислять методом «сложения», вы решите, что у первого вес 110, у второго 100, и первый должен победить. Но в действительности браузер выбирает стиль второго (с #id).

Почему? Потому что CSS не рассматривает веса селекторов как «десятичное сложение». Сравнение приоритетов в CSS по сути является иерархическим сравнением, которое можно понимать как сравнение четырёхзначных чисел:

  • Встроенные стили: 1,0,0,0
  • ID-селекторы: 0,1,0,0
  • Селекторы классов, селекторы атрибутов, псевдоклассы: 0,0,1,0
  • Селекторы тегов, псевдоэлементы: 0,0,0,1

Браузер сравнивает их слева направо, а не складывает. Сколько бы селекторов классов у вас ни было, они не смогут превзойти ID-селектор.

Поэтому перестаньте использовать метод «100+10+1». Вес — это не игра в сложение; это структурное иерархическое сравнение!