CSS selectors 選擇器


CSS selectors 選擇器

選擇器的基本意義是:根據一些特征,選中元素樹上的一批元素。

  1. 總覽分類

    1. 簡單選擇器:針對某一特征判斷是否選中元素。
    2. 復合選擇器:連續寫在一起的簡單選擇器,針對元素自身特征選擇單個元素。
    3. 復雜選擇器:由“(空格)”“ >”“ ~”“ +”“ ||”等符號連接的復合選擇器,根據父元素或者前序元素檢查單個元素。
    4. 選擇器列表:由逗號分隔的復雜選擇器,表示“或”的關系
  2. 詳解

    1. 簡單選擇器

      img

      1. 類型選擇器和全體選擇器

        1. 類型選擇器有 div span p html body a 這些,選中的是全部的DOM 上的元素。

        2. 全體選擇器就是 *,選中全部的元素。我們通常用來覆蓋默認樣式、寫字體格式這些。

      2. id 選擇器與 class 選擇器

        1. # 選中 id
        2. . 選中 class

      這里有個值得一提的是,document.getElementBy...的性能要比 document.querySelector...的性能好的多,盡量用document.getElementBy

      1. 屬性選擇器

        1. [att]

          只要元素有這個屬性,不論屬性是什么值,都可以被選中。

        2. [att=val]

          精確匹配,檢查一個元素屬性的值是否是 val。

        3. [att~=val]

          多種匹配,檢查一個元素的值是否是若干值之一,這里的 val 不是一個單一的值了,可以是用空格分隔的一個序列。

        4. [att|=val]

          開頭匹配,檢查一個元素的值是否是以 val 開頭,它跟精確匹配的區別是屬性只要以 val 開頭即可,后面內容不管。

          這個設計有點不符合直覺,感覺^=更靠譜點,畢竟正則是這么寫的。。。

      2. 偽類選擇器

        1. 樹結構關系偽類選擇器

          1. :empty 偽類表示沒有子節點的元素,這里有個例外就是子節點為空白文本節點的情況。
          2. :nth-child 和 :nth-last-child 這是兩個函數型的偽類,CSS 的 An+B 語法設計的是比較復雜的,我們這里僅僅介紹基本用法。我們還是看幾個例子:

          1ebdba2978a22c13844d108318b271a9

          1. :nth-last-child 的區別僅僅是從后往前數。

          2. :first-child :last-child 分別表示第一個和最后一個元素。

          3. :only-child 按字面意思理解即可,選中唯一一個子元素。

          4. of-type 系列,是一個變形的語法糖,S:nth-of-type(An+B) 是:nth-child(|An+B| of S) 的另一種寫法。以此類推,還有 nth-last-of-type、first-of-type、last-of-type、only-of-type。

        2. 鏈接與行為偽類選擇器(常用的一批)

          1. :any-link 表示任意的鏈接,包括 a、area 和 link 標簽都可能匹配到這個偽類
          2. :link 表示未訪問過的鏈接, :visited 表示已經訪問過的鏈接。
          3. :hover 表示鼠標懸停在上的元素。
          4. :active 表示用戶正在激活這個元素,如用戶按下按鈕,鼠標還未抬起時,這個按鈕就處於激活狀態。
          5. :focus 表示焦點落在這個元素之上。
          6. :target 用於選中瀏覽器 URL 的 hash 部分所指示的元素。
          7. 在 Selector Level 4 草案中,還引入了 target-within、focus-within 等偽類,用於表示 target 或者 focus 的父容器。具體可以去看看 w3c selector 4
        3. 邏輯偽類選擇器

          1. :not 偽類。

            *|*:not(:hover)
            
        4. 其他的偽類選擇器(了解即可)

          dir、lang、play、pause、current、past、future、nth-col、nth-last-col

      3. 復合選擇器

        連續寫在一起 如:

        html body div span .interesting #666selector {
        	background-color: 'azure';
        }
        
      4. 復雜選擇器

        1. 選擇器的組合

          1. “空格”:后代,表示選中所有符合條件的后代節點, 例如“ .a .b ”表示選中所有具有 class 為 a 的后代節點中 class 為 b 的節點。
          2. “>” :子代,表示選中符合條件的子節點,例如“ .a>.b ”表示:選中所有“具有 class 為 a 的子節點中,class 為 b 的節點”。
          3. “~” : 后繼,表示選中所有符合條件的后繼節點,后繼節點即跟當前節點具有同一個父元素,並出現在它之后的節點,例如“ .a~.b ”表示選中所有具有 class 為 a 的后繼中,class 為 b 的節點。

            這么理解更簡單,前面有.a 的 所有 .b元素

          4. “+”:直接后繼,表示選中符合條件的直接后繼節點,直接后繼節點即 nextSlibling。例如 “.a+.b ”表示選中所有具有 class 為 a 的下一個 class 為 b 的節點。
          5. “||”:列選擇器,表示選中對應列中符合條件的單元格。

          我們在實際使用時,比較常用的連接方式是“空格”和“>”。

          工程實踐中一般會采用設置合理的 class 的方式,來避免過於復雜的選擇器結構,這樣更有利於維護和性能。空格和子代選擇器通常用於組件化場景,當組件是獨立開發時,很難完全避免 class 重名的情況,如果為組件的最外層容器元素設置一個特別的 class 名,生成 CSS 規則時,則全部使用后代或者子代選擇器,這樣可以有效避免 CSS 規則的命名污染問題。

        2. 選擇器的優先級

          1. 優先級順序

            1. 第一優先級
              • 無連接符號
            2. 第二優先級
              • “空格”
              • “~”
              • “+”
              • “>”
              • “||”
            3. 第三優先級
              • “,”
          2. 優先級計算

            CSS 標准用一個三元組 (a, b, c) 來構成一個復雜選擇器的優先級。

            • id 選擇器的數目記為 a;

            • 偽類選擇器和 class 選擇器的數目記為 b;

            • 偽元素選擇器和標簽選擇器數目記為 c;

            • “*” 不影響優先級。

            • 行內屬性的優先級永遠高於 CSS 規則,瀏覽器提供了一個“口子”,就是在選擇器前加上“!import”。這個用法非常危險,因為它相當於一個新的優先級,而且此優先級會高於行內屬性

              CSS 標准建議用一個足夠大的進制,獲取“ a-b-c ”來表示選擇器優先級。

              specificity = base * base * a + base * b + c
              

              base 是一個“足夠大”的正整數。關於 base,歷史中有些趣聞,早年 IE6 采用 256 進制,於是就產生“256 個 class 優先級等於一個 id”這樣的奇葩問題,后來擴大到 65536,基本避免了類似的問題。

            我們這么計算,specificity = a * 100 + b * 10 + c * 1

            同一優先級的選擇器遵循“后面覆蓋前面的原則”。

            實際寫代碼的時候還是少來點選擇器,不然代碼可讀性會受到影響,不利於維護。(會被打死。。。)

      5. 選擇器列表

        就是一個 “,” 逗號,表示 或者 的關系。。。

  3. 偽元素

    這個東西還沒說呢

    目前兼容性達到可用的偽元素有以下幾種。

    • ::first-line
    • ::first-letter
    • ::before
    • ::after
    1. 說說 first-line 與 first-letter:
    <p>This is a somewhat long HTML
    paragraph that will be broken into several
    lines. The first line will be identified
    by a fictional tag sequence. The other lines
    will be treated as ordinary lines in the
    paragraph.</p>
    
    p::first-line { text-transform: uppercase }
    

    這一段代碼把段落的第一行字母變為大寫。注意這里的第一行指的是排版后顯示的第一行,跟 HTML 代碼中的換行無關。

    ::first-letter 則指第一個字母。首字母變大並向左浮動是一個非常常見的排版方式。

    <p>This is a somewhat long HTML
    paragraph that will be broken into several
    lines. The first line will be identified
    by a fictional tag sequence. The other lines
    will be treated as ordinary lines in the
    paragraph.</p>
    
    p::first-letter { text-transform: uppercase; font-size:2em; float:left; }
    

    雖然聽上去很簡單,但是實際上,我們遇到的 HTML 結構要更為復雜,一旦元素中不是純文本,規則就變得復雜了。

    CSS 標准規定了 first-line 必須出現在最內層的塊級元素之內。因此,我們考慮以下代碼。

    <div>
      <p id=a>First paragraph</p>
      <p>Second paragraph</p>
    </div>
    
    div>p#a {
        color:green;
    }
    
    div::first-line { 
        color:blue; 
    }
    

    這段代碼最終結果第一行是藍色,因為 p 是塊級元素,所以偽元素出現在塊級元素之內,所以內層的 color 覆蓋了外層的 color 屬性。

    如果我們把 p 換成 span,結果就是相反的。

    <div>
      <span id=a>First paragraph</span><br/>
      <span>Second paragraph</span>
    </div>
    
    div>span#a {
        color:green;
    }
    
    div::first-line { 
        color:blue; 
    }
    

    這段代碼的最終結果是綠色,這說明偽元素在 span 之外。

    ::first-letter 的行為又有所不同,它的位置在所有標簽之內,我們把前面的代碼換成::first-letter。

    <div>
      <span id=a>First paragraph</span><br/>
      <span>Second paragraph</span>
    </div>
    
    div>span#a {
        color:green;
    }
    
    div::first-letter { 
        color:blue; 
    }
    

    執行這段代碼,我們可以看到,首字母變成了藍色,這說明偽元素出現在 span 之內。

    CSS 標准只要求 ::first-line 和 ::first-letter 實現有限的幾個 CSS 屬性,都是文本相關,這些屬性是下面這些。

    6e050ee9f7a0b1657388271cceb0c548

    1. 說說 ::before 和 ::after 偽元素

      這兩個偽元素跟前面兩個不同的是,它不是把已有的內容套上一個元素,而是真正的無中生有,造出一個元素。

      ::before 表示在元素內容之前插入一個虛擬的元素,::after 則表示在元素內容之后插入。

      這兩個偽元素所在的 CSS 規則必須指定 content 屬性才會生效,我們看下例子:

      <p class="special">I'm real element</p>
      
      p.special::before {
          display: block;
          content: "pseudo! ";
      }
      

      這里要注意一點,::before 和 ::after 還支持 content 為 counter,如:

      <p class="special">I'm real element</p>
      p.special::before {
          display: block;
          content: counter(chapno, upper-roman) ". ";
      }
      

      這對於實現一些列表樣式是非常有用的。

      ::before 和 ::after 中支持所有的 CSS 屬性。實際開發中,這兩個偽元素非常有用,有了這兩個偽元素,一些修飾性元素,可以使用純粹的 CSS 代碼添加進去,這能夠很好地保持 HTML 代碼中的語義,既完成了顯示效果,又不會讓 DOM 中出現很多無語義的空元素。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM