CSS - 選擇器

選擇器

HTML 負責結構,CSS 則是外觀,它是 HTML 元素的化妝師,負責文件的版型外觀、位置、尺寸、顏色、字體,以及響應式等等。「選擇器」,它是 CSS 世界裡的支柱,就如同人類的脊椎支撐了整個身體,我們必須要選擇到目標,才能對元素進行樣式的設計。然而,CSS 選擇器擁有非常多樣貌,認識各種選擇器才能夠靈活設計樣式。值得一提的是只要符合 CSS 規範的選擇器,在 jQuery 裡,能成為$()加工廠的原料,產生出 jQuery 物件,選擇到匹配的元素集合,同時也能被 JavaScript 的 querySelector()與 querySelectorAll()方法所選擇(與 jQuery 在選擇元素同樣的功能)。

語法

「選擇器」決定所選擇的元素目標,它連結著大括號「{}」,大括號裡面是屬性、屬性值,以冒號「:」分隔屬性與屬性值,屬性值後面以分號「;」結尾。

選擇器 {
屬性: 屬性值;
}

基本選擇器

元素選擇器

以元素名稱作為選擇器,又稱為標籤選擇器。

h1 {
color: red;
background-color: #ff0;
font-size: 30px;
}

群組選擇器

選擇器之間以「,」分隔,可以一次選擇指定的選擇對象。

h1,
span {
color: green;
}

類別選擇器

替選擇器取名稱,前面加「.」。此選擇器具有「重覆使用」或「同中求異」的特性,也是使用率最高的選擇器。

.bg-primary {
background-color: blue;
}

ID 選擇器

替選擇器取名稱,前面加「#」。此選擇器具有「唯一」的特性,通常被當作網頁區塊的名稱或是 JavaScript 快速獲取 DOM 目標的方式,一份文件不能有重複的 ID 名稱。

#content {
width: 500px;
height: 500px;
}

class、ID 的命名必須以字元開頭,數字則不行,之後只允許使用字元、數字、連字 - 符號和底線 _ 符號,且有大小寫之分。可以使用中文命名,就像 JavaScript 變數一樣,但請勿使用這種作法。

通用選擇器

使用 * 作為選擇器,文件裡面任何類型的元素都會被選取。

* {
color: #333;
}

屬性選擇器

指以 HTML 元素屬性作為選擇器,有許多種選擇方式,如下:

/* 以 屬性 + 屬性值 去選擇 */
a[href="http://google.com.tw/"]
{
/* css */
}

/* 選擇 img 元素屬性為 title 的目標 */
img[title] {
/* css */
}

/* 選擇屬性 type='text' 的目標 */
input[type='text'] {
/* css */
}

/* 選擇屬性有 kaifu 單字,根據屬性值中眾多詞中某個詞進行選擇(以空白分隔決定該詞) */
a[class~='kaifu'] {
/* css */
}

/* 選擇 href 的屬性值起始字串為 http:// 的目標 */
a[href^="http://"]
{
/* css */
}

/* 選取 href 的屬性值結尾字串為 .pdf 的對象 */
a[href$='.pdf'] {
/* css */
}

/* 選取 img 所有 src 屬性值裡面包含單字 kaifu 的對象; */
img[src*='kaifu'] {
/* css */
}

/* 選取所有圖片裡面有 figure- 的圖片,例如:figure-01.jpg、figure-02.jpg */
img[src|='figure'] {
/* css */
}

複合選擇器

子代選擇器

選擇器之間以「>」分隔,選擇到兒子,也就是只選擇到下一層(子層),第三層不會被選擇,子代選擇器對於剛學習的人來說,常與後代選擇器搞混。

div > p {
color: #333;
}

後代選擇器

選擇器之間以「半形空白」分隔,可選擇到子孫們,也就是起始選擇目標之後的後代都會被選擇到,是一個使用率很高的選擇器。

div p {
color: #333;
}

同層相鄰選擇器

選擇器之間以「+」分隔,又被稱為兄弟選擇器,指選擇到與自己同一層隔壁的元素(指的是在 HTML 文件下方一個元素的意思)。

h1 + p {
color: #333;
}

同全體選擇器

選擇器之間以「~」分隔,表示選擇到 ~ 之後同層的目標,例如以下表示選擇到 h1 之後同層所有的 p 元素。

