所谓成功就是用自己的方式度过人生。 ——《明朝那些事儿》
从业多年,伪类伪元素用过甚多,但是从未对其做一个整合,犹豫再三决定为之。
如果阅读时间不够,读者可以先mark一下,方便下次查阅,对已经很熟悉的伪类,部分童鞋可以通过目录查看不熟悉的。
一、释义
1. 伪元素
伪元素: 表示的是被选择元素的某个部分,这个部分看起来像一个独立的元素,但是是"假元素",只存在于css中,所以叫"伪"的元素,例如:before和:after
2. 伪类
伪类:表示被选择元素的某种状态,例如:hover
二、伪元素集合:
1. :before/::before
::before创建一个伪元素,其将成为匹配选中的元素的第一个子元素。常通过content属性来为一个元素添加修饰性的内容。此元素默认为行内元素。
示例: 给每一个p元素加入引用标记
p::before {
content: "->";
color: blue;
}
结果:
2. :after/::after
::after用来创建一个伪元素,与before一样,但是它作为已选中元素的最后一个子元素.
示例: 给每一个p元素加入后缀标记
p::before {
content: "->";
color: blue;
}
结果:
3. :first-line/::first-line
::first-line可以设置某(块级元素存在类似文本内容)的第一行的样式。第一行的长度取决于很多因素,包括元素宽度,文档宽度和文本的文字大小。
示例: 将第一行文字标红
<p>中国风的歌曲有增无减 是好是坏问方文山最清楚 从娘子唱到 双截棍东风破到发如雪 一路走来始终如一多样的儿曲风 独爱中国风 我坚持风格我活在我的世界 谁都插不上嘴唱反调</p>
p:: first-line {
color: red;
}
结果:
4. ::placeholder
::placeholder可以选择一个表单元素的占位文本,我们可以用该伪元素设置自定义占位文本的样式.
示例: 设置输入框占位符为红色
<input placeholder="plaeholder">
input::placeholder {
color: red;
font-size: 1.2em;
font-style: italic;
}
结果:
5. ::backdrop
::backdrop是在任何处于全屏模式的元素下的即刻渲染的盒子(并且在所有其他在堆中的层级更低的元素之上)。
示例: backdrop 将视频全屏显示时的背景颜色修改。
<video
controls
src="https://prod-streaming-video-msn-com.akamaized.net/fe13f13c-c2cc-4998-b525-038b23bfa9b5/1a9d30ca-54be-411e-8b09-d72ef4488e05.mp4">
</video>
video {
width: 100vw;
}
video::backdrop {
background-color: green;
}
该伪元素存在兼容性点击展开查看
5. ::selection
::selectionCSS 伪元素应用于文档中被用户高亮的部分(比如使用鼠标或其他选择设备选中的部分)
允许属性:
- color
- background-color
- cursor
- creat-color
- outline
- text-decoration
- text-emphasis-color
- text-shadow
示例:
/* 选中的文本是红色背景,金黄色的字体 */
p::selection {
color: gold;
background-color: red;
}
6. ::slotted(X)
:slotted()用于选定那些被放在 HTML 模板中的元素,关于模板中元素可查看: 使用 templates and slots
示例: 将所有模板中元素加粗
<template id="test-template">
<div>
<slot name="test-slot"></slot>
</div>
</template>
<test-template>
<p slot="test-slot">这是一个slot1</p>
<p slot="test-slot">这是一个slot2</p>
<p slot="test-slot">这是一个slot3</p>
</test-template>
<script>
customElements.define('test-template',
class extends HTMLElement {
constructor() {
super();
let template = document.getElementById('test-template');
let templateContent = template.content;
const shadowRoot = this.attachShadow({
mode: 'open'
});
let style = document.createElement('style');
style.textContent = '::slotted(*) { color: green; font-weight: bold; } ';
shadowRoot.appendChild(style);
shadowRoot.appendChild(templateContent.cloneNode(true));
}
})
</script>
7. ::maker
::marker 选中一个 list item 的 marker box,后者通常含有一个项目符号或者数字。它作用在任何设置了display: list-item的元素或伪元素上, 列如li和summary。
可设置属性:
- 所有字体属性
- color
- text-combine-upright(兼容性差), unicode-bidi 和 direction属性
- content属性
示例: 设置ul下li的前缀样式
<style>
ul li::marker {
color: red;
font-size: 33px;
}
</style>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</body>
8. ::cue
::cue 匹配所选元素中的WebVTT提示。这可以用于在 VTT 轨道的媒体中使用字幕和其他线索
大部分情况下WebVTT是承担文本字幕,所以简而言之,::cue是一般用来设置视频的文本字幕样式,这里不做示例演示。
三、伪类集合
CSS 伪类元素较多,所以这里使用四个点归纳伪类。
- 状态类伪类
- 结构类伪类
- 表单相关伪类
- 其他伪类
意思就是字面意思,解释就是字面解释,也有很多文档换成其他分类,但是笔者感觉这种分类更好搜索记忆
状态类伪类
1. :link 正常的链接 未点击时
2. :hover 悬停时
3. :visited 点击后
4. :active 被激活时
5. :focus 聚焦时
1,2,3,4,5示例:
<style>
/* 未访问的链接 */
a:link {
color: #FF0000;
}
/* 已访问的链接 */
a:visited {
color: #00FF00;
}
/* 鼠标划过链接 */
a:hover {
color: #FF00FF;
}
/* 已选中的链接 */
a:active {
color: #0000FF;
}
</style>
<a href="https://swww.juejin.cn">跳转掘金</a>
结构类伪类
1. :first-child
表示在一组兄弟元素中的第一个元素。
2. :last-child
表示在一组兄弟元素中的最后一个元素
3. :nth-child(n)
表示一组兄弟元素中的第n个元素
4. :nth-last-child(n)
表示一组兄弟元素中的倒数第n个元素
5. :only-child
匹配没有任何兄弟元素的元素
最初定义时,所选元素必须有一个 parent。而从选择器 Level 4 开始,parent 不再是必须的。
1,2,3,4,5示例:使用两组div包裹,方便区分
<style>
p:first-child {
color: red;
}
p:last-child {
color: green;
}
p:nth-child(3) {
color: yellow;
}
p:nth-child(4) {
color: pink;
}
p:nth-last-child(1) {
color: aquamarine;
}
</style>
<div>
<p>div的第一个子元素 p标签</p>
<p>div的第二个子元素 p标签</p>
<p>div的第三个子元素 p标签</p>
<p>div的第四个子元素 p标签</p>
<p>div的第五个子元素 p标签</p>
</div>
6. :first-of-type
表示一组兄弟元素中其类型的第一个元素。
7. :last-of-type
表示一组兄弟元素中其类型的最后一个元素。
8. :only-of-type
表示一组兄弟元素中其类型的只有一个元素。
9. :nth-of-type(n)
表示一组兄弟元素中其类型的第n个元素。
10. :nth-last-of-type(n)
表示一组兄弟元素中其类型的倒数第n个元素。
6,7,8,9,10 示例:
<style>
p:first-of-type {
color: red;
}
p:last-of-type {
color: green;
}
p:only-of-type {
color: yellow;
}
p:nth-of-type(2){
color: skyblue;
}
p:nth-last-of-type(2){
color: pink;
}
</style>
<div>
<p>div的第一个子元素 p标签(first-of-type 选中)</p>
<p>div的第二个子元素 p标签(th-of-type(2)选中)</p>
<p>div的第三个子元素 p标签</p>
<p>div的第四个子元素 p标签(nth-last-of-type(2)选中)</p>
<p>div的第五个子元素 p标签(last-of-type 选中)</p>
</div>
11. :target
代表一个唯一的页面元素 (目标元素),其id 与当前 URL 片段匹配。例如,当前URL为 www.juejin.cn/#selection 的 时候,下面的元素会被:target 选中
<div id="section">juejin<div/>
示例: 将target元素添加前缀
<style>
p:target {
background-color: pink;
}
p:target::before {
content: "->";
color: red;
margin-right: 5px;
}
</style>
<ol>
<li><a href="#selection1">跳转到selection1</a></li>
<li><a href="#selection2">跳转到selection2</a></li>
<li><a href="#selection3">跳转到selection3</a></li>
</ol>
<p id="selection1">这是select1文字</p>
<p id="selection2">这是select2文字</p>
<p id="selection3">这是select3文字</p>
12. :is(selector)
is() 函数将选择器列表作为参数,并选择该列表中任意一个选择器可以选择的元素。
示例:
:is(header, footer, div) p {
font-size: 18px;
color: red;
}
// 以上等价于
header p,
footer p,
div p {
font-size: 18px;
color: red;
}
这里我们在用less scss写css的时候实际是用包裹的写法,这里不做过多的介绍。
13. :where(selector)
:where() CSS 伪类函数接受选择器列表作为它的参数,将会选择所有能被该选择器列表中任何一条规则选中的元素。 where() 和 is() 不同的地方是,:where() 的优先级为0, 而is() 的优先级是由它的选择器列表中优先级最高的选择器决定, 同样该伪类函数在IE浏览器上不支持。
14. :not(selector)
:not() 用来匹配不符合一组选择器的元素。由于它的作用是防止特定的元素被选中,它也被称为反选伪类
示例: 选择文档中所有不是class为name的元素
:not(.name) {
color: yellow;
}
注意:
- not(selector)中选择器不能被嵌套,就是selector不能再写一层not等
- not(selector) 选择器不能为伪类
- not(selector)可以提高优先级,列如 #select 和 #select:not(#name)两个实际选择相同元素,但是后面的优先级较大.
- not(selector) 会匹配所有不是selector的元素,其中包括html 和 body
- not(selector) 不支持复杂的选择器,列如 :not(.disabled, .readnoly) 不支持,需要写作 not(.disabled), :not(.readonly)
- not(selector) 不支持选择器级联,列如 :not(a.disabled){} 需要写作 :not(a):not(disabled){}
- 这个选择器只会应用在一个元素上,无法用它来排除所有父元素。比如, body :not(table) a 依旧会应用到表格元素 table 内部的 a标签 上,因为 tr将会被 :not(table) 这部分选择器匹配。简而言之如果嵌套层次较多,那么建议不要用not. 对于强制层级元素,我们可以用例如 :not(article) > p 选择器这种方式.
表单类伪类
1. :checked
它表示任何处于选中状态的radio(<input type="radio"/>),checkbox(<input type="checkbox"/>)或者select元素中option HTML 元素.
示例: 设置选中radio样式
<style>
input:checked+label {
color: red;
}
input[type="radio"]:checked {
box-shadow: 0 0 0 3px orange;
}
</style>
<div>
<input type="radio" name="my-input" id="yes">
<label for="yes">Yes</label>
<input type="radio" name="my-input" id="no">
<label for="no">No</label>
</div>
2. :disabled
表示任何被禁用的元素。如果一个元素不能被激活(如选择、点击或接受文本输入)或获取焦点,则该元素处于被禁用状态。
示例: 设置禁用的input样式
<style>
input:disabled {
background-color: #ccc;
}
</style>
<input type="text" disabled>
3. :default
表示一组相关元素中的默认表单元素.
该选择器可以在 <button>, <input type="checkbox">, <input type="radio">, 以及 <option> 上使用。
<style>
input:default {
box-shadow: 0 0 2px 1px coral;
}
input:default+label {
color: coral;
}
</style>
<input type="radio" name="last" id="orange">
<label for="orange">Orange</label>
<input type="radio" name="last" id="apple">
<label for="apple">Apple</label>
<input type="radio" name="last" id="tangerine" checked>
<label for="tangerine">Tangerine</label>
<input type="radio" name="last" id="grapefruit">
<label for="grapefruit">Grapefruit</label>
4. :enabled
表示任何被启用的(enabled)元素。如果一个元素能够被激活(如选择、点击或接受文本输入),或者能够获取焦点,则该元素是启用的。它与 :disabled 是相对应的。
在元素未被禁用的情况下,默认就为启用,这里与:disabled相对应
5. :focus
表示获得焦点的元素(如表单输入)。当表单元素得到焦点的时候它会被触发。
示例: 设置input 得到焦点的样式
<style>
input:focus {
background-color: red;
color: green;
}
</style>
<input type="text" value="最伟大的专辑">
6. :focus-within
表示一个元素获得焦点,或,该元素的后代元素获得焦点。换句话说,元素自身或者它的某个后代获得焦点的时候都会触发 :focus-within。
示例: 当表单某个元素获得焦点,表单改变颜色
<style>
form:focus-within {
background: #ff8;
color: black;
}
</style>
<form>
<label for="choiceQuestion">选择题</label>
<input id="choiceQuestion" type="text">
<br>
<label for=" gapFilling">填空题</label>
<input id="gapFilling" type="text">
</form>
7. :indeterminate
表示状态不确定的表单元素:
不确定表单如下情况有:
- <input type="checkbox"> 元素,其 indeterminate 属性被 JavaScript设置为 true 。
- <input type="radio"> 元素,表单中拥有相同 name值的所有单选按钮都未被选中时。
- 处于不确定状态的 <progress> 元素
示例: 设置不确定input样式
<style>
:indeterminate,
:indeterminate+label {
background: skyblue;
}
</style>
<input type="checkbox" id="checkbox">
<label for="checkbox">不确定的时候显示天空蓝背景</label>
<script>
const checkbox = document.querySelector("#checkbox");
checkbox.indeterminate = true;
</script>
8. :in-range
代表一个 <input> 元素,其当前值处于属性min 和max 限定的范围之内。
9. :out-of-range
代表一个 <input> 元素,其当前值处于属性min 和max 限定的范围之外。
8,9 示例:
<style>
input {
width: 100px;
}
input:in-range {
background-color: rgba(0, 255, 0, 0.25);
}
input:out-of-range {
background-color: rgba(255, 0, 0, 0.25);
}
</style>
<input id="value1" name="value1" type="number" placeholder="输入1-10" min="1" max="10" value="12">
10. :invalid
表示任意内容未通过验证的 <input> 或其他 <form> 元素 .
11. :valid
表示任意内容通过验证的 <input> 或其他 <form> 元素 .
10,11 示例
<style>
input {
width: 100px;
}
input:valid {
background-color: rgba(0, 255, 0, 0.25);
}
input:invalid {
background-color: rgba(255, 0, 0, 0.25);
}
</style>
<input type="url">
12. :optional
表示任意没有required属性的 <input>,<select> 或 <textarea> 元素使用它。
13. :required
表示设置了required属性的 <input>,<select> 或 <textarea> 元素使用它。
12, 13示例:
<style>
input {
width: 100px;
}
input:required {
background-color: skyblue;
}
input:optional {
background-color: green;
}
</style>
<input type="text" required >
<br>
<input type="text" >
14. :read-only
表示元素不可被用户编辑的状态(如锁定的文本输入框)。
15. :read-write
代表一个元素(例如可输入文本的 input 元素)可以被用户编辑。
14,15 示例:
<style>
input {
width: 100px;
}
input:read-only {
background-color: skyblue;
}
input:read-write {
background-color: green;
}
</style>
<input type="text" value="readonly" readonly >
<br>
<input type="text" value="read-write" >
其他伪类
1. :root
这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说,:root 表示 <html> 元素,除了优先级更高之外,与 html 选择器相同 这里建议使用html选择器
2. :fullscreen
:fullscreen 应用于当前处于全屏显示模式的元素。 它不仅仅选择顶级元素,还包括所有已显示的栈内元素。 该伪类为实验中功能,存在较多兼容性问题,暂时不建议使用
3. :dir()
伪类匹配特定文字书写方向的元素。在 HTML 中,文字方向由dir属性决定。其他的文档类型可能有其他定义文字方向的方法。 该伪类为实验中功能,存在较多兼容性问题,暂时不建议使用
4. :lang(<language-code> )
基于元素语言来匹配页面元素
示例: 设置如果文档为英文增加outline
<style>
*:lang(en-US) {
outline: 2px solid deeppink;
}
</style>
<p lang="en-US">
If you miss the train I'm on
<br>
You will know that I am gone
<br>
You can hear the whistle blow a hundred miles
<br>
A hundred miles a hundred miles
<br>
A hundred miles a hundred miles
</p>
<p lang="cn-Zh">
若你与我的列车交错
<br>
你会知晓我已远走他乡
</p>
5. :empty
代表没有子元素的元素。子元素只可以是元素节点或文本(包括空格)。注释或处理指令都不会产生影响。
<style>
div{
width: 100px;
height: 100px;
background-color: blue;
font-size: 20px;
color: wheat;
display: flex;
align-items: center;
justify-content: center;
}
div:empty {
background-color: skyblue;
}
</style>
<div>1</div>
<div></div>
6. :host
CSS 伪类选择包含其内部使用的 CSS 的 shadow DOM 的根元素,句话说,这允许你从其 shadow DOM 中选择一个自定义元素。
<template id="test-template">
<div>
中国风的歌曲有增无减
</div>
</template>
<test-template>
</test-template>
<script>
customElements.define('test-template',
class extends HTMLElement {
constructor() {
super();
let template = document.getElementById('test-template');
let templateContent = template.content;
const shadowRoot = this.attachShadow({
mode: 'open'
});
let style = document.createElement('style');
style.textContent = ':host {font-size: 20px; font-weight: bold;} ';
shadowRoot.appendChild(style);
shadowRoot.appendChild(templateContent.cloneNode(true));
}
})
</script>
7. :defined
表示任何已定义的元素。这包括任何浏览器内置的标准元素以及已成功定义的自定义元素. (例如通过 CustomElementRegistry.define() 方法)。
示例: 设置默认标签和 定义的自定义元素字体大小
<style>
:defined {
font-size: 20px;
font-weight: bold;
}
</style>
<template id="test-template">
<div>
中国风的歌曲有增无减
</div>
</template>
<test-template>
</test-template>
<p>这世间已经因为她甜的过头</p>
<script>
customElements.define('test-template',
class extends HTMLElement {
constructor() {
super();
let template = document.getElementById('test-template');
let templateContent = template.content;
const shadowRoot = this.attachShadow({
mode: 'open'
});
let style = document.createElement('style');
style.textContent = ' ';
shadowRoot.appendChild(style);
shadowRoot.appendChild(templateContent.cloneNode(true));
}
})
</script>
8. :left
需要和@规则 @page 配套使用,对打印文档的左侧页设置 CSS 样式
9. :right
CSS 伪类必须与@规则 @page 一起配套使用,表示打印文档的所有右页。
这里的“左” 或 “右” 不是固定的,取决与文档的写作方向。如果第一页主要文字方向是从左到右的,那么它就是:right右页,反之它就是:left左页。
10. :first
打印文档的时候,第一页的样式。
8, 9, 10 示例
/* 设置打印时的左侧文档样式 */
@page :left {
margin: 2px 3px;
}
/* 当打印时会选择所有文档右页 */
@page :right {
margin: 2px 3px;
}
/*设置打印文档第一页的样式*/
@page :first {
margin-left: 50%;
margin-top: 50%;
}
参考文档
小结一下
大体归纳下来,迄今为止可以用而不用考虑兼容性的伪元素和伪类大体如上。在特殊的场景使用我们所知道的知识去处理特殊的需求会有事半功倍的效果。
写作不易,如果有帮助请动动小手点赞♥收藏哈,感谢诸君。