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-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
readonly
和disabled
。read-write
),textarea
和全部的input
元素的默認行爲是同樣的。div
)有紅色的外輪廓,由於設置了contenteditable
屬性。在CSS
中,我很普通的使用了這兩個選擇器(沒有將它們應用到任何元素),這也意味着全部的div
、span
和其它不可編輯元素會有紅色的外輪廓,更像被用在特定的表單元素或有特定類選擇器的元素。瀏覽器
:read-write
可能會在編輯草案中被移除。ide
:read-only
和 :read-write
的支持:Chrome, Opera, Firefox, Safari.注意:正以下面的demo顯示,支持這些選擇器的瀏覽器將設置了disabled
的input
元素定義爲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; }
: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; }
這兩個僞類在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
元素自身,來代表全部字段數據是有效的。div
、p
等普通元素不起做用,由於這些元素沒有什麼方法來指定預期的數據格式。<input type="text">
,默認是有效的,但若是設置了require
屬性卻沒有數據則是無效的。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; }
這兩個僞類對於那些要求數據介於一個指定範圍的表單元素是很是有用的。你能夠根據元素數據是否在指定範圍以內來設計輸入框樣式。
於是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; }
這兩個僞類能讓你基於表單字段是否須要填寫來設計表單元素的樣式。拿下面的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
元素使用僞類了,於是這種狀況下你必須應用不一樣的樣式。
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)'; }
在CSS中,默認對屬性的大小寫是敏感的。例如,要選擇全部href
屬性的值以pdf結尾的元素,就不會選中其屬性值以PDF結尾的。有一個頗有用的新標記能夠被添加到屬性選擇器中來覆蓋這種行爲:
a[href$="pdf" i] { color: red; }
如今屬性選擇器將選擇全部href
連接到PDF文件的元素,無論.pdf擴展名是小寫、大寫仍是混合寫的。
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; }
[: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
則選擇兩個段落。
可能很難記住兩者的差異,由於名字很類似,規範中也記錄了一些問題,這個選擇器可能會改名。
: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-
私有前綴。: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。規範說明
:any-link選擇器是爲任何具備href
屬性指定樣式的快捷方式,包括a
、area
和link
元素等,也能按照下面的方式使用:
:link, :visited { color: #555; }
做爲代替,應該這樣寫:
:any-link { color: #555; }
須要注意的是,在工做草案中有一個:local-link
僞類,已經在編輯草案中被移除。
這是一個有趣的選擇器,我能夠明確地看到它是有用的。: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
也有一樣的外輪廓。
在APPs中,拖放是很基礎但又重要的功能。這兩個選擇器在改善用戶體驗上是頗有價值的。:drop
選擇器能夠設置放置區樣式(將要防止被拖動元素的地方),元素在用戶的拖動期間是可放置的。
.spot { background: #ccc; } .spot:drop { background: hotpink; }
用戶沒有拖動時,.spot
元素會有一個灰色背景;但當用戶開始拖動.spot
元素時,其背景色會改變,直到元素被放下。
:drop()
的值爲下列中的一個或多個關鍵字:
active
:爲被拖動的元素顯示當前的放置目標valid
:顯示與被拖動元素相關聯的放置目標是否有效invalid
:和前一個相反,若是與被拖動元素相關聯的放置目標無效則爲其應用樣式應用多關鍵字將讓事情更具體,若是沒有給予參數,其行爲和: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/