CSS入門8-三大特性之層疊特性與優先級

(注1:如果有問題歡迎留言探討,一起學習!轉載請注明出處,喜歡可以點個贊哦!)
(注2:更多內容請查看我的目錄。)

1. 簡介

所謂的層疊性與優先級,其實說白了可以理解為,不同的規則起沖突的情況下,聽誰的呢?有的時候這種沖突很容易解決,有的時候我們自己都難以決斷,比如好聲音三位導師都選你,該跟誰走呢。索性css給出了這些規則的優先級,不需要我們去苦惱。

2. 樣式作用情況

元素的樣式該如何去展現呢,首先看一下某個元素某個屬性可能作用樣式的情況:

  1. 沒有指定樣式(沒有內聯樣式也沒有選擇器選中指定樣式)
  2. 有唯一指定樣式(有內聯樣式或者選擇器選中,且只有一個規則作用于該屬性)
  3. 有多個樣式規則 (有內聯樣式或者選擇器選中,且不只一個規則作用于該屬性)

下面我們來詳細分析一下這三種情況。

3. 優先級分析

3.1 有唯一指定樣式的情況

我們先來看有唯一指定樣式的情況,因為,這種情況最簡單,就一個選擇,也別挑了,說啥就是啥。我們還是來大致看看。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test3.1</title>
    <style>
        p {
            color: blue;
        }
        .green {
            color: green;
        }
    </style>
</head>
<body>
<div>
    <div style="color: red">內聯唯一指定</div>
    <p>元素唯一指定</p>
    <div class="green">類唯一指定</div>
</div>
</body>
</html>

結論:若只有唯一指定樣式,以該樣式為準。

test3.1

3.2 多個樣式規則

多個樣式規則沖突,其實有很多種情況。還記得我們學過樣式引入方式有四種,涉及三種樣式,分別是內聯,內部和外部(參考CSS入門4-引入CSS)。首先我們來看只引入其中一種類型的情況下,出現沖突該如何解決。

3.2.1 僅有一種樣式類型的情況(內聯,內部或者外部)

3.2.1.1 僅有內聯

僅有內聯的情況下,要出現沖突,只可能是在style中多次對同一個屬性賦值。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test3.2.1.1</title>
</head>
<body>
<div style="color: red;color: blue;">
    僅有內聯,誰在后面,誰優先
</div>
</body>
</html>
3.2.1.1

看上圖,審查一下元素,可以看到該元素樣式中,前面的red被覆蓋了,color最后的取值是blue。最右邊文字的顏色確實也是藍色。

結論:只有內聯樣式,后面的屬性賦值優先級大于前面的屬性賦值。

3.2.1.2 僅有內部樣式

內部樣式,已經可以選擇多種選擇器來指定樣式。所以,這里情況比內聯會復雜很多。首先來復習一下選擇器的種類,可以參考CSS入門5-選擇器。這么多的選擇器類型和組合關系,可能都會產生沖突,這個時候怎么辦呢,想想都復雜,我們繼續拆分問題。將選擇器分為四類:

  1. 常用選擇器,包括元素選擇器,類選擇器,id選擇器和屬性選擇我器
  2. 偽類選擇器和偽元素選擇器
  3. 關系選擇器
  4. 通配選擇器
3.2.1.2.1 常用選擇器
3.2.1.2.1.1 同一類選擇器(包括同一個選擇器)先后沖突
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test3.2.1.2.1.1</title>
    <style>
        .text-color-black {
            color: black;
        }
        .text-color-red {
            color: red;
        }
        p {
            color: blue;
        }
        p {
            color: green;
        }
    </style>
</head>
<body>
<div class="text-color-black text-color-red">red</div>
<div class="text-color-red text-color-black">red</div>
<p>green</p>
</body>
</html>
3.2.1.2.1.1

可以看到div中兩個類對顏色的定義沖突時,不管class定義的順序如何,以style中類的順序為準,后面的覆蓋前面的樣式。如果是同一選擇器,也是后者覆蓋前者,這種情況可以涵蓋在同類選擇器的情況下。

結論:同類型選擇器(類型一樣,即同為元素選擇器,類選擇器,id選擇器或者屬性選擇器),按style中的先后順序,后者優先級更高。

