CSS選擇器

這裏有一份簡潔的前端知識體系等待你查收,看看吧,會有驚喜哦~若是以爲不錯,懇求star哈~javascript


前言

瞭解了選擇器的基礎知識。接下來系統學習一下CSS選擇器。css

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

咱們把選擇器的結構分一下類,那麼由簡單到複雜能夠分紅如下幾種。前端

  1. 簡單選擇器:針對某一特徵判斷是否選中元素。
  2. 複合選擇器:連續寫在一塊兒的簡單選擇器,針對元素自身特徵選擇單個元素。
  3. 複雜選擇器:由空格、>、~、+、||等符號鏈接的複合選擇器,根據父元素或者前序元素檢查單個元素。
  4. 選擇器列表:由逗號分隔的複雜選擇器,表示「或」的關係。

咱們能夠看到,選擇器是由簡單選擇器逐級組合而成的結構,那麼咱們就來首先看一下簡單選擇器。java


簡單選擇器

簡單選擇器是針對某一特徵判斷是否爲選中元素。git



類型選擇器和全體選擇器

咱們要介紹的第一個簡單選擇器就是類型選擇器,它根據一個元素的標籤名來選中元素。github

好比:瀏覽器

div {}
複製代碼

這看上去很是簡單,可是實際上,咱們還必需要考慮html或者xml元素的命名空間問題。ide

好比咱們的svg元素,實際上在: http://www.w3.org/2000/svg 命名空間之下。svg

svg和html中都有a元素,咱們若要想區分選擇svg中的a和html中的a,就必須用帶命名空間的類型選擇器。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
<svg width="100" height="28" viewBox="0 0 100 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <desc>Example link01 - a link on an ellipse
  </desc>
  <a xlink:href="http://www.w3.org">
    <text y="100%">name</text>
  </a>
</svg>
<br/>
<a href="javascript:void 0;">name</a>
</body>
</html>

