iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 9
14
Modern Web

金魚都能懂的 CSS 選取器 - 金魚都能懂了你還怕學不會嗎系列 第 9

CSS 屬性選取器 - 一個選取自由度超高的選取器

  • 分享至 

  • xImage
  •  

本系列文章已集結成書,並於書中添加一些新篇章及細節補充,有興趣的朋友可至天瓏書局選購,感謝各位支持
購書連結 https://www.tenlong.com.tw/products/9789864344994?list_name=b-r30-zh_tw
讓我們好好善用CSS選取器吧


CSS 屬性選取器,一個變化自由的選取器!在早期的時候CSS屬性選取器曾經是被詬病為效能不佳的一種選取器,時至今日拜電腦效能強大及瀏覽器的進步與優化來說,已不太見到有人這樣說了,且對於一個資料有可能變動的畫面來說,適當的使用 CSS 屬性選取器是可以讓我們省下不少的工作跟設定啊。而光是 CSS 屬性選取器就總共有七種選取方式,這不學就太對不起自己了。

CSS 屬性選取器的規則

前面提過 CSS 屬性選取器總共有五種選取方式,正確一點來說應該是七種選取規則,以下依序我們來看看

1. 選取【擁有特定屬性】的物件

這個屬性的寫法是 [HTML屬性] ,作用是只要你的 HTML 物件內,擁有這個屬性的物件都會被選取到,例如以下 HTML

<img src="..." alt="Amos是帥哥">
<img src="..." alt="Alvee正妹我老婆">
<img src="...">

上面這段 HTML 中有多張圖片,為了增加 SEO 的分數,所以正常來說我們都會將圖片加上 alt 屬性好讓爬蟲知道我的圖片是甚麼圖片,但是有時候小編啊你知道的,就是很忙啊,總是會漏掉或是甚麼的,這時候我們就可以利用下方這種 CSS 寫法來讓這張沒有 alt 屬性值的呈現特殊的外觀

img { border: 10px solid red; }
img[alt] { border:none; }

上面這樣的寫法會讓所有圖片被加上一個10像素的紅色邊框,但是具有 alt 屬性的圖片則不會有邊框,當然我們也會有別種更直覺的寫法,容 Amos 暫時不岔開話題,待後面再來介紹。所以這邊我們其實就可以知道這個 CSS 屬性選取器的作用就是選取到『擁有特定 HTML 屬性』的物件就會被選取到,當你有這樣的需求的時候就可以好好利用它了。

2. 選取屬性值【完全等於】特定文字的物件

由第一個屬性選取方式可以知道我們可以利用『有沒有這個屬性』來當作判斷規則,好達到我們要選取到特定物件的目的,當然就可以想到說『如果我想選到特定值』的物件有辦法達到嗎? 既然你都誠心的發問了,那我就大發慈悲的告訴你,我是金魚...(被打!) ,對不起,突然寶可夢模式上身了,回題! 這答案鐵定是可行的! 這個屬性的寫法是 [屬性=值] ,讓我們來看看下方範例 HTML 原始碼

<img src="..." alt="Amos是帥哥">
<img src="..." alt="子瑜我婆">
<img src="..." alt="新竹金城武">

這邊可以看到 HTML 結構中,竟然有人敢跟我搶子瑜,那我鐵定要讓你消失的啊! (握拳) 所以我就可以這樣寫我的 CSS

img[alt="子瑜我婆"] { display:none; }

哈哈哈!!! 被消失了吧你!!! 看你還敢不敢在我面前放肆! (突然感受到背後老婆的嚴厲目光),上面這種寫法可以讓我們選取到特定的物件,但前題是如果你的 alt 屬性值中只要有一個不一樣的內容就選不到了,所以只要對方寫成這樣 <img src="..." alt="子瑜是我婆">我就選不到了,除非我再次改變我屬性選取器內中方括號的內容,這可真是不好用啊! 沒關係我還有別招,就讓我們繼續看下去。

3. 選取屬性值【開頭等於】特定文字的物件

這個屬性的寫法是 [屬性^=值],作用就是當我 HTML 中有特定開頭的文字(字串)的時候,我就可以利用這個選取器來做選取,所以我就直接用『子瑜』來當作我的選取目標好了,於是把剛剛的 CSS 選取器改寫成下方這樣看看