3.2.1.2.1.2 不同類選擇器相互沖突
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test3.2.1.2.1.2</title>
    <style>
        #test {
            color: orange;
        }
        .text-color-red {
            color: red;
        }
        [otitle='test'] {
            color: purple;
        }
        div {
            color: grey;
        }
        [otitle='testReverse'] {
            color: purple;
        }
        .text-color-red-reverse {
            color: red;
        }
        #testReverse {
            color: orange;
        }
    </style>
</head>
<body>
<div class="text-color-red" id="test" otitle="test">從上到下,id,類,屬性和元素pk,id贏</div>
<div class="text-color-red-reverse" id="testReverse" otitle="testReverse">從下到上,id,類,屬性和元素pk,id贏</div>
<div otitle="test" class="text-color-red">從上到下,類,屬性和元素pk,屬性贏</div>
<div otitle="testReverse" class="text-color-red-reverse">從下到上,類,屬性和元素pk,類贏</div>
<div class="text-color-red">從上到下類和元素pk,類贏</div>
<div class="text-color-red-reverse">從下到上類和元素pk,類贏</div>
<div otitle="test">從上到下屬性和元素pk,屬性贏</div>
<div otitle="testReverse">從下到上屬性和元素pk,屬性贏</div>
</body>
</html>
test3.2.1.2.1.2

我們選擇正反兩種順序,來看不同選擇器之間的比較。首先,四種選擇器在一起時,id選擇器獲勝。然后排除id選擇器,剩余三種選擇器比較時,類和屬性誰在下邊誰贏,也就是后者覆蓋前者。最后,元素分別與類和屬性比較,發現元素都輸了。

結論:id > (類和屬性) > 元素,類和屬性同級,遵循同級元素后者覆蓋前者的規則。

注:查看某個元素樣式的時候,調試窗口是按照優先級規則從小到大往上排的,越往上的規則優先級越高,對同個屬性的樣式規定將會覆蓋下面低優先級的樣式規定。

3.2.1.2.2 偽類選擇器和偽元素選擇器
3.2.1.2.2.1 偽類選擇器
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test3.2.1.2.1.2-1</title>
    <style>
        #test {
            color: red;
        }
        #targetone {
            color: red;
        }
        .test {
            color: orange;
        }
        [otitle] {
            color: purple;
        }
        a {
            color: blue;
        }
        input {
            color: blue;
        }
        :link {
            color: green;
        }
        :hover {
            color: black;
        }
        :target {
            color: yellow;
            background: darkblue;
        }
        :disabled {
            color: grey;
        }
        :first-child {
            color: aqua;
        }
        :last-child {
            color: aqua;
        }
    </style>
</head>
<body>
<div>
    <a href="#targetone" id="test" class="test" otitle>123</a>
    <br>
    <input class="test" value="targettwo">
    <br>
    <input id="targetone" class="test" disabled="disabled" value="targetone">
</div>
</body>
</html>

注:要想在調試器看到動態偽類效果,需要在styles中勾選該效果。


3.2.1.2.2.1-1.1

3.2.1.2.2.1-1.2錨點未點擊

3.2.1.2.2.1-1.3錨點已點擊

看上面示例,我們在style內先按id,類,屬性,元素,靜態偽類(只應用于超鏈接),動態偽類(可應用于任何元素),目標偽類:target(IE8-不支持,匹配錨點對應的目標元素),UI元素偽類(IE8-不支持),結構偽類(IE8-不支持)的順序指定規則。結果發現其表現如下:

a:id > 結構偽類 > 動態偽類 > 靜態偽類 > 屬性 > 類 > 元素 > 瀏覽器默認屬性 > 繼承屬性

input:id > 結構偽類 > UI元素偽類 > 目標偽類 > 動態偽類 > 類 > 元素 > 瀏覽器默認屬性 > 繼承屬性

我們合并一下這兩個結論,有如下結論:

3.2.1.2.2.1-1 id > 結構偽類 > UI元素偽類 > 目標偽類 > 動態偽類 > 靜態偽類 > 屬性 > 類 > 元素 > 瀏覽器默認屬性 > 繼承屬性
(當然,需要注意的是,并不是每個元素都有這些屬性的)

然后,我們將style內各規則倒序一下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test3.2.1.2.1.2-2</title>
    <style>
        :last-child {
            color: aqua;
        }
        :first-child {
            color: aqua;
        }
        :disabled {
            color: grey;
        }
        :target {
            color: yellow;
            background: darkblue;
        }
        :hover {
            color: black;
        }
        :link {
            color: green;
        }
        input {
            color: blue;
        }
        a {
            color: blue;
        }
        [otitle] {
            color: purple;
        }
        .test {
            color: orange;
        }
        #targetone {
            color: red;
        }
        #test {
            color: red;
        }
    </style>