@namespace svg url(http://www.w3.org/2000/svg);
@namespace html url(http://www.w3.org/1999/xhtml);
svg|a {
  stroke:blue;
  stroke-width:1;
}

html|a {
  font-size:40px
}
複製代碼

這裏有一個特殊的選擇器,就是「 * 」 ,它稱爲全體選擇器,能夠選中任意元素。它的用法跟類型選擇器是徹底一致的,這裏就把它們放到一塊兒介紹了。


id選擇器與class選擇器

id選擇器和class選擇器都是針對特定屬性的選擇器。id選擇器是「#」號後面跟隨id名,class選擇器是「.」後面跟隨class名。咱們來看看基本用法:

#myid {
  stroke:blue;
  stroke-width:1;
}
.mycls {
  font-size:40px
}
複製代碼

這兩個選擇器都是在屬性選擇器以前就設計出來的選擇器,屬性選擇器出來了之後,理論上能夠必定程度上替代它們。可是要注意,class選擇器識別的是:用空格分隔的class語法。

<a class="a b c">xxx</a>
.a {
  color:red;
}
複製代碼

在這個例子中,咱們使用了用空格分隔的class屬性,使用「.a」「.b」或者「.c」都可以選中元素,也可使用多個class選擇器來要求元素具備多個類。


屬性選擇器

屬性選擇器根據HTML元素的屬性來選中元素。屬性選擇器有四種形態。


第一種,[att]

直接在方括號中放入屬性名,是檢查元素是否具備這個屬性,只要元素有這個屬性,不論屬性是什麼值,均可以被選中。


第二種,[att=val]

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


第三種,[att~=val]

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


第四種,[att|=val]

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

有些HTML屬性含有特殊字符,這個時候,能夠把val用引號括起來,造成一個CSS字符串。CSS字符串容許使用單雙引號來規避特殊字符,也能夠用反斜槓轉義,這樣,就能夠表示出任意屬性值啦。


僞類選擇器

僞類選擇器是一系列由CSS規定好的選擇器,它們以冒號開頭。僞類選擇器有普通型和函數型兩種。

咱們首先來介紹一下僞類中最經常使用的部分:樹結構關係僞類。


樹結構關係僞類選擇器

:root 僞類表示樹的根元素,在選擇器是針對完整的html文檔狀況,咱們通常用html標籤便可選中根元素。可是隨着scoped css和shadow root等場景出現,選擇器能夠針對某一子樹來選擇,這時候就很須要root僞類了。

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


  1. :nth-last-child的區別僅僅是從後往前數。
  2. :first-child :last-child 分別表示第一個和最後一個元素。
  3. :only-child 按字面意思理解便可,選中惟一一個子元素。

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。


連接與行爲僞類選擇器

連接與行爲是第一批設計出來的僞類,也是最經常使用的一批。

  1. :any-link 表示任意的連接,包括a、area和link標籤均可能匹配到這個僞類。
  2. :link 表示未訪問過的連接, :visited 表示已經訪問過的連接。
  3. :hover 表示鼠標懸停在上的元素,
  4. :active 表示用戶正在激活這個元素,如用戶按下按鈕,鼠標還未擡起時,這個按鈕就處於激活狀態
  5. :focus 表示焦點落在這個元素之上。
  6. :target 用於選中瀏覽器URL的hash部分所指示的元素。

在Selector Level 4草案中,還引入了 target-within、focus-within 等僞類,用於表示target或者focus的父容器。


邏輯僞類選擇器

咱們這裏介紹一個邏輯僞類 —— :not 僞類。

這個僞類是個函數型僞類,它的做用時選中內部的簡單選擇器命中的元素。

*|*:not(:hover)

選擇器3級標準中,not只支持簡單選擇器,在選擇器4級標準,則容許not接受一個選擇器列表,這意味着選擇器支持嵌套,僅靠not便可完成選擇器的一階真值邏輯完備,但目前尚未看到瀏覽器實現它。

在Selector Level 4草案中,還引入了:is :where :has 等邏輯僞類,可是它們有一些違背了選擇器匹配DOM樹不回溯的原則,因此這部分設計最終的命運如何還不太肯定。


其它僞類選擇器

還有一些草案中或者不經常使用的選擇器,你僅作大概瞭解便可。

  1. 國際化:用於處理國際化和多語言問題。
    • dir
    • lang
  2. 音頻/視頻:用於區分音視頻播放狀態。
    • play
    • pause
  3. 時序:用於配合讀屏軟件等時序性客戶端的僞類。
    • current
    • past
    • future
  4. 表格:用於處理table的列的僞類。
    • nth-col
    • nth-last-col

僞類是很大的一類簡單選擇器,它是選擇器能力的一種補充。在實際使用中,我仍是建議你儘可能經過合適的id和class來標識元素,約束僞類的使用。最好只在不得不使用僞類的場景使用僞類,這對於CSS代碼的性能和可讀性都有好處。


選擇器的組合

在CSS規則中,選擇器部分是一個選擇器列表。

  1. 選擇器列表是用逗號分隔的複雜選擇器序列;
  2. 複雜選擇器則是用空格、大於號、波浪線等符號鏈接的複合選擇器;
  3. 複合選擇器則是連寫的簡單選擇器組合。

根據選擇器列表的語法,選擇器的鏈接方式能夠理解爲像四則運算同樣有優先級。

  1. 第一優先級
    • 無鏈接符號
  2. 第二優先級
    • 「空格」
    • 「~」
    • 「+」
    • 「>」
    • 「||」
  3. 第三優先級
    • 「,」

例如如下選擇器:

.c,.a>.b.d {
/*......*/
}
複製代碼

咱們應該理解爲這樣的結構。

.c,.a>.b.d
.c
.a>.b.d
.a
.b.d
.b
.d
複製代碼

複合選擇器表示簡單選擇器中「且」的關係,例如,例子中的「 .b.d 」,表示選中的元素必須同時具備b和d兩個class。

複雜選擇器是針對節點關係的選擇,它規定了五種鏈接符號。

  1. 「空格」:後代,表示選中全部符合條件的後代節點, 例如「 .a .b 」表示選中全部具備class爲a的後代節點中class爲b的節點。
  2. 「>」 :子代,表示選中符合條件的子節點,例如「 .a>.b 」表示:選中全部「具備class爲a的子節點中,class爲b的節點」。
  3. 「~」 : 後繼,表示選中全部符合條件的後繼節點,後繼節點即跟當前節點具備同一個父元素,並出如今它以後的節點,例如「 .a~.b 」表4示選中全部具備class爲a的後繼中,class爲b的節點。
  4. 「+」:直接後繼,表示選中符合條件的直接後繼節點,直接後繼節點即nextSlibling。例如 「.a+.b 」表示選中全部具備class爲a的下一個class爲b的節點。
  5. 「||」:列選擇器,表示選中對應列中符合條件的單元格。

咱們在實際使用時,比較經常使用的鏈接方式是「空格」和「>」。

工程實踐中通常會採用設置合理的class的方式,來避免過於複雜的選擇器結構,這樣更有利於維護和性能。

空格和子代選擇器一般用於組件化場景,當組件是獨立開發時,很難徹底避免class重名的狀況,若是爲組件的最外層容器元素設置一個特別的class名,生成CSS規則時,則所有使用後代或者子代選擇器,這樣能夠有效避免CSS規則的命名污染問題。

逗號表示「或」的關係,實際上,能夠把它理解爲「兩條內容同樣的CSS規則」的一種簡寫。如咱們開頭的例子,能夠理解成與下面的代碼等效:

.c {
/*......*/
}
.a>.b.d {
/*......*/
}
複製代碼

到這裏,咱們就講完了如何用簡單選擇器組合成複合選擇器和複雜選擇器,造成選擇器列表,這可以幫助咱們應對各類複雜的需求。

CSS選擇器是基於規則生效的,同一個元素命中多條規則是很是常見的事情。不一樣規則指定同一個屬性爲不一樣值時,就須要一個機制來解決衝突。這個機制,就是接下來咱們要講的選擇器優先級。


選擇器的優先級

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

  1. id選擇器的數目記爲a;
  2. 僞類選擇器和class選擇器的數目記爲b;
  3. 僞元素選擇器和標籤選擇器數目記爲c;
  4. 「*」 不影響優先級。

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

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

行內屬性的優先級永遠高於CSS規則,瀏覽器提供了一個「口子」,就是在選擇器前加上「!import」。

這個用法很是危險,由於它至關於一個新的優先級,並且此優先級會高於行內屬性。

同一優先級的選擇器遵循「後面的覆蓋前面的」原則,咱們能夠看一個例子:

<div id="my" class="x y">text<div>
.x {
  background-color:lightblue;
}
.y {
  background-color:lightgreen;
}
複製代碼

調換「.x」和「.y」咱們能夠獲得不一樣的顯示效果。選擇器的優先級是針對單條規則的,多條規則的選擇器同時命中元素,優先級不會發生疊加。

<div id="my" class="x y z">text<div>
.x {
  background-color:lightblue;
}
.z {
  background-color:lightblue;
}
.y {
  background-color:lightgreen;
}
複製代碼

在這個例子中,「.x 」和「.z 」都指定了背景色爲淺藍色,可是由於「.y 」規則在最後,因此最終顯示結果爲淺綠色。另一個須要注意的是,選擇器的優先級是針對複雜選擇器的優先級,選擇器列表不會合並計算優先級。

咱們看一個例子:

<div id="my" class="x y z">text<div>
.x, .z {
  background-color:lightblue;
}
.y {
  background-color:lightgreen;
}
複製代碼

這裏選擇器列表「 .x, .z」命中了div,可是它的兩項分別計算優先級,因此最終優先級仍跟「 .y」 規則相同。

以上就是選擇器優先級的相關規則了,雖然咱們這裏介紹了詳細的計算方式,可是我認爲選擇器的使用上,若是產生複雜的優先級計算,代碼的可讀性必定是有問題的。

因此實踐中,建議你「根據 id 選單個元素」「class和class的組合選成組元素」「tag選擇器肯定頁面風格」這樣的簡單原則來使用選擇器,不要搞出過於複雜的選擇器。


僞元素

前面忽略了一種重要的簡單選擇器:僞元素。

之因此沒有把它放在簡單選擇器中,是由於僞元素自己不僅僅是一種選擇規則,它仍是一種機制。

僞元素的語法跟僞類類似,可是實際產生的效果倒是把不存在的元素硬選出來。

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

  1. ::first-line
  2. ::first-letter
  3. ::before
  4. ::after

下面咱們就來分別講講它們。

::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屬性,都是文本相關,這些屬性是下面這些。



接下來咱們說說 ::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中出現不少無語義的空元素。


結語

這這篇文章中,咱們介紹了CSS選擇器的總體結構,而且介紹了一系列簡單選擇器。它們包括了下面這些內容。

  1. 類型選擇器:根據一個元素的標籤名來選中元素。
  2. 全體選擇器:與類型選擇器相似,選擇任意元素。
  3. id選擇器:#後面跟隨id名。
  4. class選擇器:.後面跟隨class名。
  5. 僞類選擇器:一系列由CSS規定好的選擇器,它們以冒號開頭,僞類有普通型和函數型。

而後介紹了CSS選擇器的三種機制:選擇器的組合、選擇器優先級、以及僞元素。

在選擇器組合這一部分,咱們講到了,選擇器的鏈接方式像四則運算同樣有優先級, 第一優先級是無鏈接符號;第二優先級是:「空格」「~」「+」「>」「||」;第三優先級是「,」。

而後咱們又介紹了選擇器優先級的計算方式。

最後咱們爲你們介紹了僞元素,咱們逐次講解了:

  1. ::first-line
  2. ::first-letter
  3. ::before
  4. ::after

僞元素的語法跟僞類類似,可是實際產生的效果是把不存在的元素硬選出來。這一點就與僞類不太同樣了。

相關文章
相關標籤/搜索