img[alt^="子瑜"] { display: none; }

這樣就可以選到所有圖片 alt 屬性中含有『子瑜』這個文字的圖片,並且讓它消失不見了,你看看多麼的厲害啊!! 連正常的圖片中只要含有『子瑜』兩個字的話都會被消失呢! 咦??? 不對啊,這樣全部的『子瑜』都不見了啊啊啊啊啊啊! (正宮老婆表示對這個選取器很滿意)

4.選取屬性值【結尾等於】特定文字

好吧! 雖然『子瑜』被消失了,但還是要打起精神來繼續看下一個選取器,這個 CSS 選取器屬性的寫法是 [屬性$=值] ,作用是選取 HTML 屬性值的結尾等於特定文字(字串)的物件,這個選取器真是特好用了! 縱使你不管子瑜的照片(還在講!),也可以用到一般正常的網頁設計中,讓我們看下方這個下載區的 HTML 例子

<h2>資源下載</h2>
<div class="download-list">
	<a href="CSScoke-logo.png">CSScoke Logo</a>
	<a href="CSScoke.pdf">CSScoke文章精選輯</a>
	<a href="CSScoke.psd">Amos 的照片</a>
	<a href="CSScoke.docx">Amos 的簡歷</a>
</div>

上面是一個網頁中檔案下載區的例子,因為每個檔案的類型不同,所以設計師希望在不同檔案類型的前面加上該檔案類型的圖示,方便使用者一眼就可以辨識這個連結會下載甚麼樣的檔案,所以我就可以用下面這種 CSS 寫法

a[href$=".png"] { background-image: url("icon-png.png"); }
a[href$=".pdf"] { background-image: url("icon-pdf.png"); }
a[href$=".psd"] { background-image: url("icon-psd.png"); }
a[href$=".docx"] { background-image: url("icon-docx.png"); }
a[href$=".doc"] { background-image: url("icon-docx.png"); }

這樣我就不需要寫程式去判斷我的檔案是哪種然後套用特定 CSS class 了,真是超級的方便啊啊啊!

文字大小寫有別

甚麼! 為何我沒選到我的目標? 注意檢查看看你是否選取器內的英文字母大小寫不同呢? 在 CSS 的世界中,大小寫是有區別的,所以你只要大小寫不同就會選不到,加上目前比較麻煩的一點是 ms office 新舊版本的副檔名不同的問題,我們可能針對 office 的檔案就必須要改成這樣設定 CSS

a[href$=".docx"] { background-image: url("icon-docx.png"); }
a[href$=".DOCX"] { background-image: url("icon-docx.png"); }
a[href$=".Docx"] { background-image: url("icon-docx.png"); }
a[href$=".dOcx"] { background-image: url("icon-docx.png"); }
a[href$=".doCx"] { background-image: url("icon-docx.png"); }
a[href$=".DOcx"] { background-image: url("icon-docx.png"); }
a[href$=".DOcX"] { background-image: url("icon-docx.png"); }
a[href$=".dOCX"] { background-image: url("icon-docx.png"); }
a[href$=".DocX"] { background-image: url("icon-docx.png"); }
a[href$=".dOcX"] { background-image: url("icon-docx.png"); }
a[href$=".doCX"] { background-image: url("icon-docx.png"); }
.
.
.
夠了!!!!! 快停手!!! 不然我要打人了

看到了吧,這些排列組合就夠你受了,當然你會說有誰會寫出這種白癡副檔名? ㄜ.......我只能說年輕人終究是年輕人,沒打過怪才會這樣說,通常遇到這種狀況在之前我會只寫兩組設定,就是全大寫跟全小寫,至於那些混種大小寫的副檔名,只能花時間教育一下客戶了,這應該是不難的啦,於是....我們的 CSS 就會變成這樣

a[href$=".png"] { background-image: url("icon-png.png"); }
a[href$=".pdf"] { background-image: url("icon-pdf.png"); }
a[href$=".psd"] { background-image: url("icon-psd.png"); }
a[href$=".docx"] { background-image: url("icon-docx.png"); }
a[href$=".doc"] { background-image: url("icon-docx.png"); }

