CSS並不簡單--選擇器你們庭

梳理選擇器的種類,理解選擇器的優先級,從而避免莫名其妙的樣式重疊問題。css

1、選擇器的種類

一、基本選擇器

  基本選擇器包含:通配選擇器、元素選擇器、ID選擇器、類選擇器和羣組選擇器。html

  對於類選擇器的命名,'-'和'_'二者多有,具體能夠看這裏學習

  通配選擇器(*),它用來選擇全部元素,不過這個選擇器的效率比較低,因此慎重選擇,可是瞅了一眼Boostrap4.0是這樣設置box-sizing:網站

html {
        box-sizing: border-box;
    }
    *, *::before, *::after {
        box-sizing: inherit;
    }
複製代碼

  因此吧,也不是不能用,不過也就這一處,仍是得少用。ui

  ID選擇器,它的惟一性是規範,可是應用於多個元素,樣式一樣生效,不推薦這樣作。spa

  羣組選擇器,經過逗號隔開,能夠有效的減小一些冗餘代碼,例如上面的例子中:code

*, *::before, *::after {
        box-sizing: inherit;
    }
複製代碼

二、屬性選擇器

  屬性選擇器主要針對於元素的屬性值進行篩選,包含這幾種操做符:=、|=、~=、*=、^=和$=:cdn

  • [attr=val]:屬性值爲val;
  • [attr|=val]:屬性值爲val或者以val-開頭;
  • [attr~=val]:屬性值爲val或者以多個空格分開含有val;
  • [attr*=val]:屬性值包含val;
  • [attr^=val]:屬性值以val開頭;
  • [attr$=val]:屬性值以val結尾。

  屬性選擇器的應用不少,例如Vue中的scoped css也正是利用屬性選擇器實現的。htm

三、層次選擇器

  層次選擇器包含後代選擇器(E F)、子選擇器(E > F)、相鄰兄弟選擇器(E + F)和通用選擇器(E ~ F)。blog

  後代選擇器與子選擇器的區別:相比較前者,子選擇器的搜索範圍侷限於兒子節點。

  相鄰兄弟選擇器,選擇E後面相鄰的兄弟節點F。很遺憾不能選擇前面的。這個選擇器的應用也不少,好比咱們設置列表項之間的距離爲20px:

li:not(:last-child) + li {
        margin-top: 20px;
    }
複製代碼

  通用選擇器,選擇E後面全部的兄弟節點F。一樣上面的例子:

li:first-child ~ li {
        margin-top: 20px;
    }
複製代碼

  若是你能理解上面這兩種寫法,基本上這兩個選擇器你就理解了。

四、僞元素選擇器

  首先對於僞元素的寫法,標準是推薦雙冒號,感受這樣寫挺好的,能夠和僞類區別開來。

  ::first-letter做用於整塊文本的第一段的第一個文字,元素必須爲塊級元素。例如修飾段落第一個單詞的樣式:

p::first-letter {
        color: red;
        font-size: 20px;
    }
複製代碼

  ::first-line則是做用於整塊文本的第一段,一樣必須爲塊級元素。

  ::before和::after分別向元素的先後添加內容,用處很大,好比咱們實現這樣的購物車:

購物車

<span role="btn" aria-label="購物車" attr-quantity="2" class="caricon"></span>
複製代碼
/* 這裏就不展示可有可無的樣式了 */
    .caricon {
        /* 這裏設置容器的樣式 */
    }
    .caricon::before {
        /* 經過僞元素設置購物車圖標 */
    }
    .caricon::after {
        /* 這兩個僞元素多有一個重要的content屬性,用來設置僞元素的內容 這裏經過attr獲取元素的屬性值,實現購物車數量 */
        content: attr(attr-quantity);
    }
複製代碼

  在一些網站中,當你鼠標選擇文字會發生樣式變化,這是由於用了::selection,不過它能改變的CSS屬性比較有限,具體能夠查詢MDN。

  還有咱們討厭input的placeholder樣式太丑時,你可使用::placeholder來修改,可是這是一個試驗性的僞元素,還有不少試驗性的僞元素,有興趣能夠搜索一下。

五、僞類

  僞類的組成就更豐富了,這裏選擇兩個比較重要可能還有點容易混淆的說說。

  首先看看否認僞類選擇器:not,在前面的例子中你已經看到它的身影了,它匹配不符合描述的元素,用處能夠說很大。

  而後就是結構僞類選擇器,這裏的內容也多,並且很容易混淆。

  例如:first-child和:first-of-type:

p:first-child {
        /* 計算範圍:全部的兄弟節點 */
    }
    
    p:first-of-type {
        /* 計算範圍:兄弟節點中全部p元素 */
    }
複製代碼

  一樣還有:last-child和:last-of-type,就很容易懂了。

  :nth-child就比較強大了,不只可使用odd和even,還可使用表達式。例如咱們列表的斑馬線:

li:nth-child(even) {
        background: red;
    }
複製代碼

  關於:nth-child重要的幾點能夠總結爲:

  • 值的下標是從1開始的;
  • 可是n的下標是從0開始;
  • 當表達式的值爲0或者負數是無效的;
  • 採用表達式能夠實現不少需求,例如我只想讓列表的前三項設置樣式:nth-child(-n + 3);

  像什麼:nth-of-type,:nth-last-child和:nth-last-of-type是否是小case了。

  :only-child表示父節點只有一個子節點,其實學習了上面的一些選擇器,咱們徹底能夠找到等價的表達方式:

li:first-child:last-child {
        background: yellow;
    }
複製代碼

  固然還有:only-of-type是必不可少的。

2、選擇器的優先級

  上面這麼多的選擇器,是否是很頭大,這也是爲何這裏要特意說一下選擇器優先級。當多條樣式應用在一個元素上,系統會將樣式合併,當一個屬性被賦了屢次值,到底取哪一個值呢?這時候就須要優先級了,優先級高的覆蓋優先級低的。

  選擇器優先級規則:

  • 首先通配符是沒有權重的(因此我感受這點也是不推薦使用它的緣由);
  • !important的權重bug級的高;
  • 權重第二高的就是元素的行內樣式(style屬性中的值);

  接下來的狀況咱們能夠數值化:

  • id選擇器的權重爲100;
  • 類選擇器、屬性選擇器和僞類選擇器的權重爲10;
  • 元素和僞元素的權重爲1。
  • 若是優先級同樣,則後聲明的優先級高。

  看個例子:

li {
        width: 300px;
        height: 90px;
        background: red;
    }
    ul li {
        background: yellow;
    }
複製代碼

  首先對於沒有重複賦值的width和height,並不存在什麼優先級的問題,而對於background,第一個樣式的優先級爲1,而第二個樣式的優先級爲2,因此將yellow賦值給background。

3、總結

  前面寫了不少廢話,也沒有將選擇器羅列完整,可是基本的構成,你們應該很清晰了。

  對於後面說的選擇器優先級的計算,並非說你每次寫完樣式多要求算一下,最重要的目的是:你理解計算規則後,讓你對每種選擇器的應用場景更加清晰,而不是說隨便用,從而形成意想不到的樣式覆蓋問題。

  最後,謝謝你們看完這篇文章。

參考資料: 圖解CSS3 CSS Specificity: Things You Should Know


  喜歡本文的小夥伴們,歡迎關注個人訂閱號超愛敲代碼,查看更多內容.

相關文章
相關標籤/搜索