【譯】下一代選擇器:CSS4

2014年1月,我寫了一篇文章:The Current Generation of CSS3 Selectors,這篇文章的目的是介紹一些CSS3中新增的選擇器。文中的選擇器已經有了不少文檔,而且也被大多數瀏覽器支持(包括IE9+)。css

因爲Selectors Level 4 specification 目前已經是工做草案狀態,而且Editor’s Draft of the same spec也在進行中(編輯草案一般被視爲更有權威),將來的CSS選擇器看起來很明朗了,html

這篇文章重點介紹沒有在以前那篇文章中出現的新選擇器。瀏覽器對這些新特性的支持並不樂觀,因此我不建議在生產環境中使用這些新選擇器。能夠把這篇文章視爲當規範進一步完善而且瀏覽器開始支持CSS4的時候,它會帶來什麼影響。對於已經被支持的特性,我例舉了demo。jquery

:read-only 和 :read-write

這兩個選擇器是很簡單的。任何可編輯的元素都是read-write狀態,反之,元素則是read-only狀態。看一下下面HTML:css3

<input type="text" readonly>
<input type="text" disabled>
<input type="text">
<div contenteditable></div>

CSS以下:web

:read-only {
  outline: solid 1px blue;
}

:read-write {
  outline: solid 1px red;
}

對上述代碼的分析以下:api

  • 開始的兩個元素有藍色的外輪廓,由於在HTML中,它們分別設置了readonlydisabled
  • 第三個元素有紅色的外輪廓,由於它是天然的可編輯狀態(read-write),textarea和全部的input元素的默認行爲是同樣的。
  • 最後一個元素(div)有紅色的外輪廓,由於設置了contenteditable屬性。

CSS中,我很普通的使用了這兩個選擇器(沒有將它們應用到任何元素),這也意味着全部的divspan和其它不可編輯元素會有紅色的外輪廓,更像被用在特定的表單元素或有特定類選擇器的元素。瀏覽器

:read-write可能會在編輯草案中被移除。ide

瀏覽器對:read-only:read-write的支持:Chrome, Opera, Firefox, Safari.

注意:正以下面的demo顯示,支持這些選擇器的瀏覽器將設置了disabledinput元素定義爲read-write,然而根據規範,這是不正確的。ui

HTML:this



<div class="c"> <h2>Demo for <code>:read-only</code> and <code>:read-write</code></h2> This input is "readonly": <input type="text" readonly> <br> This input is "disabled": <input type="text" disabled> <br> This input is normal: <input type="text"> <br> <div class="ce" contenteditable>This div is contenteditable</div> <div class="ro">This div has nothing special.</div> <p><strong>Legend:</strong> Red outline: read-write; Blue outline: read-only</p> <p class="p">Demo by Louis Lazaris. <a href="http://www.sitepoint.com/future-generation-css-selectors-level-4" target="_blank">See article</a>.</p> </div>

CSS:

body {
  line-height: 2em;
}

.c {
  width: 600px;
  margin: auto;
}

.p {
  text-align: center;
  font-size: .9em;
  padding-top: 100px;
}

input:read-write, .ce:read-write, .ro:read-write {
  outline: solid 1px red;
}

input:read-only, .ce:read-only, .ro:read-only {
  outline: solid 1px blue;
}

View this code on codepen

默認選項僞類: :default

:default 僞類會匹配那些在一組相關的集合中做爲默認選項的元素。例如,一個表單的默認提交按鈕或一組單選按鈕中被默認選中的按鈕。

以下面的HTML片斷顯示的那樣,能夠有多個默認選項:

<input type="checkbox" value ="f" name="group" checked> Fruits
<input type="checkbox" value ="v" name="group"> Vegetables
<input type="checkbox" value ="m" name="group" checked> Meats
<input type="checkbox" value ="p" name="group" checked> Poultry
<input type="checkbox" value ="n" name="group"> Nuts
<input type="checkbox" value ="b" name="group"> Breads

將下面的CSS應用到上面的HTML

input[type=checkbox]:default {
  outline: solid 1px hotpink;
}

