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 是由一個或多個 sequence of simple selector (簡單選擇器) 所組合,並用 combinator 分隔的一串東西。
sequence of simple selectors:
以下這些都是 simple selector:
E
*
E[foo]
.myclass
#myid
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 的 id
和 class
屬性值、字體名稱和 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 後面接著數字為開頭。
當多個選擇器共享相同的宣告時,它們可以用逗號來分隔每個選擇器,每個選擇器都會選到 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:
與 HTML 的 element type 的名稱 (也就是 HTML tag 名稱) match。
例如:match 所有 h1
元素:
<h1>header 1</h1>
h1 { color: red; }
Demo:Codepen 連結
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
這個屬性來標識它們。在 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 連結
第一個 h1
和 h2
元素的字體顏色不會變成紅色,只有第二個 h1
和 h2
元素才會變紅色:
如果需要同時指定某元素上的兩個 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-primary
和highlight
。
Demo:Codepen 連結
如果要對某個元素作唯一的標示,就可以用 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 會在之後的兩篇中介紹到:
今天介紹一些 simple selector,接下來幾天會接續介紹其他 selector。
資料來源:
说一下个人的内容:
id
、class
的值,class="highligt"
不能由.Highlight
匹配。我將之前留言中的「認為選擇器不包含偽元素」改成「認為簡單選擇器不包含偽元素」,少打了「簡單」兩個字差很多 > < 。
你將偽元素直接看成 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一致。所以,在某些方面理解一致。当然,对此,没有太清晰的概念。