iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 2
5
Modern Web

重新認識 CSS系列 第 2

重新認識 CSS - Simple Selector & Groups of selector

Selector (選擇器) 可用來選擇 HTML 和 XML 文件中的節點,並將樣式屬性綁定到文件 (HTML 和 XML) 中的元素上。當選擇器與某元素 match 的時候,就可以對選到的元素進行 CSS 樣式設定。

前言

「重新認識 CSS」這個系列名稱的由來就如其名,我想要重新認識它。雖然以前就有學過 CSS,但這次想從 CSS Spec 中學到最原始的定義和內容,更加了解 CSS 的原理,讓我在切版的時候可以更加確定自己在做什麼,我踩到的雷只是因為我不夠了解它才會炸開。

在這 30 天的內容中,會將 Spec 內看到的資料整理成這個系列,也希望正在學 CSS 的各位可以更加了解它。另外我也會同時將文章發至我的 Blog,如果想直接看文內的程式碼 Demo 畫面,可以到我的 Blog 來看 。

本文同步發表於 Titangene Blog:重新認識 CSS - Simple Selector & Groups of selector

「重新認識 CSS」系列文章發文於:

Selector 語法

Selector 是由一個或多個 sequence of simple selector (簡單選擇器) 所組合,並用 combinator 分隔的一串東西。

sequence of simple selectors:

  • 由多個 simple selector 組成,沒有被 combinator 分隔
  • 以 type selector 或 universal selector 為開頭

以下這些都是 simple selector:

  • type selector:例如 E
  • universal selector:例如 *
  • attribute selector:例如 E[foo]
  • class selector:例如 .myclass
  • ID selector:例如 #myid
  • pseudo-class:例如 E:hover

combinator 是 空白字元、>+~,例如:

E F { color: red; }
E > F { color: red; }
E + F { color: red; }
E ~ F { color: red; }

simple selector 與 combinator 之間可以加上空白,不加空白也可以。例如:下面兩個選擇器是相同的:

E > F
E>F

不過,通常在之間都會加空白,因為可讀性較佳。

所有 CSS 語法在 ASCII 範圍內都不分大小寫 (也就是 [a-z] 等於 [A-Z] ),但不受 CSS 控制的部分除外。例如:HTML 的 idclass 屬性值、字體名稱和 URI 是否分大小寫都超出 CSS Spec 的定義範圍。另外,HTML 的元素名稱是不分大小寫的,但在 XML 就有分大小寫。

雖然在 CSS 2.2 spec 是說 pseudo-element 和 pseudo-class 的名稱不分大小寫,但通常會使用小寫。

在 CSS 中,identifier (包括 selector 中的元素名稱、class 和 ID) 只能包含字元 [a-zA-Z0-9] 和 ISO 10646 字元中的 U+0080 及之後的字元,以及 hyphen ( - ) 和底線 ( _ );它們不能以數字、兩個 hyphen 或 hyphen 後面接著數字為開頭。

詳情可參閱 CSS 2.2 - 4.1.3. Characters and case

Groups of selector

當多個選擇器共享相同的宣告時,它們可以用逗號來分隔每個選擇器,每個選擇器都會選到 match 的所有元素,例如:

<h1>header 1</h1>
<h2>header 2</h2>
<h3>header 3</h3>
h1 { color: red; }
h2 { color: red; }
h3 { color: red; }

等同於:

h1, h2, h3 { color: red; }

Demo:Codepen 連結

不要要注意的是,上面兩個範例會有一樣的結果是因為所有選擇器都是有效的選擇器 (valid selector)。如果其中一個選擇器為無效時,就會讓整個選擇器群組都無效。不過,若將三個選擇器分開宣告時,就只有那一個會失效。例如:

<h1>header 1</h1>
<h2>header 2</h2>
<h3>header 3</h3>
h1 { color: red; }
h2..foo { color: red; }
h3 { color: red; }

不等於:

h1, h2..foo, h3 { color: red; }

Demo:Codepen 連結

如下圖,因為上面其中的 h2..foo 是無效選擇器 (invalid selector),所以會造成 h1, h2..foo, h3 完全無效,並且會刪除這個樣式規則:

如果是分開宣告,就只會刪除 h2..foo 這個樣式規則,如下圖:

Simple selector

以下這些都是 simple selector:

  • type selector
  • universal selector
  • attribute selector
  • class selector
  • ID selector
  • pseudo-class

Type selector

與 HTML 的 element type 的名稱 (也就是 HTML tag 名稱) match。

例如:match 所有 h1 元素:

<h1>header 1</h1>
h1 { color: red; }

Demo:Codepen 連結

Universal Selector

Universal selector 是使用 * 來 match 任何 element type 的名稱。

例如:下面範例可以選到所有元素:

<h1>header 1</h1>
<h2>header 2</h2>
<h3>header 3</h3>
<a href="https://titangene.github.io/">Titangene Blog</a>
* { color: red; }