在這個案例中,全部有checked屬性的元素將呈現一個外輪廓的樣式。

瀏覽器對:default的支持:Chrome, Opera, Firefox, Safari.

在這個demo中,儘管默認選中的複選框應該有一個外輪廓,可是WebKit/Blink瀏覽器不會爲默認選中的複選框應用輪廓,這看起來是一個Bug。Firefox能正確呈現。

HTML:



<div class="c"> <h2>Demo for <code>:default</code></h2> <input type="checkbox" value="f" name="group"> Fruits <input type="checkbox" value="v" name="group"> Vegetables <input type="checkbox" value="m" name="group" checked> Meats <input type="checkbox" value="p" name="group" checked> Poultry <input type="checkbox" value="n" name="group"> Nuts <input type="checkbox" value="b" name="group"> Breads <form onsubmit="return false;"> <input type="submit"> <input type="submit"> </form> <p>The items with a pink outline are in the "default" state. Chrome and Opera incorrectly fail to add the pink outline to the checkboxes.</p> <p class="p">Demo by Louis Lazaris. <a href="http://www.sitepoint.com/future-generation-css-selectors-level-4" target="_blank">See article</a>.</p> </div>

CSS:

body {
  line-height: 2em;
}

.c {
  width: 500px;
  margin: auto;
}

.p {
  text-align: center;
  font-size: .9em;
  padding-top: 100px;
}

input[type=checkbox]:default {
  outline: solid 1px hotpink;
}

input:default {
  outline: solid 1px hotpink;
}

View this code in codepen

有效性僞類: :valid 和 :invalid

這兩個僞類在HTML表單中是很是有用的,它能給予用戶在輸入數據時視覺上的有效性,而這些本應該有JavaScript完成的。

看一個示例:

Email: <input type="email" required>

注意,這個字段期待被輸入的數據時有效的郵件地址,能夠這樣作:

input[type=email]:invalid {
  outline: red solid 1px;
}

input[type=email]:valid {
  outline: lightgreen solid 1px;
}

根據上面的CSS,用戶沒有輸入以前,email字段將有紅色的外輪廓,一旦用戶輸入合法的電子郵件,外輪廓會變成綠色。

用這些僞類能夠很容易的在表單元素以前添加一個綠標記的僞元素(或其它相似的)來顯示有效的字段數據。

須要注意的是:

  • 有趣的是,有效性檢測也能應用到form元素自身,來代表全部字段數據是有效的。
  • divp等普通元素不起做用,由於這些元素沒有什麼方法來指定預期的數據格式。
  • 普通且沒有要求特定數據格式的<input type="text">,默認是有效的,但若是設置了require屬性卻沒有數據則是無效的。

瀏覽器對 :valid 和 :invalid支持:Chrome, Opera, Firefox, Safari, IE10+.

HTML:



<div class="c"> <h2>Demo for <code>:valid</code> and <code>:invalid</code></h2> Email: <input type="email" required> <p>Type an email address. The outline will change from red to green.</p> <p class="p">Demo by Louis Lazaris. <a href="http://www.sitepoint.com/future-generation-css-selectors-level-4" target="_blank">See article</a>.</p> </div>

CSS:

body {
  line-height: 2em;
}

.c {
  width: 500px;
  margin: auto;
}

.p {
  text-align: center;
  font-size: .9em;
  padding-top: 100px;
}

input[type=email]:invalid {
  outline: red solid 2px;
}

input[type=email]:valid {
  outline: lightgreen solid 2px;
}

View this code on codepen

範圍僞類: :in-range 和 :out-of-range

這兩個僞類對於那些要求數據介於一個指定範圍的表單元素是很是有用的。你能夠根據元素數據是否在指定範圍以內來設計輸入框樣式。

於是HTML應該像這樣子的:

<input type="date"
       min="1994-01-01" max="2015-03-01"
       value="1993-01-01">

注意默認值是"1993-01-01",不在數據容許的範圍以內。你能夠根據默認數據和輸入的數據來動態地設計輸入框樣式,像這樣:

input[type=date]:in-range {
  outline: lightgreen solid 1px;
}

