CSS 屬性選擇器,能夠經過已經存在的屬性名或屬性值匹配元素。css
屬性選擇器是在 CSS2 中引入的而且在 CSS3 中獲得了很好拓展。本文將會比較全面的介紹屬性選擇器,儘量的去挖掘這個選擇器在不一樣場景下的不一樣用法。html
下面幾個屬於 CSS3 新增語法,也被稱爲「僞正則選擇器」,由於它們提供相似 regular expression 的靈活匹配方式。前端
屬性選擇器最基本的用法,就是經過元素的屬性值去選擇 DOM 元素。像這樣,將選中全部帶 href
屬性的DOM 元素:git
[href] {
color: red;
}
複製代碼
CodePen Demo -- 屬性選擇器基本用法github
div [href]{
...
}
複製代碼
選擇一個 img 標籤,它含有 title 屬性,而且包含類名爲 logo 的元素。正則表達式
img[title][class~=logo]{
...
}
複製代碼
i
參數忽略類名的大小寫限制,選擇包含 class 類名包含子字符串爲 text,Text,TeXt... 等狀況的 p 元素。 這裏的 i 的含義就是正則裏面參數 i 的含義,ignore,忽略大小寫的意思。express
p[class*="text" i] {
...
}
複製代碼
因此上面的選擇器能夠選中相似這樣的目標元素:瀏覽器
<p class="text"></p>
<p class="nameText"></p>
<p class="desc textarea"></p>
複製代碼
g
參數與正則表達式不同,參數 g
在這裏表示大小寫敏感(case-sensitively)。然而,這個屬性當前仍未歸入標準,支持的瀏覽器很少。網站
:not()
僞類還有一種比較經常使用的場景就是搭配:not()
僞類,完成一些判斷檢測性的功能。譬以下面這個選擇器,就能夠選取全部沒有 [href]
屬性的 a
標籤,添加一個紅色邊框。
a:not([href]){
border: 1px solid red;
}
複製代碼
固然,複雜一點,咱們能夠搭配不只僅一個 :not()
僞類,像是這樣,能夠同時多個配合使用,選擇一個 href, target, rel 屬性都沒有的 a 標籤:
a:not([href]):not([target]):not([rel]){
border: 1px solid blue;
}
複製代碼
CodePen Demo -- 屬性選擇器配合 :not 僞類
甚至乎,若是有這種場景,咱們還能夠覆蓋掉行內樣式,像這樣:
<p style="height: 24px; color: red;">xxxxxx</p>
複製代碼
咱們可使用屬性選擇器強制覆蓋掉上述樣式:
[style*="color: red"] {
color: blue !important;
}
複製代碼
固然,屬性選擇器不必定只是單單的進行標籤的選擇。
配合上僞元素,咱們能夠實現不少有助提高用戶體驗的功能。
這裏有一個小知識點,僞元素的 content
屬性,經過 attr(xxx)
,能夠讀取到對應 DOM 元素標籤名爲 xxx 的屬性的值。
因此,配合屬性選擇器,咱們能夠很容易的實現一些角標功能:
<div count=「5「>Message</div>
複製代碼
div {
position: relative;
width: 200px;
height: 64px;
}
div::before {
content: attr(count);
...
}
複製代碼
這裏右上角的數字 5 提示角標,就是使用屬性選擇器配合僞元素實現,能夠適應各類長度,以及中英文,可以節省一些標籤。CodePen Demo -- 屬性選擇器實現角標功能
咱們都知道,若是給一個圖片添加一個 title 屬性,當 hover 到圖片上面的時,會展現 title 屬性裏面附加的內容,相似這樣:
<img src="xxxxxxxxx" title="風景圖片">
複製代碼
這裏不必定是 img
標籤,其餘標籤添加 title
屬性都能有相似的效果。可是這裏會有兩個問題:
因此這裏,若是咱們但願有一些本身可以控制樣式的可快速響應的浮層,能夠自定義一個類 title 屬性,咱們把它稱做 popTitle
,那麼能夠這樣操做:
<p class="title" popTitle="文字彈出">這是一段描述性文字</p>
<p class="title" popTitle="標題A">這是一段描述性文字</p>
複製代碼
p[popTitle]:hover::before {
content: attr(popTitle);
position: absolute;
color: red;
border: 1px solid #000;
...
}
複製代碼
對比一下,第一個是原生自帶的 title
屬性,下面兩個是使用屬性選擇器配合僞元素模擬的提示:
瀏覽器自帶的
title
屬性延遲響應是添加一層防抖保護,避免頻繁觸發,這裏也能夠經過對僞元素添加一個100毫秒級的transition-delay
實現延遲展現。
CodePen Demo -- 屬性選擇器配合僞元素實現類 title 功能
好,上面的運用實例咱們再拓展一下,考慮如何更好的運用到實際業務中,其實也是有不少用武之地的。譬如說,經過屬性選擇器給圖片添加標籤,相似一些電商網站會用到的一個效果。
咱們但願給圖片添加一些標籤,在 hover 圖片的時候展現出來。
固然,CSS 中,諸如
<img>
、<input>
、<iframe>
,這幾個標籤是不支持僞元素的。
因此這裏咱們輸出 DOM 的時候,給 img 的父元素帶上部分圖片描述標籤。經過 CSS 去控制這些標籤的展現:
<div class="g-wrap" desc1="商品描述AAA" desc2="商品描述BBB">
<img src="https://xx.baidu.com/timg?xxx" >
</div>
複製代碼
[desc1]::before,
[desc2]::after {
position: absolute;
opacity: 0;
}
[desc1]::before {
content: attr(desc1);
}
[desc2]::after {
content: attr(desc2);
}
[desc1]:hover::before,
[desc2]:hover::after{
opacity: 1;
}
複製代碼
看看效果:
CodePen Demo -- 經過屬性選擇器給圖片添加標籤
咱們知道,HTML5 對標籤新增了一個 download 屬性,此屬性指示瀏覽器下載 URL 而不是導航到它。
那麼,咱們能夠利用屬性選擇器對全部帶此類標籤的元素進行提示。像這樣:
<a href="https://www.xxx.com/logo.png" download="logo">logo</a>
複製代碼
[download] {
position: relative;
color: hotpink;
}
[download]:hover::before {
content: "點擊可下載此資源!";
position: absolute;
...
}
複製代碼
當咱們 hover 到這個連接的時候,就會這樣,提示用戶,這是一個能夠下載的按鈕:
CodePen Demo -- 屬性選擇器配合僞元素作下載提示
如今大部分網站不是切了 https 就是走在切 https 的路上。若是頁面上的連接不少或者對跳轉頁面的協議有要求,使用屬性選擇器配合僞元素對連接的協議進行提示也不失爲一種好方法。
a[href^="http:"]:hover::before {
content: "這是一個http連接";
...
}
a[href^="https:"]:hover::before {
content: "這是一個https連接";
}
複製代碼
CodePen Demo -- 屬性選擇器配合僞元素對連接的協議進行提示(http/https)
固然,僞元素的內容不必定是純文字的,爲了給用戶更好的體驗,圖或者圖片加文字也是能夠的。
譬如咱們能夠形象化地給 https 連接站點再加一個小綠鎖,符合用戶的一些常規認知。
這裏我將小綠鎖的圖片使用 base64 嵌入到僞元素當中,簡單的使用 text-indent
控制圖文的排布:
a[href^="https:"]:hover::before {
content: "";
padding-left: 16px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAb0lEQVQoz2NkQAJc5aIc//7962VgYIiDCi1iYmIq/tb5+gdMDROyBqhiGWYmJlVmJiZVBgYGGagYdsBRKvyZu1xUAsbnLheV4CgV/oxbQ4nwf0JiTAwkAkaIU4QaGf4z1uFX+b/pR/e7epJtGJEaAKDXHzEJ3KYmAAAAAElFTkSuQmCC");
...
}
複製代碼
這裏只是一個很是小的 Demo,實際狀況是大部分用戶並不瞭解這個小綠鎖的含義,因此實際使用應該搭配文字輔助提示。
CodePen Demo -- 屬性選擇器配合僞元素對https協議進行圖文提示
也能夠對一些可下載資源進行視覺上 icon 的提示。
<ul>
<li><a href="xxx.doc">Word File</a></li>
<li><a href="xxx.ppt">PPT File</a></li>
<li><a href="xxx.PDF">PDF File</a></li>
<li><a href="xxx.MP3">MP3 File</a></li>
<li><a href="xxx.avi">AVI File</a></li>
</ul>
複製代碼
a[href$=".doc" i]::before {
content: "doc";
background: #a9c4f5;
}
a[href$=".ppt" i]::before {
content: "ppt";
background: #f8e94f;
}
a[href$=".pdf" i]::before {
content: "pdf";
background: #fb807a;
}
a[href$=".mp3" i]::before {
content: "mp3";
background: #cb5cf5;
}
a[href$=".avi" i]::before {
content: "avi";
background: #5f8ffc;
}
複製代碼
input
類型的處理屬性選擇器其實對 input
類型的元素是一個很好的幫手,由於 input
經常使用,且常常搭配不少不一樣功能的屬性值。
只不過,因爲 input
類型沒法添加僞元素。因此搭配屬性選擇器更多的經過屬性的各類狀態改變自身的樣式。
簡單舉個例子,譬如:
<input type="text">
<input type="text" disabled>
複製代碼
input[type=text][disabled] {
border: 1px solid #aaa;
background: #ccc;
}
複製代碼
這裏,咱們選擇了 type=text
而且擁有 disabled
屬性的 input
元素,將它的背景色和邊框色設置爲灰色。給與用戶更好的視覺提示。
.class
與 [class=xxx]
是否等價考慮這個問題,下面兩個選擇器是否等值?
<div class="header">
複製代碼
.header {
color: red;
}
[class~="header"] {
color: blue;
}
複製代碼
上述兩個選擇器,做用徹底一致。然而,若是是下面這種狀況,二者就不同了:
<div id="header">
複製代碼
#header{
color: red;
}
[id="header"] {
color: blue;
}
複製代碼
這裏,ID 選擇器#header
比屬性選擇器[id="header"]
的權重更高,雖然二者可以選擇一樣的元素,可是二者並不徹底等價。
考慮下面三種狀況,是否一致?
[class="header"]{ ... }
[class='header']{ ... }
[class=header]{ ... }
複製代碼
事實上,從 HTML2 開始,不添加引號的寫法就已經獲得支持,因此上述三種寫法都是正確的。
然而,可以不使用引號也是有限制的,再看看下面這種寫法:
a[href=bar] { ... }
a[href^=http://] {... }
複製代碼
第二個選擇器是個無效選擇器,://
不引發來的話會識別錯誤,必須使用引號引發來像這樣a[href^="http://"]
,這裏具體的緣由能夠看看這篇文章:Unquoted attribute value validator。
因此保險起見,建議都加上引號。
編寫」具備語義的HTML」原則是現代、專業前端開發的一個基礎。固然,咱們常常談論到的都是 HTML 語義化。
那麼,CSS 須要語義化嗎?CSS 有語義化嗎?例如上述的例子,使用特定的類名或者 id 選擇器皆可完成。那麼使用屬性選擇器的理由是什麼?
個人理解是,屬性(attribute)自己已經具備必定的語義,表達了元素的某些特徵或者功能,利用屬性選取元素再進行對該屬性值的特定操做,必定程度上也能夠輔助提高代碼的語義化。至少的提高了 CSS 代碼的可讀性。可是 CSS 是否須要語義化這個問題就見仁見智了。
這裏有幾篇文章還涵蓋了不少其餘方面使用,能夠對比觀看:
更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。
好了,本文到此結束,但願對你有幫助 :)
若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。