</head>
<body>
<div>
    <a href="#targetone" id="test" class="test" otitle>123</a>
    <br>
    <input class="test" value="targettwo">
    <br>
    <input id="targetone" class="test" disabled="disabled" value="targetone">
</div>
</body>
</html>
3.2.1.2.2.1-2.1

3.2.1.2.2.1-2.2錨點未點擊

3.2.1.2.2.1-2.3錨點已點擊

結果發現其表現如下:

a:id > 類 > 屬性 > 靜態偽類 > 動態偽類 > 結構偽類 > 元素 > 瀏覽器默認屬性 > 繼承屬性

input:id > 類 > 動態偽類 > 目標偽類 > UI元素偽類 > 結構偽類 > 元素 > 瀏覽器默認屬性 > 繼承屬性

我們合并一下這兩個結論,有如下結論:

3.2.1.2.2.1-2 id > 類 > 屬性 > 靜態偽類 > 動態偽類 > 目標偽類 > UI元素偽類 > 結構偽類 > 元素 > 瀏覽器默認屬性 > 繼承屬性

綜合3.2.1.2.2.1-1和3.2.1.2.2.1-2來看,我們再次驗證了類和屬性同級,并且發現它們和偽類也是同級的。有如下結論:

結論:id > (類,屬性,偽類) > 元素,類,屬性和偽類同級,遵循同級元素后者覆蓋前者的規則。

3.2.1.2.2.2 偽元素選擇器

偽元素,說是元素,但又不是真實的元素,是一個虛擬的元素。如何詳細理解這段話呢,我們來看一下下面這個例子。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test3.2.1.2.2.2</title>
    <style>
        :first-child {
            color: red;
        }
        :last-child {
            color: red;
        }
        p:before {
            content: 'abc';
            color: blue;
        }
        p:after {
            content: 'def';
            color: purple;
        }
        :hover {
            color: black;
        }
    </style>
</head>
<body>
<div>
    <p>123</p>
    <p>456</p>
</div>
</body>
</html>

3.2.1.2.2.2-1

3.2.1.2.2.2-2

從上面兩幅圖可以看出,偽元素其實是在元素內容內虛擬創建了一個元素,且無法被其他選擇器選取。所以對于偽元素的樣式,不用考慮優先級

3.2.1.2.3 關系選擇器
3.2.1.2.3.1 社群關系-分組選擇器
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test3.2.1.2.3.1</title>
    <style>
        .test01 {
            color: red;
        }
        .test02 {
            color: black;
        }
        .test01, .test02 {
            color: blue;
        }
        .test03, .test04 {
            color: blue;
        }
        .test03 {
            color: red;
        }
        .test04 {
            color: black;
        }
    </style>
</head>
<body>
<div>
    <div class="test01 test02">123</div>
    <div class="test03 test04">123</div>
</div>
</body>
</html>

3.2.1.2.3.1-1

3.2.1.2.3.1-2

以上兩圖可以看到,社群關系不會影響其本身的權重,即同時指定多個選擇器和單獨指定這些選擇器效果一樣。

3.2.1.2.3.2 親戚關系
3.2.1.2.3.2.1 不同關系類型的比較
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.2.1.2.3.2.1-1</title>
    <style>
        div p {
            color: red;
        }
        div > p {
            color: orange;
        }
        p ~ p {
            color: blue;
        }
        p + p {
            color: green;
        }
    </style>
</head>
<body>
<div>
    <p>123</p>
    <p>456</p>
</div>
</body>
</html>
3.2.1.2.3.2.1-1

先按后代,子代,通用兄弟,相鄰兄弟在style中排序,發現后面的優先級高。然后順序反過來:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.2.1.2.3.2.1-2</title>
    <style>
        p + p {
            color: green;
        }
        p ~ p {
            color: blue;
        }
        div > p {
            color: orange;
        }
        div p {
            color: red;
        }
    </style>
</head>
<body>
<div>
    <p>123</p>
    <p>456</p>
</div>
</body>
</html>

3.2.1.2.3.2.1-2

發現仍然是后者覆蓋前者,也就是說關系型選擇器的不同關系之間沒有優先級

