虚拟元素选择器
所谓的“虚拟元素”也称为“伪元素”,表示不存在于真实的 HTML 元素,可能是“想像的元素”或根据现有元素进行“想像分类”,而“虚拟元素选择器”就是专门针对这些“想像元素或分类”的选择器,例如 ::before、::after、::first-letter、::first-line、::marker 等等,这篇教学会深入介绍这些虚拟元素选择器的用法。
教学影片
搭配教学影片一起阅读,效果会更好!欢迎大家订阅 STEAM 教育学习网的 Youtube 频道。
虚拟元素选择器
虚拟元素选择器开头使用两个冒号“::”,虽然也支援一个冒号,但为了避免和使用一个冒号的“虚拟类别选择器”产生误会,仍强烈建议使用两个冒号 ( 目前支援一个冒号是为了向下相容,但不能保证哪天浏览器就不支援了 )。
使用虚拟元素选择器时,需要注意以下几点:
- 所有的虚拟元素选择器都必须放在选择器的“最末端”。
- 一个选择器里只会出现“一个虚拟元素”。
下方列出常用的虚拟元素选择器 ( 支援度 All 表示主流浏览器都支援 ),:
| 虚拟元素选择器 | 说明 | 支援度 |
|---|---|---|
| ::before、::after | 元素前方或后方的虚拟元素。 | All |
| ::first-letter、::first-line | 元素内容的第一个字或第一行。 | All |
| ::marker | 清单标记图示。 | IE 不支援 |
| ::selection | 选取的文字。 | 部分浏览器不支援 |
| ::placeholder | 未输入内容时的显示文字。 | All |
| ::file-selector-button | 打开文件的按钮。 | All |
| ::spelling-error | 英文拼字错误。 | 部分浏览器不支援 |
::before、::after
“::before”和“::after”表示“元素前方或后方的想像元素”,是使用频率非常高的虚拟元素,只要搭配主元素使用,就会自动在元素的前方或后方添加一个 display 为“inline”的虚拟元素,此外,这两个虚拟元素必须搭配“content”样式属性来呈现内容。
下方的范例执行后,会在所有的元素前方加上红色的“123”,以及在后方加上绿色的“456”。
<!-- HTML 程式碼 -->
<h2>oxxo</h2>
<h3>hello world</h3>
<div>我是 DIV</div>
<ul>
<li>oxxo</li>
<li>apple</li>
<li>banana</li>
<li>orange</li>
</ul>
<!-- CSS 程式碼 -->
<style>
body *::before {
content: "123";
color: red;
}
body *::after {
content: "456";
color: green;
}
</style>
::before 和 ::after 的 content 属性除了可以设定内容,也可以使用“attr(屬性)”语法,“读取主要元素的属性”,下方的范例执行后,::before 会读取并显示主元素的 b 属性,::after 会读取并显示主元素的 f 属性,如果没有读到属性也是会产生一个虚拟元素 ( 例如 ul 的 ::after ),但长宽会是 0x0 ( 等同于不可见 )。
<!-- HTML 程式碼 -->
<h2 b="123" f="456">oxxo</h2>
<h3 b="789" f="ABC">hello world</h3>
<div b="DEF" f="GH">我是 DIV</div>
<ul>
<li b="IJK" f="XYZ">oxxo</li>
<li b="QQQ" f="PPP">apple</li>
<li b="123" f="456">banana</li>
<li b="123" f="456">orange</li>
</ul>
<!-- CSS 程式碼 -->
<style>
body *::before {
content: "(" attr(b) ")"; /* 顯示 b 屬性內容,並與括號結合 */
color: red;
}
body *::after {
content: attr(f); /* 顯示 f 屬性內容 */
color: green;
}
</style>
如果使用“url(網址)”语法,也能让 ::before 和 ::after 显示图片,不过需要注意这个方式无法使用正规的方法改变图片尺寸,图片多大就会显示多大。
<!-- HTML 程式碼 -->
<ul>
<li>oxxo</li>
<li>apple</li>
<li>banana</li>
<li>orange</li>
</ul>
<!-- CSS 程式碼 -->
<style>
li::after {
content: url(圖片網址); /* 顯示圖片 */
}
</style>
::before 和 ::after 常与“用户互动”有关,与“:hover”虚拟类别互相搭配的应用更是屡见不鲜,下方的范例除了会读取主元素的 note 属性,更会搭配虚拟类别,当鼠标悬停在 a 元素上方时,就会显示由 ::before 和 ::after 所构成的提示方块 ( 不需要太过深入理解范例程序码,此处主要强调虚拟元素选择器 )。
<!-- HTML 程式碼 -->
<nav>
<a href="#" note="張小彥">oxxo</a>
<a href="#" note="紅蘋果">apple</a>
<a href="#" note="黃香蕉">banana</a>
<a href="#" note="橘橘子">orange</a>
</nav>
<!-- CSS 程式碼 -->
<style>
a {
position:relative; /* 設定 a 的位置屬性 */
}
a::before {
content: attr(note); /* 顯示屬性 */
display:block; /* 改變為 block 顯示類型 */
position:absolute; /* 絕對定位 */
left:0;
top:30px; /* 設定位置 */
width:max-content; /* 使用內容作為寬度 */
padding:3px 5px; /* 設定內邊距 */
color: white; /* 文字白色 */
background: black; /* 背景黑色 */
border-radius:5px; /* 圓角 */
opacity: 0; /* 全透明 */
}
a::after {
content:""; /* 不顯示內容 */
display:block; /* 改變為 block 顯示類型 */
position:absolute; /* 絕對定位 */
left:10px;
top:20px; /* 設定位置 */
width:0;
height:0; /* 寬高設為 0 */
border-width:5px; /* 邊框 5px */
border-color: rgba(0,0,0,0) rgba(0,0,0,0) rgba(0,0,0,1); /* 下邊框黑色,其他都是透明 */
border-style: solid; /* 邊框樣式為實心 */
opacity: 0; /* 全透明 */
}
a:hover::before, a:hover::after {
opacity: 1; /* 滑鼠懸停時改成不透明 */
}
</style>
::first-letter、::first-line
::first-letter 和 ::first-line 会选取内容的“第一个字母”或“第一行”,不过这两个虚拟元素只能使用下列的样式属性:
| ::first-letter 支援属性 | ::first-line支援属性 |
|---|---|
| 所有 font 样式 | 所有 font 样式 |
| 所有 text 样式 | 所有 text 样式 |
| 所有 background 样式 | 所有 background 样式 |
| 所有 border 样式 | 所有 border 样式 |
| color | color |
| box-shadow | margin |
| inline layout | padding |
| opacity | opacity |
打开下方的范例后,第一个字会是 100px 的红色文字,第一行则会是绿色文字,就算缩放屏幕后第一行字数有变动,还是会只有第一行的文字是绿色的。
<!-- HTML 程式碼 -->
<p>
CSS 教學會透過一系列的文章和許多由淺入深的範例,介紹 CSS 的相關知識,從 CSS 的基本概念、選擇器的應用一直到排版佈局、動畫效果都有完整介紹,希望對於網頁初學者、網頁設計師、甚至是網頁前端工程師,提供非常有幫助的知識內容。
</p>
<!-- CSS 程式碼 -->
<style>
p::first-letter {
color: red;
font-size:100px;
}
p::first-line {
color: green;
}
</style>
::marker
::marker 是针对“清单标记图示”的虚拟元素,可以修改使用清单元素时,自动产生的标记图示,使用时需要搭配“content”属性,属性内容可以使用符号、url(圖片) 或 attr(屬性)。
::marker只支援下列的样式属性:所有 font 样式、color、white-space、animation 和 transition。
下方的范例打开后,三组清单分别会将清单标记替换为纯文字符号、属性内容和图片。
<!-- HTML 程式碼 -->
<ul class="a">
<li>oxxo</li>
<li>apple</li>
<li>banana</li>
<li>orange</li>
</ul>
<ul class="b">
<li icon="$">oxxo</li>
<li icon="$">apple</li>
<li icon="$">banana</li>
<li icon="$">orange</li>
</ul>
<ul class="c">
<li>oxxo</li>
<li>apple</li>
<li>banana</li>
<li>orange</li>
</ul>
<!-- CSS 程式碼 -->
<style>
.a li::marker {
content: ">> ";
color: green;
}
.b li::marker {
content: attr(icon) ".";
color: red;
}
.c li::marker {
content: url(圖片網址) " - ";
}
</style>
::selection
::selection 是针对“选取的文字”的虚拟元素,可以修改选取的文字样式,由于是选取的文字样式,样式属性只支援 color、background-color、text-decoration 和 text-shadow 这几种,下方的范例打开后,使用鼠标选择一段文字,这段文字就会呈现红底白字。
<!-- HTML 程式碼 -->
<p>
CSS 教學會透過一系列的文章和許多由淺入深的範例,介紹 CSS 的相關知識,從 CSS 的基本概念、選擇器的應用一直到排版佈局、動畫效果都有完整介紹,希望對於網頁初學者、網頁設計師、甚至是網頁前端工程師,提供非常有幫助的知識內容。
</p>
<!-- CSS 程式碼 -->
<style>
p::selection {
background: red;
color: white;
}
</style>
::placeholder
::placeholder 是针对“未输入内容时的显示文字”的虚拟元素,只会对“输入元素”有作用,下方的范例打开后,有使用 placeholder 属性的输入元素,就会呈现红底白字,开始输入文字后,就会恢复原本的样式。
::placeholder和虚拟类别的:placeholder-shown虽然看起来都是针对“未输入内容时的显示文字”,但::placeholder只针对文字,:placeholder-shown则是该input或textarea元素,延伸阅读::placeholder-shown。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
<input type="text" placeholder="你的 id">
<br>
<input type="text" placeholder="你的姓名">
</form>
<!-- CSS 程式碼 -->
<style>
input::placeholder {
background: red;
color: white;
}
</style>
::file-selector-button
::file-selector-button 是针对“打开文件的按钮”的虚拟元素,只会对“input 的 file 类型”有作用,下方的范例打开后,打开文件的按钮就会变成指定的样式。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
<input type="file" accept=".jpg">
</form>
<!-- CSS 程式碼 -->
<style>
input::file-selector-button {
background: red;
color: white;
padding:10px;
}
</style>
::spelling-error
::spelling-error 是针对“英文拼字错误”的虚拟元素,只会对“有设定 spellcheck="true" 的输入元素”有作用,因为只针对文字,所以只支援 inline 行内元素相关的样式属性,下方的范例打开后,在多行输入字段里输入一些英文,当发生拼字错误时,拼错的字就会出现对应的样式 ( 注意 textarea 有设定 spellcheck="true" 的属性 )。
<!-- HTML 程式碼 -->
<form action="/test.aspx" method="post">
<textarea spellcheck="true" cols="30" rows="10"> </textarea>
</form>
<!-- CSS 程式碼 -->
<style>
::spelling-error {
color: red;
background: pink;
}
</style>
小结
其实 W3C 还定义了许多有趣的虚拟元素,例如 ::backdrop ( dialog 背景 )、::cue ( 影片字幕样式 )、::highlight() ( 文字高光样式 )、::grammar-error ( 文法拼写错误 ) 等等,但可惜目前支援度仍然不高且不太实用,如果未来浏览器陆续支援,或许可以发现其中的奥妙之处吧。
微信扫码关注
抖音扫码关注