a[href$=".PNG"] { background-image: url("icon-png.png"); }
a[href$=".PDF"] { background-image: url("icon-pdf.png"); }
a[href$=".PSD"] { background-image: url("icon-psd.png"); }
a[href$=".DOCX"] { background-image: url("icon-docx.png"); }
a[href$=".DOC"] { background-image: url("icon-docx.png"); }

兩倍大小的原始碼,讓我們利用 CSS 選取器的群組式宣告 整理一下 CSS 吧

a[href$=".png"], a[href$=".PNG"] { background-image: url("icon-png.png"); }
a[href$=".pdf"], a[href$=".PDF"] { background-image: url("icon-pdf.png"); }
a[href$=".psd"], a[href$=".PSD"] { background-image: url("icon-psd.png"); }
a[href$=".docx"], a[href$=".DOCX"] { background-image: url("icon-docx.png"); }
a[href$=".doc"], a[href$=".DOC"] { background-image: url("icon-docx.png"); }

看起來OK了,但這一段寫那麼多當然不是為了充版面,知道這寫選取器的麻煩問題後,讓我們來學終極的用法,在選取器中多加一個 i 讓你的選取器直接不分大小寫都能選到,CSS 像下面這樣

a[href$=".png" i] { background-image: url("icon-png.png"); }
a[href$=".pdf" i] { background-image: url("icon-pdf.png"); }
a[href$=".psd" i] { background-image: url("icon-psd.png"); }
a[href$=".docx" i] { background-image: url("icon-docx.png"); }
a[href$=".doc" i] { background-image: url("icon-docx.png"); }

真是太完美的解決方案啦(歡呼)~~~

5. 選取屬性值中【包含特定文字】的物件

這個屬性的寫法是 [屬性*=值] ,剛剛在第2個屬性選取器的時候有提到每次都要變更我寫的值,這樣實在非常的不便利啊,能不能讓我抓到『只要值裡面有特定文字』就好了? 既然你都誠心的發問了,那我就大發慈悲的告訴你,我是金魚他爸...(被連續擊打!) ,同一個梗玩太多次了對不起(跪),這個選取器可以選取到『只要值裡面有指定的特定文字』,這真是非常方便,所以這樣我們就可以設定下方這樣的條件讓那些『子瑜我婆』的人消失,又不會影響到『子瑜』這個關鍵字
HTML

<img src="..." alt="Amos是帥哥">
<img src="..." alt="子瑜我婆">
<img src="..." alt="新竹金城武">

CSS

img[alt*="子瑜"][alt*="我婆"] { display: none; }

注意上面這寫法的意思是『圖片的 alt 屬性值中必須同時包含有子瑜以及我婆』這樣的關鍵字,就會被消失,如果覺得寫法不是很能夠理解的話,我們可以複習一下 [CSS 選取器的組合式宣告] ,當你的選取器中沒有空格且該物件同時具備選取器所設定的條件時就會被選取,很單純且簡單對吧! 不管如何子瑜總算是回來了(顯示已被老婆打暈狀態...)

6. 選取屬性值中【包含特定單字】的物件

這個屬性的寫法是 [屬性~=值] ,作用的方式是『只要屬性值中有指定的單字』,這句話中最重要的就是單字 而不是 字串,針對中文語系國家來說,這個選取器的效果可能不容易測試出來,但是對於外語來說就會非常明顯了,以英文為例子來說,英文的文章是以英文字母組成『單字』,接著再由一堆的『單字』組合成『文章』,而單字與單字之間是以空格作為區隔,就像下方這樣的 HTML

Amos is a handsome live broadcaster

其中每個單字都用空格作為區隔,讓你可以看懂每個『英文單字』是甚麼。如果轉換成我們的網頁內容 HTML 可能會是這樣

<img src="..." alt="Amos is a handsome live broadcaster">
<img src="..." alt="Alvee">
<img src="..." alt="Amos is Youtuber">
<img src="..." alt="AmosIsYoutuber">

如果我們要選取到 alt 中有『Amos』這個『文字』的圖片的話,就這樣寫 CSS

img[alt*="Amos"] { ...略 }

