CSS優先順序

qq_39509610發表於2020-12-07

瀏覽器通過優先順序來判斷哪一些屬性值與一個元素最為相關,從而在該元素上應用這些屬性值。優先順序是基於不同種類選擇器組成的匹配規則。

優先順序是如何計算的?

優先順序就是分配給指定的CSS宣告的一個權重,它由 匹配的選擇器中的 每一種選擇器型別的 數值 決定。

而當優先順序與多個CSS宣告中任意一個宣告的優先順序相等的時候,CSS中最後的那個宣告將會被應用到元素上。

當同一個元素有多個宣告的時候,優先順序才會有意義。因為每一個直接作用於元素的CSS規則總是會接管/覆蓋(take over)該元素從祖先元素繼承而來的規則。

注意: 文件樹中元素的接近度 (Proximity of elements) 對優先順序沒有影響。

選擇器型別

下面列表中,選擇器型別的優先順序是遞增的:

  1. 型別選擇器(type selectors)(例如, h1)和 偽元素(pseudo-elements)(例如, ::before)
  2. 類選擇器(class selectors) (例如,.example),屬性選擇器(attributes selectors)(例如, [type="radio"]),偽類(pseudo-classes)(例如, :hover)
  3. ID選擇器(例如, #example)

通配選擇符(universal selector)(*), 關係選擇符combinators) (+>~, ‘ ‘)  和 否定偽類(negation pseudo-class)(:not()) 對優先順序沒有影響。(但是,在 :not() 內部宣告的選擇器是會影響優先順序)。

給元素新增的內聯樣式 (例如, style="font-weight:bold") 總會覆蓋外部樣式表的任何樣式 ,因此可看作是具有最高的優先順序。.

例外的 !important 規則

當在一個樣式宣告中使用一個!important 規則時,此宣告將覆蓋任何其他宣告。雖然技術上!important與優先順序無關,但它與它直接相關。

使用 !important 是一個壞習慣,應該儘量避免,因為這破壞了樣式表中的固有的級聯規則 使得除錯找bug變得更加困難了。當兩條相互衝突的帶有 !important 規則的宣告被應用到相同的元素上時,擁有更大優先順序的宣告將會被採用。

一些經驗法則:

  • 一定要優化考慮使用樣式規則的優先順序來解決問題而不是 !important
  • 只有在需要覆蓋全站或外部 css(例如引用的 ExtJs 或者 YUI )的特定頁面中使用 !important
  • 永遠不要在全站範圍的 css 上使用 !important
  • 永遠不要在你的外掛中使用 !important
  • 取而代之,你可以:

  1. 更好地利用CSS級聯屬性
  2. 使用更具體的規則。在您選擇的元素之前,增加一個或多個其他元素,使選擇器變得更加具體,並獲得更高的優先順序。
    <div id="test">
      <span>Text</span>
    </div>
    div#test span { color: green }
    span { color: red }
    div span { color: blue }
  3. As a nonsense special case for (2), duplicate simple selectors to increase specificity when you have nothing more to specify.

無論你c​ss語句的順序是什麼樣的,文字都會是綠色的(green),因為這一條規則是最有針對性、優先順序最高的。(同理,無論語句順序怎樣,藍色(blue)的規則都會覆蓋紅色(red)的規則)

什麼的情況下可以使用 !important:

A) 一種情況

  1. 你的網站上有一個設定了全站樣式的CSS檔案,
  2. 同時你(或是你同事)寫了一些很差的內聯樣式。

在這種情況下,你就可以在你全域性的CSS檔案中寫一些!important的樣式來覆蓋掉那些直接寫在元素上的行內樣式。

活生生的例子比如:一些寫得很糟糕的 jQuery外掛裡面使用的內聯樣式。

B) 另一種情況

#someElement p { color: blue; } p.awesome { color: red; }

在外層有 #someElement 的情況下,你怎樣能使 awesome 的段落變成紅色呢?這種情況下,如果不使用 !important ,第一條規則永遠比第二條的優先順序更高

怎樣覆蓋 !important

A)很簡單,只需再新增一條 帶!important 的CSS規則,要麼給這個給選擇器更高的優先順序(新增一個標籤,ID或類);或是新增一樣選擇器,把它的位置放在原有宣告的後面(總之,最後定義一條規則比勝)。

一些擁有更高優先順序的例子:

table td    { height: 50px !important; }
.myTable td { height: 50px !important; }
 #myTable td { height: 50px !important; }

B)或者使用相同的選擇器,但是置於已有的樣式之後: 

td { height: 50px !important; }

C)或乾脆改寫原來的規則,以避免使用 ! important 。

瞭解更多資訊,訪問:

http://stackoverflow.com/questions/3706819/what-are-the-implications-of-using-important-in-css

http://stackoverflow.com/questions/9245353/what-does-important-in-css-mean

http://stackoverflow.com/questions/5701149/when-to-use-important-property-in-css

http://stackoverflow.com/questions/11178673/how-to-override-important

http://stackoverflow.com/questions/2042497/when-to-use-important-to-save-the-day-when-working-with-css

 

:not 偽類例外

:not 否定偽類在優先順序計算中不會被看作是偽類. 事實上, 在計算選擇器數量時還是會把其中的選擇器當做普通選擇器進行計數.

這是一塊CSS程式碼:

div.outer p {
  color:orange;
}
div:not(.outer) p {
  color: blueviolet;
}

當它被應用在下面的HTML時:

<div class="outer">
  <p>This is in the outer div.</p>
  <div class="inner">
    <p>This text is in the inner div.</p>
  </div>
</div>

會在螢幕上出現以下結果:

這裡寫圖片描述

基於形式的優先順序(Form-based specificity)

優先順序是基於選擇器的形式進行計算的。在下面的例子中,儘管選擇器*[id=”foo”] 選擇了一個ID,但是它還是作為一個屬性選擇器來計算自身的優先順序。

有如下樣式宣告:

* #foo {
  color: green;
}
*[id="foo"] {
  color: purple;
}

將其應用在下面的HTML中:

<p id="foo">I am a sample text.</p>

最終會出現下面的效果:

雖然匹配了相同的元素,但是 ID 選擇器擁有更高的優先順序。所以第一條樣式宣告生效。

無視DOM樹中的距離

有如下樣式宣告:

body h1 {
  color: green;
}
html h1 {
  color: purple;
}

當它應用在下面的HTML時:

<html>
<body>
  <h1>Here is a title!</h1>
</body>
</html>

瀏覽器會將它渲染成:

這裡寫圖片描述

直接給目標元素新增樣式和目標元素繼承樣式對比

為目標元素直接新增樣式,永遠比繼承樣式的優先順序高,無視優先順序的遺傳規則。

#parent {
  color: green;
}
h1 {
  color: purple;
}

當它應用在下面的HTML時:

<html>
<body id="parent">
  <h1>Here is a title!</h1>
</body>
</html>

瀏覽器會將它渲染成:

這裡寫圖片描述

因為 h1 選擇器明確的定位到了元素,但綠色選擇器的僅僅繼承自其父級。

相關文章