h1 ~ p {
color: #333;
}

偽類選擇器

偽類(又稱虛擬類別)(Pseudo-class Selector)本質都與狀態、結構有關,參照到文件的標記結構或是當元素處於某個狀態觸發。偽類有一個需要特別注意的地方:偽類是指向它們本身附屬的元素,沒有任何例外,別誤以為參照的是後代元素。早期「偽類」與「偽元素」都是以單冒號(:)表示,CSS3 開始區分它們,偽類依舊是單冒號(:),偽元素則是雙冒號(::),撰寫這兩種樣式時務必遵守規範。

連結狀態

這種偽類出現的順序是必須遵守的,值得注意的是一般 a:link 很難在網站樣式中出現,通常都會直接以 a 作為選擇器,而不會是 a:link,差別在於前者是選擇到連結時的狀態,後者則是選擇到 a 元素本身自己,這樣的寫法好處就是可以少寫幾個字。

<style>
/* LoVe HAte 順序記法 */
a:link {
}
a:visited {
}
a:hover {
}
a:active {
}
</style>

介面狀態

介面狀態非常多種:

  • 最常被使用的是:checked、:focus。
  • 在做表單驗證時會使用到:valid、:invalid。
  • 表單取值:required、:read-only,表單使用狀態:enable、:disable,應用隨著設計調整即可。

偽類在 CSS 會持續增加,請參照MDN

名稱 說明
:checked 選擇被選取的 radio button 或 checkbox,包含使用者選擇或文件本身的預設選取
:focus 選擇成為焦點的元素,不只有表單,可以為任何元素(使用 html 屬性 tabindex)
:empty 選擇內容為空的元素
:enabled 選擇啟用的使用這介面元素(如表單元素),也就是能夠接受輸入的元素。
:disable 選擇停用的使用這介面元素(如表單元素),也就是無法接受輸入的元素
:required 選擇必須要設定數值的使用者輸入元素
:read-only 選擇無法編輯的使用者輸入元素
:defalut 選擇預設選取的 radio button、checkbox 或 option
:valid 選擇滿足本身資料驗證條件的使用者輸入元素
:invalid 選擇不滿足本身資料驗證條件的使用者輸入元素
:read-write 選擇能夠編輯的使用輸入元素
:in-range 選擇使用者輸入的值介於最小值與最大值的元素
:out-of-range 選擇使用者輸入的值超出最大值與最小值範圍之外的元素
:optional 選擇不一定需要設定數值的使用者輸入元素
:indetermiate 表示不是選取,也不是未選取的 radio button 或 checkbox,這個狀態只能透過 DOM 腳本設定,無法由使用者輸入設定

結構元素

根據結構類型來選擇元素,分為 child 與 type 兩組。

:first-child

選擇第一個子元素,等同 nth-child(1),必須注意,這種選擇方式,第一個子元素必定是要指定的選擇器。以下範例是正確的:

<style>
#child div:first-child {
background: #aaa;
}
</style>
<div id="child">
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
</div>

若是以下範例就不行,當你覺得自己已經選擇到第一個 div 子元素,但不給過,因為選擇的子元素必定要為這裡面真正的第一個子元素。

<style>
#child div:first-child {
background: #aaa;
}
</style>
<div id="child">
<p>Lorem ipsum dolor sit amet.</p>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum dolor sit amet.</div>
</div>

:last-child

選擇最後一個子元素,等同:nth-last-child(1)。

#child div:last-child {
background: #aaa;
}

:nth-child(n)

選擇器的第 n 個兒子,nth-child(),括號還可以放置其他參數,odd 是奇數,even 是偶數。第 n 個兒子必須符合父元素的第 n 個兒子即是該選擇器元素,若第 n 個兒子不是該選擇器元素,則無法成功,child 原理都是如此。

/*
:nth-child(n) 第幾個
:nth-child(3n+1) 從第 1 個開始選,每 3 個元素再選取一次,循環...
:nth-child(3n+3) 這樣寫不好,直接寫 :nth-child(3n)
:nth-child(odd) 選擇奇數的子元素
:nth-child(even) 選擇偶數的子元素
:nth-last-child(index) 跟 nth-child 相反,從另一端開始選擇
:only-child 選擇到的父元素,這父元素只能有唯一子元素,也就是只有他,連其他兄弟都不能有
*/

