id 的選取器為什麼要這麼寫 li#first?

來源:互聯網
上載者:User
一. 一個疑問?

看到過一篇關於 CSS 的文章,其中說到:對於類似 li#first 這樣的選取器,由於使用 id 就已經可以確定元素了,沒有必要再寫上前面的 li, 直接寫上 #first 這樣的 id 選取器就可以了。聽起來說得不錯,簡單測試一下也沒有問題。

可是,我們經常看到帶有元素名稱的選取器,例如,在微軟的項目模板中就有大量的帶有元素名稱的選取器,如果沒有用的話,為什麼要這樣寫呢?

ul#navlist{    float: right;}ul#navlist li{    display: inline;}
二. 問題出現了!

寫一個簡單的菜單,使用 ul 和 li 實現,功能表項目之間使用邊框來實現間隔線。

html 代碼如下:


  • Home
  • Store
  • ShoppingCart
  • Admin

使用下面的樣式表,首先通過為所有的超級連結增加一個左邊框來畫出間隔的虛線,然後將第一個功能表項目的左邊框去掉,我的第一個樣式使用了 .first a。

ul#navlist li{    display: inline;}        ul#navlist li a{    border-left: 1px dotted #8A8575;    padding: 10px;    margin-top: 10px;    color: #8A8575;    text-decoration: none;    float: left;}        .first a{    border: none;}

看一下效果,完全沒有反應。