input[type=date]:out-of-range {
  outline: red solid 1px;
}

須要注意的是:

  • 能應用於number, datetime, datetime-local, month, week及其它容許範圍的輸入
  • 支持range,但我不認爲有一種方法能使range元素的數據超出範圍,這種狀況下,使用這兩個僞類的做用是很是有限的。
  • 和其它僞類同樣,此僞類僅做用在有能力定義可接受的數據範圍的元素

瀏覽器對 :in-range 和 :out-of-range支持:Chrome, Opera, Firefox, Safari.

HTML:



<div class="c"> <h2>Demo for <code>:in-range</code> and <code>:out-of-range</code></h2> <input type="date" min="1994-01-01" max="2015-03-01" value="1993-01-01"> <p>This date field expects a date between "1994-01-01" and "2015-03-01". Change to a valid date to see the outline switch from red to green.</p> <p class="p">Demo by Louis Lazaris. <a href="http://www.sitepoint.com/future-generation-css-selectors-level-4" target="_blank">See article</a>.</p> </div>

CSS:

body {
  line-height: 2em;
}

.c {
  width: 500px;
  margin: auto;
}

.p {
  text-align: center;
  font-size: .9em;
  padding-top: 100px;
}

input[type=date]:in-range {
  outline: lightgreen solid 1px;
}

input[type=date]:out-of-range {
  outline: red solid 1px;
}

View this code on codepen

可選擇性僞類: :required 和 :optional

這兩個僞類能讓你基於表單字段是否須要填寫來設計表單元素的樣式。拿下面的HTML爲例:

<div>
  <label for="name">name:</label>
  <input type="text" id="name" required>
  <span class="msg"></span>
</div>
<div>
  <label for="email">Email:</label>
  <input type="email" id="email" required>
  <span class="msg"></span>
</div>
<div>
  <label for="address">Address:</label>
  <input type="text" id="address">
  <span class="msg"></span>
</div>

每一個input後面添加了一個空的span元素,同時前面兩個input元素是比填的,第三個是非必填的。CSS以下:

input:required ~ .msg:after {
  content: '*';
  color: red;
}

input:optional ~ .msg:after {
  content: '(optional)';
}

在這個示例中,我用兄弟選擇器在緊跟每一個必填字段的後面添加一個紅色星號,非必填字段後添加 「optional」。

示例中使用了我額外添加的元素。若是你不喜歡,可使用JavaScript動態添加或直接在input元素上使用其餘樣式,可是不能對錶單的input元素使用僞類了,於是這種狀況下你必須應用不一樣的樣式。

瀏覽器對 :required 和 :optional的支持:全部瀏覽器.

HTML:



<div class="c"> <h2>Demo for <code>:required</code> and <code>:optional</code></h2> <div> <label for="name">Name:</label> <input type="text" id="name" required> <span class="msg"></span> </div> <div> <label for="email">Email:</label> <input type="email" id="email" required> <span class="msg"></span> </div> <div> <label for="address">Address:</label> <input type="text" id="address"> <span class="msg"></span> </div> <p>The red asterisks and "(optional)" text are added via CSS, based on the presence or absence of the <code>required</code> attribute.</p> <p class="p">Demo by Louis Lazaris. <a href="http://www.sitepoint.com/future-generation-css-selectors-level-4" target="_blank">See article</a>.</p> </div>

CSS:

body {
  line-height: 2em;
}

.c {
  width: 500px;
  margin: auto;
}

.p {
  text-align: center;
  font-size: .9em;
  padding-top: 100px;
}

form div {
  padding: 10px;
}

input:required ~ .msg:after {
  content: '*';
  color: red;
}

input:optional ~ .msg:after {
  content: '(optional)';
}

View this code on codepen

不區分大小寫的屬性選擇器: i

在CSS中,默認對屬性的大小寫是敏感的。例如,要選擇全部href屬性的值以pdf結尾的元素,就不會選中其屬性值以PDF結尾的。有一個頗有用的新標記能夠被添加到屬性選擇器中來覆蓋這種行爲:

a[href$="pdf" i] {
  color: red;
}

如今屬性選擇器將選擇全部href連接到PDF文件的元素,無論.pdf擴展名是小寫、大寫仍是混合寫的。

瀏覽器對 i 的支持:Opera.

HTML:



<div class="c"> <h2>Demo for case-insensitive attribute selectors</h2> <ul> <li><a href="example.pdf" onclick="return false;">example.pdf</a></li> <li><a href="example.PDF" onclick="return false;">example.PDF</a></li> <li><a href="example.Pdf" onclick="return false;">example.Pdf</a></li> </ul> <p>In non-supporting browsers, only the first link is red. In supporting browsers, all links are red.</p> <p class="p">Demo by Louis Lazaris. <a href="http://www.sitepoint.com/future-generation-css-selectors-level-4" target="_blank">See article</a>.</p> </div>

CSS:

body {
  line-height: 2em;
}

.c {
  width: 500px;
  margin: auto;
}

.p {
  text-align: center;
  font-size: .9em;
  padding-top: 100px;
}

form div {
  padding: 10px;
}

a[href$="pdf"] {
  color: red;
}

a[href$="pdf" i] {
  color: red;
}

View this code on codepen

:blank僞類

[:blank]僞類和:empty有點相似,在The Current Generation of CSS3 Selectors一文中介紹了empty的用法。用empty能夠選擇沒有子元素的元素,無論其子元素是一個元素、文本節點仍是空白節點,所以若是元素即便只包含一個空格,也不被認爲是"empty"的。

然而,:blank僞類將選擇沒有文本和其它子元素,包含空白的元素,它能包含空白、換行符等,這依然是有合格的。

HTML以下 :

<p></p>

<p> </p>

第一個段落是徹底的空元素,但第二個有一個空白字符。CSS以下:

p:blank {
  outline: solid 1px red;
}

p:empty {
  border: solid 1px green;
}

在這個示例中,對「blank」元素應用了紅色的外輪廓,對 「empty」元素應用了綠色的邊框。:empty僅選擇第一個段落,由於它是徹底的空元素;:blank則選擇兩個段落。

可能很難記住兩者的差異,由於名字很類似,規範中也記錄了一些問題,這個選擇器可能會改名。

瀏覽器對 :blank的支持:沒有瀏覽器支持。

Matches-any僞類: :matches()

:matches()僞類是使選擇分組更簡潔的一種方式,當瀏覽器對其的支持狀況獲得改善時,是對規範頗有用的一個補充。

MDN的一個示例中,CSS以下:

section section h1, section article h1,
section aside h1, section nav h1,
article section h1, article article h1, 
article aside h1, article nav h1,
aside section h1, aside article h1,
aside aside h1, aside nav h1,
nav section h1, nav article h1, 
nav aside h1, nav nav h1, {
  font-size: 20px;
}

:matches(),能將其簡化:

:matches(section, article, aside, nav)
:matches(section, article, aside, nav) h1 {
  font-size: 20px;
}

簡化的版本能夠解釋爲:對這四個元素,若是h1在任意一個以內,並在任何相同的四個元素以內,則應用後面的規則。

須要注意的是:

  • 以往的規範中是使用:any,須要添加-moz--webkit-私有前綴。
  • 正如CSS-Tricks指出的,原則同選擇器在預處理器中的嵌套規則。
  • 該選擇器的參數必須是一個」簡單選擇器「(不能是一個僞元素;除了子節點,不能使用鏈接符)

瀏覽器對 :matches()的支持:沒有瀏覽器支持。但WebKit/Blink和Mozilla有等效的渲染選擇。

相關僞類: :has()

:has() 僞類相似於JQuery中的.has()方法,但前者有更普遍的能力。看一個示例就清楚了。注意代碼中的註釋,它解釋了每個示例選擇什麼元素。

/* Section elements that contain a footer */
section:has(footer) {
  background: #ccc;
}

/* Any element containing a p element with a class of "alert" */
:has(p.alert) {
  background-color: red;
}

/* img element with paragraph immediately following. */
img:has(+p) {
  color: red;
}