使用負數的 nth-child 來選擇元素

<style>
li {
color: red;
}

/* 選擇第 1 至第 3 個元素並顯示出來 */
li:nth-child(-n + 3) {
color: blue;
}
</style>

:first-of-type 或 :last-of-type

可以跟 first-child 相呼應,只是 :first-of-type 顧名思義是以類型為主,選擇同類型的第一個元素。而 :last-of-type 則是選擇同類型的最後一個元素。child 適合用在單一類型的元素項目做選擇,如果混雜許多的元素項目,就必須用 type,例如以下的範例:

<style>
/* 選擇 div 同類型的第一個元素 */
#type div:first-of-type {
color: red;
}
/* 選擇 p 同類型的第一個元素 */
#type p:first-of-type {
color: green;
}
</style>
<div id="type">
<div>標題</div>
<p>Lorem ipsum dolor sit amet.</p>
<div>標題</div>
<p>Lorem ipsum dolor sit amet.</p>
<div>標題</div>
<p>Lorem ipsum dolor sit amet.</p>
<div>標題</div>
<p>Lorem ipsum dolor sit amet.</p>
<div>標題</div>
<p>Lorem ipsum dolor sit amet.</p>
</div>

:nth-of-type(n)

一種類型裡的第 n 個,若子元素們有許多種標籤類型,可依據條件選出特定類型的子元素。

/*
:nth-of-type(2n+1) 選擇同類型從第1個開始選,每2個選一次,循環...
:nth-of-type(odd) 選擇同類型奇數的子元素
:nth-of-type(even) 選擇同類型偶數的子元素
:nth-last-of-type(index) 跟 nth-of-type 相反,從另一端開始選擇
:only-of-type 選擇一個父元素,父元素裡面有眾多類型的元素,選擇其中唯一類型且只有他自己一個的元素。
*/

/* 奇數圖片往左,偶數圖片往右 */
img:nth-of-type(odd) {
float: left;
}
img:nth-of-type(even) {
float: right;
}

/* 從第二個開始選取每個 div 類型的目標 */
div:nth-of-type(1n + 2) {
margin-left: 20px;
}

:not 反選選擇器

:not() 選擇器為反轉條件,否定掉:not()括號中的條件,不要它們,其他都要。使用 :not() 時要先將它附掛到元素,接著在括號裡填入一個簡單選擇器,也就是類型選擇器、通用選擇器(*)、屬性選擇器、ID 選擇器或虛擬類別其中之一。

/* 選擇誰:not(排除誰) */
.ha {
color: red;
}

/* 選擇所有 p ,排除 p 裡面有 .ha 的元素 */
p:not(.ha) {
color: blue;
}

/* 選擇所有li,但排除第一個兒子 */
ul li:not(:first-child) {
color: red;
}

/* 選擇 href 開頭為 http://,但排除 http://mysite.com 開頭的對象 */
a[href^="http://"]:not([href^="http://mysite.com"])
{
text-decoration: none;
}

/* 更簡短版 */
a[href^="http://"]:not([href*="mysite.com"])
{
text-decoration: none;
}

/* 選擇沒有勾選 checked 的對象 */
input[type='checkbox']:not(:checked) {
color: red;
}

偽元素(虛擬元素)選擇器

在此不介紹 ::before、::after 這兩個偽元素,它們可以被獨立討論。偽元素(虛擬元素)(Pseudo-element Selector)擴展了元素本體選擇內容的方式,讓本體多了豐富的樣式選擇,但它們目前是很稀少的,除了::selection 與 ::placeholder 是較新的偽元素,它們只能用雙冒號顯示,其餘的可以單冒號、雙冒號,不過,CSS3 已經規範出偽元素必須是雙冒號,請建立習慣,偽元素應該用雙冒號。

  • ::first-letter(第一個字母)
  • ::first-line(第一行)
  • ::selection(選取文字反白)
  • ::placeholder(選取有屬性 placeholder 的元素)

繼承

關於繼承,並不是所有屬性都會被繼承,大部分跟文本有關的屬性會被繼承,
color、font-family、font-size、font-weight、font-variant、font-style、line-height、letter-spacing、text-align、text-indent、white-space、word-spacing 等等…。