初探CSS 選擇器Level 4
在開始聊CSS選擇器Level 4( ofollow,noindex" target="_blank">Selectors Level 4 )之前,先要明確一個簡單的概念。時至今日,在CSS的世界之中再不會有大版本的稱謂,比如以前大家熟悉的CSS2.1、CSS3。現在的CSS都只會以CSS模組的版本來進行區分,比如我們今天要聊的CSS選擇器,其最新版本就是: CSS Selectors Level 4 。在CSS Selectors Level 4中為選擇器增添了不少的新特性,當然這些新特性有的已得到瀏覽器的支援,有的只得到部分主流瀏覽器的支援。所以接下來,花點時間學習一下,以備後用。
:not()
否定偽類 :not()
是一個 函式偽類 ,以選擇器列表做為引數,它表示的元素不是由其引數表示的。 :not()
選擇器 可以用來做為判斷的一個選擇器,好比JavaScript中的非。其主要作用就是將符合規則的元素剔除,將樣式規則應用於其他元素上。事實上,在CSS Selector Level 3就有 :not()
的身影,只不過當初的功能比較弱,比如 :not(p)
用來選擇不是 <p>
的元素。但在新版本的中,其功能變得更為強大,可以應用更為複雜的規則,但是同樣地不允許巢狀使用,比如 :not(:not(...))
。
我們平時開發專案的時候,時常會碰到列表這樣的效果,列表項之間有一個 margin-bottom
,而往往想在最後一項中不設定 margin-bottom
。比如像下圖這樣的效果:
往往我們藉助偽類選擇器 :last-child
來幫我實現,比如:
li{ margin-bottom: 20px; } li:last-child { margin-bottom: 0; }
如果我們使用 :not()
選擇器,會變得更容易:
li:not(:last-child) { margin-bottom: 20px }
上面的程式碼表示的意思就是: 選中除最後一項 li
的所有 li
,並給其設定 margin-bottom: 20px;
。
另外, :not()
選擇器還有一個提高CSS權重的小作用,比如 div:not(span)
跟 div
是同一個概念,但是明顯的前者的優先順序要更高。
瀏覽器的支援度:
:has()
關係偽類 :has()
和 :not()
選擇器類似,也是一個函式偽類,不同的是 :has()
使用相對選擇器列表作為引數。它表示一個元素,任何一個相對選擇器(當將元素絕對化並將其賦值為 :scope
元素)至少匹配一個元素。
:has()
偽類有點類似於jQuery中的 .has()
方法,簡單來說就是用來 匹配含有某些規則的元素 。比如:
// 匹配含有`img`子元素的`a`元素 a:has(> img) { } // 匹配擁有dt兄弟元素的dt元素 dt:has(+ dt) {} // 匹配不含有h1、h2、h3、h4、h5和h6的section元素 section:not(:has(h1, h2, h3, h4, h5, h6)) {} // 匹配含有的不是h1、h2、h3、h4、h5、h6子元素的元素 section:has(:not(h1, h2, h3, h4, h5, h6)) {}
最後兩個示例是 :not()
和 :has()
組合在一起使用的,但兩者組合在一起所達到的意思卻完全不一樣。其中 :not(:has(selector))
匹配不含有 selector
選擇元素的元素(有點繞,對應看上面示例描述),而 :has(:not(selector))
匹配含有的不是 selector
子元素的元素。兩都主要區別在於, :has(:not(selector))
寫法必須要含有一個子元素,而 :not(:has())
可以不含有元素也會被匹配。
:matches()
:matches()
同樣是一個函式偽類,以選擇器列表作為引數。主要用於匹配所述規則的元素,並應用相應的樣式規則,選擇該列表中任意一個選擇器可以選擇的元素。它可以讓我們節省書寫大量的 CSS 樣式匹配規則,讓我們從大量重複的規則書寫中解放出來。
來看兩個示例:
.matches { color: black; } .matches :matches(span, div) :matches(span, div) { color: green; }
上面的程式碼等同於:
.matches span div, .matches span span, .matches div span, .matches div div { color: green; }
注意,許多瀏覽器通過一個更舊的偽類選擇器 :any()
來替代 :matches()
,並且要帶上對應的瀏覽器私有字首, :-webkit-any()
、 :-moz-any()
,其工作方式與 :matches()
完全相同,比如上面示例,我們可以改寫成:
.matches :-webkit-any(span, div) :-webkit-any(span, div) { color: green; } .matches :-moz-any(span, div) :-moz-any(span, div) { color: green; }
來看一個簡單的示例:
示例中通過一行程式碼:
:matches(header, main, footer) p:hover { color: red; cursor: pointer; }
就替代了:
header p:hover, main p:hover, footer p:hover { color: red; cursor: pointer; }
如果你使用過CSS的處理器,就較好理解,它有點類似於CSS處理器中的巢狀規則。
有一點需要注意, :matches()
不能巢狀工作,也不能和 :not()
配合在一起工作,比如下面的幾個選擇器,都將無法正常工作:
:matches(:not(...)) {} :not(:matches(...)) {} :matches(:matches(...)) {}
除此之外,在 :matches()
傳遞的選擇器列表中也不允許一些組合選擇器,比如 ~
、 >
和 +
等。
瀏覽器支援度:
:something()
:something()
被稱為權重調整偽類,也是一個函式偽類,其語法和功能與 :matches()
類似。其不同之處是 :something()
偽類和它的任何引數都不影響選擇器的權重, 它的權重總是為 0
。
對於在選擇器中引入過濾器很有用,同時保持關聯的樣式宣告易於重寫。
下面是一個常見的例子:
a:not(:hover) { text-decoration: none; } nav a { /* 無效果 */ text-decoraation: underline; }
如果我們使用 :something()
偽類選擇器就可以達到作者期望的效果:
a:something(:not(:hover)) { text-decoration: none; } nav a { /* Works now! */ text-decoration: underline; }