CSS入門8-三大特性之層疊特性與優(yōu)先級

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

1. 簡介

所謂的層疊性與優(yōu)先級,其實說白了可以理解為,不同的規(guī)則起沖突的情況下,聽誰的呢?有的時候這種沖突很容易解決,有的時候我們自己都難以決斷,比如好聲音三位導(dǎo)師都選你,該跟誰走呢。索性css給出了這些規(guī)則的優(yōu)先級,不需要我們?nèi)タ鄲馈?/p>

2. 樣式作用情況

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

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

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

3. 優(yōu)先級分析

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">內(nèi)聯(lián)唯一指定</div>
    <p>元素唯一指定</p>
    <div class="green">類唯一指定</div>
</div>
</body>
</html>

結(jié)論:若只有唯一指定樣式,以該樣式為準(zhǔn)。

test3.1

3.2 多個樣式規(guī)則

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

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

3.2.1.1 僅有內(nèi)聯(lián)

僅有內(nèi)聯(lián)的情況下,要出現(xiàn)沖突,只可能是在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;">
    僅有內(nèi)聯(lián),誰在后面,誰優(yōu)先
</div>
</body>
</html>
3.2.1.1

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

結(jié)論:只有內(nèi)聯(lián)樣式,后面的屬性賦值優(yōu)先級大于前面的屬性賦值。

3.2.1.2 僅有內(nèi)部樣式

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

  1. 常用選擇器,包括元素選擇器,類選擇器,id選擇器和屬性選擇我器
  2. 偽類選擇器和偽元素選擇器
  3. 關(guān)系選擇器
  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中類的順序為準(zhǔn),后面的覆蓋前面的樣式。如果是同一選擇器,也是后者覆蓋前者,這種情況可以涵蓋在同類選擇器的情況下。

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

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選擇器,剩余三種選擇器比較時,類和屬性誰在下邊誰贏,也就是后者覆蓋前者。最后,元素分別與類和屬性比較,發(fā)現(xiàn)元素都輸了。

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

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

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>

注:要想在調(diào)試器看到動態(tài)偽類效果,需要在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內(nèi)先按id,類,屬性,元素,靜態(tài)偽類(只應(yīng)用于超鏈接),動態(tài)偽類(可應(yīng)用于任何元素),目標(biāo)偽類:target(IE8-不支持,匹配錨點對應(yīng)的目標(biāo)元素),UI元素偽類(IE8-不支持),結(jié)構(gòu)偽類(IE8-不支持)的順序指定規(guī)則。結(jié)果發(fā)現(xiàn)其表現(xiàn)如下:

a:id > 結(jié)構(gòu)偽類 > 動態(tài)偽類 > 靜態(tài)偽類 > 屬性 > 類 > 元素 > 瀏覽器默認(rèn)屬性 > 繼承屬性

input:id > 結(jié)構(gòu)偽類 > UI元素偽類 > 目標(biāo)偽類 > 動態(tài)偽類 > 類 > 元素 > 瀏覽器默認(rèn)屬性 > 繼承屬性

我們合并一下這兩個結(jié)論,有如下結(jié)論:

3.2.1.2.2.1-1 id > 結(jié)構(gòu)偽類 > UI元素偽類 > 目標(biāo)偽類 > 動態(tài)偽類 > 靜態(tài)偽類 > 屬性 > 類 > 元素 > 瀏覽器默認(rèn)屬性 > 繼承屬性
(當(dāng)然,需要注意的是,并不是每個元素都有這些屬性的)

然后,我們將style內(nèi)各規(guī)則倒序一下:

<!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錨點已點擊

結(jié)果發(fā)現(xiàn)其表現(xiàn)如下:

a:id > 類 > 屬性 > 靜態(tài)偽類 > 動態(tài)偽類 > 結(jié)構(gòu)偽類 > 元素 > 瀏覽器默認(rèn)屬性 > 繼承屬性

input:id > 類 > 動態(tài)偽類 > 目標(biāo)偽類 > UI元素偽類 > 結(jié)構(gòu)偽類 > 元素 > 瀏覽器默認(rèn)屬性 > 繼承屬性

我們合并一下這兩個結(jié)論,有如下結(jié)論:

3.2.1.2.2.1-2 id > 類 > 屬性 > 靜態(tài)偽類 > 動態(tài)偽類 > 目標(biāo)偽類 > UI元素偽類 > 結(jié)構(gòu)偽類 > 元素 > 瀏覽器默認(rèn)屬性 > 繼承屬性

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

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

3.2.1.2.2.2 偽元素選擇器

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

<!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

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

3.2.1.2.3 關(guān)系選擇器
3.2.1.2.3.1 社群關(guān)系-分組選擇器
<!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

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

3.2.1.2.3.2 親戚關(guān)系
3.2.1.2.3.2.1 不同關(guān)系類型的比較
<!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中排序,發(fā)現(xiàn)后面的優(yōu)先級高。然后順序反過來:

<!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

發(fā)現(xiàn)仍然是后者覆蓋前者,也就是說關(guān)系型選擇器的不同關(guān)系之間沒有優(yōu)先級。

3.2.1.2.3.2.2 相同關(guān)系內(nèi)部成員數(shù)量
<!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

上圖說明,親戚關(guān)系中,成員數(shù)量越多,優(yōu)先級越高

3.2.1.2.3.2.3 相同關(guān)系內(nèi)部成員成份順序
<!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

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

3.2.1.2.3.2.4 相同關(guān)系內(nèi)部成員成份組成
<!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

由上面圖片可以看出,在親戚關(guān)系內(nèi)部,成員的重要性和其單獨出現(xiàn)時的重要性保持一致,即id>類>元素。

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

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

可以看出,通配選擇器樣式優(yōu)先級僅比瀏覽器默認(rèn)樣式和繼承樣式優(yōu)先級高一些。

總結(jié)3.2.1.2 僅有內(nèi)部樣式的情況,有如下結(jié)論:

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

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

3.2.1.3 僅有外部

3.2.1.3.1 外部樣式在一個文件內(nèi)部發(fā)生沖突

這種情況的表現(xiàn)形式與內(nèi)部樣式一樣。

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

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

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

內(nèi)聯(lián) > 內(nèi)部 > 外部

4.總結(jié)

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

參考

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容