CSS 優先級淺析

前言

層疊樣式表 CSS 做爲 Web 重要組成部分,開發人員的關注點大多在於複雜的視覺效果、惆悵的瀏覽器兼容性、脆弱的可維護性,而對於最基本的層疊優先級規則,每每如同霧裏看花,人云亦云,甚至產生原則性謬誤,本文基於規範文檔,嘗試理清脈絡。css

層疊樣式

所謂層疊,跳過晦澀定義,簡單理解爲,瀏覽器爲特定元素,不一樣來源的屬性聲明,選擇優先級最高的終值。html

優先級排序依次以下:web

Origin and Importance

規則聲明來源(Origin)分爲如下部分:chrome

  • user agent declarations - 瀏覽器預設樣式
  • user declarations - 用戶手動預設樣式,部分瀏覽器不支持
  • author declarations - 開發人員設定樣式
  • Animation - 動畫插幀
  • Transition - 過渡效果插幀

Importance 暨使用關鍵字 !important 聲明規則。瀏覽器

優先級排序以下:網絡

  1. Transition declarations
  2. Important user agent declarations
  3. Important user declarations
  4. Important author declarations
  5. Animation declarations
  6. Normal author declarations
  7. Normal user declarations
  8. Normal user agent declarations

通常狀況下,僅考慮瀏覽器預設樣式,開發者設定樣式便可,終端用戶樣式不歸入考慮。動畫

Scope

經過 scoped style element 聲明的樣式,僅對其父元素範圍內生效。若是存在嵌套關係,優先級順序以下:ui

  1. Important ansestor declarations
  2. Important descendant declarations
  3. Normal descendant declarations
  4. Normal ansestor declarations

unscoped declarations 能夠理解做用域爲 root elementstyle attribute declarations 能夠理解做用域爲元素自己,style attribute important declarations 理解做用域爲 root elementspa

<div class="outer">
  <style scoped> .success { color: purple; } </style>
  <ul class="base">
    <li class="success">success</li>
    <li class="success">success</li>
    <li class="success">success</li>
  </ul>
  <div class="inner">
    <style scoped> .success { color: yellow; } </style>
    <ul class="base">
      <li class="success">success</li>
      <li class="success">success</li>
      <li class="success">success</li>
    </ul>
  </div>
</div>
複製代碼

示例代碼 .success 大機率所有爲黃色,由於規範已刪除 scoped css,大部分瀏覽器已不支持。順便一提,經過工程化手段可以實現相似的功能。code

原始代碼:

<style scoped> .example { color: red; } </style>

<template>
  <div class="example">hi</div>
</template>
複製代碼

轉換後代碼:

<style> .example[data-v-f3f3eg9] { color: red; } </style>

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>
複製代碼

Specificity

選擇器的特異性由選擇器自己的成分肯定,計算規則以下:

  • 計數選擇器中 ID 選擇器數量 A
  • 計數選擇器中類選擇器、屬性選擇器、僞類選擇器數量 B
  • 計數選擇器中元素原則器、僞元素選擇器數量 C

選擇器特異性標記記爲:

P(S)=
  \begin{pmatrix}
  A & B & C \\
  \end{pmatrix}

比較時,按從左至右方向比較。

特殊場景須要特別注意:

  • 僞類選擇器 :is():not():has() 特異性爲參數選擇器列表中,特異性最高的選擇器特異性
  • 僞類選擇器 :nth-child(An+B [of S]?):nth-last-child(An+B [of S]?) 特異性爲參數選擇器列表中,特異性最高的選擇器特異性疊加普通僞類選擇器特異性
  • 僞類選擇器 :where() 特異性爲 0
  • 通配選擇器 * 特異性爲 0

舉例說明:

選擇器 特異性
#container .header (1, 1, 0)
#container section (1, 0, 1)
.container *:not(.header) (0, 2, 0)

Order of Appearance

位置靠後的樣式聲明優先級更高,包含兩點:

  • 單文件內樣式聲明順序
  • 多文件 @import()<style><link> 引入前後順序

擴展思考

理論基本介紹完畢,將理論應用於實踐纔是最終目的。

四參數比較法

選擇器優先級,可能看到的四參數版本:

  • 行內樣式聲明標誌位計爲 A
  • 計數選擇器中 ID 選擇器數量 B
  • 計數選擇器中類選擇器、屬性選擇器、僞類選擇器數量 C
  • 計數選擇器中元素原則器、僞元素選擇器數量 D
A =
\begin{cases}
1,  & \text{行內樣式} \\
0, & \text{非行內樣式}
\end{cases}

比較時,按從左至右方向比較:

P(S)=
  \begin{pmatrix}
  A & B & C & D \\
  \end{pmatrix}

延伸出加權取和比較法:

P(S) = 1000 \times A + 100 \times B + 10 \times C + D

問題:如何看待這種比較方式

自動填充

部分瀏覽器支持表單自動填充,默認狀況下,填充後的輸入框樣式較爲醜陋,且與總體風格不搭,默認的效果基本以下(圖來自網絡):

Chrome 78 樣式聲明以下:

input:-internal-autofill-selected {
  background-color: rgb(232, 240, 254) !important;
  background-image: none !important;
  color: rgb(0, 0, 0) !important;
}
複製代碼

Safari 13 樣式聲明以下:

input:-webkit-autofill,
input:-webkit-autofill-strong-password {
  background-color: rgb(250, 255, 189);
  background-image: none;
  color: rgb(0, 0, 0);
}
複製代碼

問題:如何處理瀏覽器預設醜不拉幾的自動填充效果?

其它

  • 如何覆蓋依賴庫引入的樣式?
  • 如何避免複雜的優先級計算?
  • 如何在多人協做項目中維護樣式?

參考連接

相關文章
相關標籤/搜索