/* list item with ul as a direct child */
li:has(> ul) {
  color: red;
}

注意,:has()存在編輯草案中而不是工做草案中;也正如Ralph在評論中指出的那樣,這個選擇器僅能經過JavaScript纔可用(相似querySelectorAll),而不是CSS。規範說明

瀏覽器對 :has()的支持:沒有瀏覽器支持。

超連接僞類: :any-link

:any-link選擇器是爲任何具備href屬性指定樣式的快捷方式,包括aarealink元素等,也能按照下面的方式使用:

:link, :visited {
  color: #555;
}

做爲代替,應該這樣寫:

:any-link {
  color: #555;
}

須要注意的是,在工做草案中有一個:local-link僞類,已經在編輯草案中被移除。

瀏覽器對 :any-link的支持:Chrome, Opera, 和Firefox(須要私有前綴)

輸入焦點僞類: :focus-within

這是一個有趣的選擇器,我能夠明確地看到它是有用的。:focus-within不只會選擇得到焦點的元素,還會選擇其父元素。

示例的HTML:

<div>
  <label for="email">Email:</label>
  <input type="email" id="email">
</div>

CSS以下:

input:focus-within {
  outline: yellow solid 1px;
}

這不只會致使得到焦點的input元素有黃色的外輪廓,其父元素div也有一樣的外輪廓。

瀏覽器對 :focus-within的支持:沒有瀏覽器支持。

拖放僞類: :drop 和 :drop()

在APPs中,拖放是很基礎但又重要的功能。這兩個選擇器在改善用戶體驗上是頗有價值的。
:drop選擇器能夠設置放置區樣式(將要防止被拖動元素的地方),元素在用戶的拖動期間是可放置的。

.spot {
  background: #ccc;
}

.spot:drop {
  background: hotpink;
}

用戶沒有拖動時,.spot元素會有一個灰色背景;但當用戶開始拖動.spot元素時,其背景色會改變,直到元素被放下。

:drop() 的值爲下列中的一個或多個關鍵字:

  • active:爲被拖動的元素顯示當前的放置目標
  • valid:顯示與被拖動元素相關聯的放置目標是否有效
  • invalid:和前一個相反,若是與被拖動元素相關聯的放置目標無效則爲其應用樣式

應用多關鍵字將讓事情更具體,若是沒有給予參數,其行爲和:drop同樣。

注意:

  • 工做草案規範有一組徹底不一樣與此的僞類,所以這些選擇器仍在變化中
  • drop()是有"危險的",有可能被移除

瀏覽器對 :drop 和 :drop()的支持:沒有瀏覽器支持

提名獎

除了上面提到的,還有一些新特性我不打算細講,但也值得簡單提一下:
* 列鏈接符(||):用於定義table和grid中的列和單元格之間的關係
* :nth-column():nth-last-column()僞類用於指定table和grid中的特定列
* attr():屬性節點選擇器,是第一個非元素選擇器
* 後代選擇器由>>代替(而不只是一個空格字符)
* :user-error僞類:爲用戶輸入的數據不正確的文本框設置樣式
* @namespace:定義命名空間
* :dir()僞類:根據方向來選擇元素(如ltr
* :scope僞類:爲選擇元素提供一個做用域或引用點
* :current, :past, 和 :future僞類:定義目標元素在時間進程上的樣式,如一個視頻字幕。
* :placeholder-shown僞類:定義表單元素中placeholder值不爲空的input元素的樣式

結束語和更多信息

正如以前提到的,這些功能很是新,並無被很好的支持,僅展現了瀏覽器支持的信息和demos。

爲了跟上進展,這裏有一些關於CSS 4的資源:

譯文出處:http://www.ido321.com/1590.html

本文根據@Louis Lazaris的《The Future Generation of CSS Selectors: Level 4》所譯,整個譯文帶有我本身的理解與思想,若是譯得很差或有不對之處還請同行朋友指點。如需轉載此譯文,需註明英文出處:http://www.sitepoint.com/future-generation-css-selectors-level-4/

相關文章
相關標籤/搜索