上面會被選取到的圖片是 1、3、 4 總共三張圖片

如果我們要選取到 alt 中有『Amos』這個『單字』的圖片的話,則必須要這樣寫 CSS

img[alt~="Amos"] { ...略 }

這樣被選取到的就必須是一個『單字』,所以被選取到的圖片就會是 1、3 兩張圖片,這樣應該就很清楚何謂『單字』的意思了吧。

7. 選取屬性值【開頭等於特定文字或包括 - 號】的物件

這個屬性的寫法是 [屬性|=值] ,這個選取器看起來它的作用跟 [屬性^=值] 選取器的作用很像,同樣都是從前面開始選取,但是更特別的是這個選取器可以選到文字後面帶有連接號(-)的物件,這個屬性選取器 Amos 目前使用到的機會不多,但倘若搭配語言屬性來使用的話,應該是滿方便的啦,就看各位有沒有機會遇到了。

實際應用

除了上面 Amos 所舉的例子外,其實在實務應用時 Amos 沒有特定使用的地方,純粹都是看特性適合哪個需求來使用,多舉個例子的話就像是 [屬性^=值] 這個選取器好了,如果我今天網站中的超連結有區分內部連結跟外部連結的話,我希望頁面能夠自動判斷外部連結,並對外部連結添加粗體的話,我們可以這樣設定 CSS

a[href] { font-weight: bold; }
a[href^="https://csscoke.com"] { font-weight: normal; }

當然上面這寫法是先將所有超連結都設定為粗體後,再利用選取器將特定網址的超連結設定為一般粗細字體,頗有脫褲子放屁的感覺,或許你覺得更簡單一點應該是思考『如果連結網址中不是 http://csscoke.com的都要被選到』,那麼使用下面這種寫法更直接一點

a:not([href^="https://csscoke.com"])  { font-weight: bold; }

除了上述實務案例外,如果你的網頁超連結是另外開新視窗的,那就給他添加一個圖示好了,這樣的話你就可以這樣寫

a[target="_blank"] { background: url("icon-png.png") no-repeat right center; }

好囉~ 看完上面這一大串之後,是不是發現屬性選取器真的是非常有趣的一個選取器呢? 而且有子瑜的陪伴學習,精神是不是更加的越發昂揚呢

好了好了,成功的男人背後都有一位強大的女人,我背後那位女人在呼喚我了(我老婆說我再不過去跪算盤就死定了),以上就是今天的 金魚都能懂的 CSS 選取器 - CSS 屬性選取器 - 一個選取自由度超高的選取器,如果文中描述有誤歡迎各位前輩不吝指正,各位金魚我們明天見~

金魚都能懂的教學系列

鐵人雙主題挑戰中,歡迎訂閱一波

金魚都能懂的這個網頁畫面怎麼切

立刻訂閱 CSS可樂的網站/頻道享受精彩文章

Line搜尋「@CSScoke」加入CSS可樂公開帳號,可以收到 Amos 第一手資訊喔
CSS 可樂部落格
CSS coke 的 Youtube 直播頻道
快按此訂閱 CSS coke 的頻道接收最新教學
/images/emoticon/emoticon12.gif


上一篇
CSS 通用選取器 - 一個你我都該熟知的老朋友
下一篇
親代選取器之妹妹選取器與鞭炮串選取器
系列文
金魚都能懂的 CSS 選取器 - 金魚都能懂了你還怕學不會嗎30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
King Tzeng
iT邦新手 3 級 ‧ 2019-09-24 21:58:31

<img src="..." alt="子瑜我婆"> /images/emoticon/emoticon37.gif
師母快來!!!這邊這邊!!!(不要怪我呼叫師母囉!!!/images/emoticon/emoticon31.gif

CSScoke iT邦新手 3 級 ‧ 2019-09-24 23:27:20 檢舉
#King-Tzeng { display: none; }

你已經被消失了/images/emoticon/emoticon01.gif

<div id="King-Tzeng" style="display: block">師母快來RRRR~~~</div> 

佔位哥壓壓壓壓壓!!!(好幼稚XD /images/emoticon/emoticon16.gif

這是一個殺人滅口的故事 /images/emoticon/emoticon04.gif

我要留言

立即登入留言