Demo:Codepen 連結

Class selector

如果要對多個元素需要相同的樣式時,就可以用 class 這個屬性來標識它們。在 CSS 是使用 . 來代表 class 屬性,也等同於 ~= 表示法 (notation),屬性值必須在 . 之後。例如:

<h1>header 1</h1>
<h1 class="highlight">highlight header 1</h1>
h1.highlight { color: red; }

等同於:

h1[class~=highlight] { color: red; }

Demo:Codepen 連結

第一個 h1 元素的字體顏色不會變成紅色,只有第二個 h1 元素才會變紅色:

如果只單獨使用 class selector (也就是 . ),也等同於在前面加上 universal selector (也就是 * )。例如:

<h1>header 1</h1>
<h1 class="highlight">highlight header 1</h1>
<h2>header 2</h2>
<h2 class="highlight">highlight header 2</h2>
*.highlight { color: red; }
.highlight { color: red; }

Demo:Codepen 連結

第一個 h1h2 元素的字體顏色不會變成紅色,只有第二個 h1h2 元素才會變紅色:

如果需要同時指定某元素上的兩個 class,可以寫成這樣:

<h1>header 1</h1>
<h1 class="text-primary highlight">highlight header 1</h1>
<h2>header 2</h2>
<h2 class="highlight">highlight header 2</h2>
.text-primary.highlight { color: red; }

註:在 HTML 要對某元素上同時設定多個 class,是使用空白字元來分隔多個 class。以上面範例來說,第二個 h1 上有兩個 class,分別是 text-primaryhighlight

Demo:Codepen 連結

ID selector

如果要對某個元素作唯一的標示,就可以用 id 這個屬性來標識它們。在 CSS 是使用 # 來代表 id 屬性,屬性值必須在 # 之後。例如:

<h1>header 1</h1>
<h1 id="titan">header 1</h1>
<h2>header 2</h2>
<h2 id="titan">header 2</h2>
#titan { color: red; }

Demo:Codepen 連結

如果只想選擇帶有 titan 這個 id 的 h2 元素,可以寫成這樣:

h2#titan { color: red; }

Demo:Codepen 連結

Pseudo-class

pseudo-class 會在之後的兩篇中介紹到:

最後

今天介紹一些 simple selector,接下來幾天會接續介紹其他 selector。

資料來源:


上一篇
重新認識 CSS - CSS 簡介
下一篇
重新認識 CSS - Attribute selector (屬性選擇器)
系列文
重新認識 CSS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
mihuartuanr
iT邦新手 4 級 ‧ 2019-10-10 11:25:33

说一下个人的内容:

  1. 简单选择器,是没有任何连接符分隔的选择器(当然,规范中没有说,简单选择器包含伪元素)。
  2. Universal selector 是使用 * 來 match 任何Type Selector
  3. HTML中元素名是大小写不敏感,但,不由CSS控制的部分对大小写敏感。例如,HTML中idclass的值,class="highligt"不能由.Highlight匹配。
看更多先前的回應...收起先前的回應...
Titangene iT邦新手 4 級 ‧ 2019-10-13 12:49:26 檢舉
  1. 你說的 "連接符" 應該是指 "combinator" 嗎?另外,spec 裡面的確沒說簡單選擇器包含偽元素,但我看過 spec 之後是認為簡單選擇器不包含偽元素
  2. "match 任何Type Selector" 是指 "任何元素 type" 嗎?
  3. 感謝補充 : )
  • "連接符" 是指 "combinator" 。
  • spec 裡面在选择器优先级一章,说伪元素的优先级等同于Type Selector,我是在选择器上,将伪元素直接看成Type Selector了。
  • 选择器有类别之分,spec里明确地指出Universal selector match 任何Type Selector。Type Selector是指元素标签名。
Titangene iT邦新手 4 級 ‧ 2019-10-14 22:39:01 檢舉

我將之前留言中的「認為選擇器不包含偽元素」改成「認為簡單選擇器不包含偽元素」,少打了「簡單」兩個字差很多 > < 。

你將偽元素直接看成 type selector 只是因為 specificity 這個原因嗎?還是有其他因素?因為我還是認為兩者有很大的差別。

關於我提問的第二點部份,universal selector 在 CSS 2.2 的定義如下:

The universal selector, written "*", matches the name of any element type.

雖然 universal selector 跟 type selector 都是用來 match element type 的名稱,但 universal selector 應該不是 match 任何 type selector。而「元素標籤名稱」應該是指「element type 的名稱」。

所以我在文中修正成:「Universal selector 是使用 * 來 match 任何 element type 的名稱」,就如同 spec 的原義。

嗯,关于Universal selector描述地更加准确呢。

使用伪元素最终生成的是是匿名元素,又在specificity上与type selector一致。所以,在某些方面理解一致。当然,对此,没有太清晰的概念。

我要留言

立即登入留言