還有的地方說 id 選取器的層級比較高,那麼將類改成 id 。


  • Home
  •  將樣式表也進行相應的修改。

    #first a{    border: none;}

    可是結果呢?巋然不動!

    用Firefox的 firebug 看一看,被忽略了。

    三. 探源

    為什麼我的樣式被秒殺了?

    網上有大量的文章,但是說法並不一致,有的說要考慮三個層級,可是也有的說需要考慮四個層級,但是總的方向大致是關於層疊的。

    不如到 W3C 的網站上看一個究竟。相關的標準在 這個頁面 可以看到,目前為止的 CSS 標準有三個: CSS1, CSS2, 以及 CSS3。

    CSS1 是最早的標準,其中關於層疊順序的描述在 這裡,還提供了一個簡單的樣本進行說明。

    LI            {...}  /* a=0 b=0 c=1 -> specificity =   1 */UL LI         {...}  /* a=0 b=0 c=2 -> specificity =   2 */UL OL LI      {...}  /* a=0 b=0 c=3 -> specificity =   3 */LI.red        {...}  /* a=0 b=1 c=1 -> specificity =  11 */UL OL LI.red  {...}  /* a=0 b=1 c=3 -> specificity =  13 */ #x34y         {...}  /* a=1 b=0 c=0 -> specificity = 100 */ 

    在 CSS1 中將優先順序分為三組,將 id 選取器作為 a 組,類別選取器作為 b 組,元素名作為 c 組,每組中出現一次,計數一次,按照先 a 組進行比較,相同的情況下,使用 b 組進行比較,最後是 c 組。什麼選取器的優先順序別高,什麼選取器提供的樣式有效。比如在上面的例子中,第 5 組使用 id 的層級最高,所以,這組的樣式設定生效,而其他的設定將會被忽略掉。

    CSS21 標準

    在 CSS2 中,又增加了關於行內說明 style 的組,所以參與比較的組成為了 4 組,其中 style 的優先順序別最高。同樣,在 CSS2 的標準說明中也提供了範例。

     *             {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */ li            {}  /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */ li:first-line {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul li         {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul ol+li      {}  /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */ h1 + *[rel=up]{}  /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */ ul ol li.red  {}  /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */ li.red.level  {}  /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */ #x34y         {}  /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */ style=""          /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

    在這個樣本中,style 的優先順序別最高,所以將會覆蓋掉通過 id 進行的設定,顏色為綠色。

    四. 解決問題

    通過上面的分析可以看到,僅僅提供選取器並不足以能夠生效,還要看選取器的優先順序別,在我們的問題中,即使使用 id 來選擇第一個功能表項目:#first a ,包括了一個 id 和一個元素名,那麼所得的優先順序別為:

    a=0, b=1, c=0, d=1

    可是,通用的選取器是這樣的:ul#navlist li a,優先順序中卻包括了一個 id, 還有 3 個元素名稱,所以優先順序別為:

    a=0, b=1, c=0, d=3

    所以我們的選取器沒有比過通用的選取器,悲劇發生了!

    知道了原因,問題也就簡單了,提高我們選取器的優先順序別,超過通用選取器的優先順序就可以了,比如,我們可以寫成這樣:

    ul#navlist li#first a

    現在的優先順序是多少呢?

    a=0, b=2, c=0, d=3

    在 b 組比較的時候就已經超過了,看看是否已經成功了!

    還可以加上重要性說明,也可以解決。!important 必須寫在樣式與分號之間,每個樣式必須單獨聲明。

    #first a{    border: none !important;}

    看來選取器不是那麼簡單呀!

    一. 一個疑問?

    看到過一篇關於 CSS 的文章,其中說到:對於類似 li#first 這樣的選取器,由於使用 id 就已經可以確定元素了,沒有必要再寫上前面的 li, 直接寫上 #first 這樣的 id 選取器就可以了。聽起來說得不錯,簡單測試一下也沒有問題。

    可是,我們經常看到帶有元素名稱的選取器,例如,在微軟的項目模板中就有大量的帶有元素名稱的選取器,如果沒有用的話,為什麼要這樣寫呢?

    ul#navlist{    float: right;}ul#navlist li{    display: inline;}
    二. 問題出現了!

    寫一個簡單的菜單,使用 ul 和 li 實現,功能表項目之間使用邊框來實現間隔線。

    html 代碼如下:

    
    
    • Home
    • Store
    • ShoppingCart
    • Admin

    使用下面的樣式表,首先通過為所有的超級連結增加一個左邊框來畫出間隔的虛線,然後將第一個功能表項目的左邊框去掉,我的第一個樣式使用了 .first a。

    ul#navlist li{    display: inline;}        ul#navlist li a{    border-left: 1px dotted #8A8575;    padding: 10px;    margin-top: 10px;    color: #8A8575;    text-decoration: none;    float: left;}        .first a{    border: none;}

    看一下效果,完全沒有反應。

    還有的地方說 id 選取器的層級比較高,那麼將類改成 id 。

    
    
  • Home
  •  將樣式表也進行相應的修改。

    #first a{    border: none;}

    可是結果呢?巋然不動!

    用Firefox的 firebug 看一看,被忽略了。

    三. 探源

    為什麼我的樣式被秒殺了?

    網上有大量的文章,但是說法並不一致,有的說要考慮三個層級,可是也有的說需要考慮四個層級,但是總的方向大致是關於層疊的。

    不如到 W3C 的網站上看一個究竟。相關的標準在 這個頁面 可以看到,目前為止的 CSS 標準有三個: CSS1, CSS2, 以及 CSS3。

    CSS1 是最早的標準,其中關於層疊順序的描述在 這裡,還提供了一個簡單的樣本進行說明。

    LI            {...}  /* a=0 b=0 c=1 -> specificity =   1 */UL LI         {...}  /* a=0 b=0 c=2 -> specificity =   2 */UL OL LI      {...}  /* a=0 b=0 c=3 -> specificity =   3 */LI.red        {...}  /* a=0 b=1 c=1 -> specificity =  11 */UL OL LI.red  {...}  /* a=0 b=1 c=3 -> specificity =  13 */ #x34y         {...}  /* a=1 b=0 c=0 -> specificity = 100 */ 

    在 CSS1 中將優先順序分為三組,將 id 選取器作為 a 組,類別選取器作為 b 組,元素名作為 c 組,每組中出現一次,計數一次,按照先 a 組進行比較,相同的情況下,使用 b 組進行比較,最後是 c 組。什麼選取器的優先順序別高,什麼選取器提供的樣式有效。比如在上面的例子中,第 5 組使用 id 的層級最高,所以,這組的樣式設定生效,而其他的設定將會被忽略掉。

    CSS21 標準

    在 CSS2 中,又增加了關於行內說明 style 的組,所以參與比較的組成為了 4 組,其中 style 的優先順序別最高。同樣,在 CSS2 的標準說明中也提供了範例。

     *             {}  /* a=0 b=0 c=0 d=0 -> specificity = 0,0,0,0 */ li            {}  /* a=0 b=0 c=0 d=1 -> specificity = 0,0,0,1 */ li:first-line {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul li         {}  /* a=0 b=0 c=0 d=2 -> specificity = 0,0,0,2 */ ul ol+li      {}  /* a=0 b=0 c=0 d=3 -> specificity = 0,0,0,3 */ h1 + *[rel=up]{}  /* a=0 b=0 c=1 d=1 -> specificity = 0,0,1,1 */ ul ol li.red  {}  /* a=0 b=0 c=1 d=3 -> specificity = 0,0,1,3 */ li.red.level  {}  /* a=0 b=0 c=2 d=1 -> specificity = 0,0,2,1 */ #x34y         {}  /* a=0 b=1 c=0 d=0 -> specificity = 0,1,0,0 */ style=""          /* a=1 b=0 c=0 d=0 -> specificity = 1,0,0,0 */

    在這個樣本中,style 的優先順序別最高,所以將會覆蓋掉通過 id 進行的設定,顏色為綠色。

    四. 解決問題

    通過上面的分析可以看到,僅僅提供選取器並不足以能夠生效,還要看選取器的優先順序別,在我們的問題中,即使使用 id 來選擇第一個功能表項目:#first a ,包括了一個 id 和一個元素名,那麼所得的優先順序別為:

    a=0, b=1, c=0, d=1

    可是,通用的選取器是這樣的:ul#navlist li a,優先順序中卻包括了一個 id, 還有 3 個元素名稱,所以優先順序別為:

    a=0, b=1, c=0, d=3

    所以我們的選取器沒有比過通用的選取器,悲劇發生了!

    知道了原因,問題也就簡單了,提高我們選取器的優先順序別,超過通用選取器的優先順序就可以了,比如,我們可以寫成這樣:

    ul#navlist li#first a

    現在的優先順序是多少呢?

    a=0, b=2, c=0, d=3

    在 b 組比較的時候就已經超過了,看看是否已經成功了!

    還可以加上重要性說明,也可以解決。!important 必須寫在樣式與分號之間,每個樣式必須單獨聲明。

    #first a{    border: none !important;}

    看來選取器不是那麼簡單呀!

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.