3.2.1.2.3.2.2 相同關系內部成員數量
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.2.1.2.3.2.2</title>
    <style>
        div {
            color: yellow;
        }
        div div {
            color: red;
        }
        div div div {
            color: orange;
        }
        section section section {
            color: orange;
        }
        section section {
            color: red;
        }
        section {
            color: yellow;
        }
    </style>
</head>
<body>
<div>
    <div>
        <div>123</div>
    </div>
</div>
<section>
    <section>
        <section>456</section>
    </section>
</section>
</body>
</html>

3.2.1.2.3.2.2

上圖說明,親戚關系中,成員數量越多,優先級越高

3.2.1.2.3.2.3 相同關系內部成員成份順序
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.2.1.2.3.2.3</title>
    <style>
        div .test02 {
            color: yellow;
        }
        .test01  div {
            color: orange;
        }
        div .test03 {
            color: red;
        }
    </style>
</head>
<body>
<div class="test01">
    <div class="test02">123</div>
    <div class="test03">456</div>
</div>
</body>
</html>

3.2.1.2.3.2.3

上圖說明,交換不同類型成員的順序并不影響優先級

3.2.1.2.3.2.4 相同關系內部成員成份組成
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.2.1.2.3.2.4</title>
    <style>
        #test01 #test02 {
            color: red;
        }
        #test01 .test02 {
            color: orange;
        }
        #test01 div {
            color: black;
        }
        .test01 .test02 {
            color: grey;
        }
        .test01 div {
            color: yellow;
        }
        div div {
            color: blue;
        }
        .test03 div {
            color: yellow;
        }
        .test03 .test04 {
            color: grey;
        }
        #test03 div {
            color: black;
        }
        #test03 .test04 {
            color: orange;
        }
        #test03 #test04 {
            color: red;
        }
    </style>
</head>
<body>
<div class="test01" id="test01">
    <div class="test02" id="test02">123</div>
</div>
<div class="test03" id="test03">
    <div class="test04" id="test04">123</div>
</div>
</body>
</html>

3.2.1.2.3.2.4-1

3.2.1.2.3.2.4-2

由上面圖片可以看出,在親戚關系內部,成員的重要性和其單獨出現時的重要性保持一致,即id>類>元素

由以上幾點結論可以得出,親戚關系發生沖突時,先看id選擇器數量,誰多誰大,一樣多就看類(及其同級)選擇器,誰多誰大,若還是一樣多,則看元素選擇器,誰多誰大。如果仍然一樣多,誰在后面誰優先。

3.2.1.2.4 通配選擇器
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>3.2.1.2.4</title>
    <style>
        input {
            color: red;
        }
        * {
            color: blue;
        }
    </style>
</head>
<body>
<input type="text" value="123" disabled="disabled">
</body>
</html>
3.2.1.2.4

可以看出,通配選擇器樣式優先級僅比瀏覽器默認樣式和繼承樣式優先級高一些

總結3.2.1.2 僅有內部樣式的情況,有如下結論:

  1. (級別)對于不同元素,有如下優先級別,id > 類(屬性,偽類)> 元素 > 通配符 > 瀏覽器默認樣式 > 繼承樣式
  2. (個數)樣式沖突時,比較兩者的最高級別選擇器的級別,級別高的勝出。若級別一樣,則比較其個數,個數多的勝出。若一樣,則比較次一級別的級別與個數,如此循環往下,直到有一個勝出或者打平。
  3. (順序)若兩者級別及其個數一樣,則后者覆蓋前者。

ps:對于社群關系,在比較優先級時,將其理解為在該位置拆按順序成一個個單獨的個體即可。

3.2.1.3 僅有外部

3.2.1.3.1 外部樣式在一個文件內部發生沖突

這種情況的表現形式與內部樣式一樣。

3.2.1.3.2 外部樣式在多個文件之間發生沖突

這種情況遵循后者覆蓋前者的原則,后面的link優先于前面的link,而不管其加載的順序如何。

3.2.2 多種樣式類型的情況(內聯,內部和外部相互作用)

內聯 > 內部 > 外部

4.總結

  1. !important最優先(特權階級)
  2. 比較樣式文件類型,內聯 > 內部 > 外部 (內外有別)
  3. 比較樣式權重,按級別,個數與順序進行計算 (親疏有別,量大優先,后來居上)

參考

CSS的繼承性、層疊性、權重
css知多少(3)——樣式來源與層疊規則
深入理解CSS中的層疊上下文和層疊順序

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容