偽元素讓你在不碰 HTML 的前提下插入內容、選取特定部分,或者做純裝飾性的事。下面從最常用的 ::before/::after 開始,到幾個容易忽略的偽元素,逐一說明。

什麼是偽元素?

偽元素讓你在文件中插入內容或選取特定部分,不需要修改 HTML 結構。語法是雙冒號 ::(基於向後相容,部分偽元素也接受舊的單冒號 : 寫法)。

CSS 偽元素列表

以下是常見的 CSS 偽元素:

  1. ::before - 在元素內容之前插入生成內容
  2. ::after - 在元素內容之後插入生成內容
  3. ::first-line - 選取元素的第一行
  4. ::first-letter - 選取元素的第一個字母
  5. ::selection - 選取使用者反白的部分
  6. ::placeholder - 選取輸入框的預設提示文字
  7. ::marker - 選取列表項目的標記(點或數字)
  8. ::backdrop - 全螢幕元素底下的背景層

較少使用但在特定情況下很有用的偽元素:

  1. ::cue - 用於 WebVTT 字幕
  2. ::slotted() - 用於 Web Components 中的投影內容

::before 和 ::after 詳解

::before::after 是最常用的兩個偽元素,讓你在元素內容的前後插入生成的內容。

基本語法

1
2
3
4
5
6
7
selector::before {
content: "你想插入的內容";
}

selector::after {
content: "你想插入的內容";
}

注意: content 屬性是必須的,即使它的值是空字串。

常見用途

裝飾性元素

不需要多一個 <span> 來放引號或底線裝飾:

1
2
3
4
5
6
7
blockquote::before {
content: '"';
font-size: 3em;
color: #ccc;
line-height: 0;
vertical-align: -0.4em;
}

clearfix

最常見的用法之一,解決浮動容器高度塌陷:

1
2
3
4
5
.clearfix::after {
content: "";
display: block;
clear: both;
}

計數器

搭配 counter-increment 做自動編號,不用靠 JS 或手寫數字:

1
2
3
4
5
6
7
8
9
10
ol {
counter-reset: item;
list-style: none;
}

li::before {
counter-increment: item;
content: counter(item) ". ";
font-weight: bold;
}

工具提示

data-* 屬性搭配 attr() 動態帶入提示文字:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
background: #333;
color: #fff;
padding: 4px 8px;
border-radius: 4px;
font-size: 0.875em;
white-space: nowrap;
top: calc(100% + 4px);
left: 50%;
transform: translateX(-50%);
opacity: 0;
pointer-events: none;
transition: opacity 0.2s;
}

[data-tooltip]:hover::after {
opacity: 1;
}

其他偽元素的使用

::first-line 和 ::first-letter

這兩個偽元素常用於排版設計,特別是文章或段落的開頭。

1
2
3
4
5
6
7
8
9
p::first-line {
font-weight: bold;
}

p::first-letter {
font-size: 2em;
float: left;
margin-right: 5px;
}

::selection

自定義使用者選取文字時的樣式。

1
2
3
4
::selection {
background-color: #ffb7b7;
color: #000;
}

::placeholder

自定義輸入框的預設文字樣式。

1
2
3
4
input::placeholder {
color: #999;
font-style: italic;
}

::marker

自定義列表項目的標記樣式。

1
2
3
4
li::marker {
color: #1a73e8;
font-size: 1.2em;
}

::backdrop

當元素處於全螢幕模式時,為其底下的背景添加樣式。

1
2
3
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}

使用上的限制

  1. ::before::after 預設是行內元素(display: inline),需要 width/height 時記得改成 blockflex
  2. 偽元素不存在於 DOM 裡,JS 無法直接取得或操作。
  3. imginputtype="text" 等)等替換元素不支援 ::before::after,因為這類元素的內容由外部資源決定。
  4. 不是所有偽元素都能套在所有元素上,使用前確認相容性。

偽元素的覆蓋範圍比多數人意識到的廣,::before/::after 只是入口,::marker::placeholder 這類專屬偽元素往往能省掉一層多餘的包裝元素。