我们先来了解一下两者的官方定义,可以见 伪元素和伪类,简单的总结一下就是
CSS
引入伪类和伪元素概念是为了格式化文档树以外的信息,也就是说,伪类和伪元素的作用主要是用来修饰不在文档树中的部分,两者的区别如下
- 伪类用于当已有元素处于的某个状态时,为其添加对应的样式,这个状态是根据用户行为而动态变化的
- 比如说,当用户悬停在指定的元素时,我们可以通过
:hover
来描述这个元素的状态
- 比如说,当用户悬停在指定的元素时,我们可以通过
- 伪元素用于创建一些不在文档树中的元素,并为其添加样式
- 比如说,我们可以通过
:before
来在一个元素前增加一些文本,并为这些文本添加样式 - 虽然用户可以看到这些文本,但是这些文本实际上不在文档树中
- 比如说,我们可以通过
简单的总结就是
- 伪类的操作对象是文档树中已有的元素
- 而伪元素则创建了一个文档数外的元素
两者的区别主要在于有没有创建一个文档树之外的元素,具体可见下图
伪元素是使用单冒号还是双冒号?
CSS3
规范中的要求使用双冒号(::
)表示伪元素,以此来区分伪元素和伪类
- 比如
::before
和::after
等伪元素使用双冒号(::
) :hover
和:active
等伪类使用单冒号(:
)
除了一些低于 IE8
版本的浏览器外,大部分浏览器都支持伪元素的双冒号(::
)表示方法,然而,除了少部分伪元素,如 ::backdrop
必须使用双冒号,大部分伪元素都支持单冒号和双冒号的写法,比如 ::after
,写成 :after
也可以正确运行
那么我们到底应该是使用单冒号还是双冒号呢?我们可以参考 MDN 得知,大概的意思就是,虽然 CSS3
标准要求伪元素使用双冒号的写法,但也依然支持单冒号的写法(为了向后兼容,建议你在目前还是使用单冒号的写法),实际上,伪元素使用单冒号还是双冒号很难说得清谁对谁错,你可以按照个人的喜好来选择某一种写法
下面我们再来看看一些操作伪元素的方式,比如如何获取并修改伪元素的值
获取伪元素的值
这里主要涉及 ::before
和 ::after
,其余几个伪元素(::first-letter
、::first-line
、::selection
等)由于没有 content
属性,所以一笔带过,本质上是一样的,由于 JavaScript
里没有可以直接操作伪元素的选择符,但是我们可以通过获取其 CSS
属性的方法来达到目的,这里可以利用 window.getComputedStyle
方法选择到伪元素,然后利用 getPropertyValue
方法获取对应的属性的值
1 | window.getComputedStyle(element[, pseudoElt]) |
此方法包含两个参数,一个是元素本身另一个是元素的伪元素
1 | var div = document.querySelector('div') |
更改伪元素值
虽然上面的方法可以获取到伪元素的属性值,但是却无法更改,如果使用 JavaScript
来更改伪元素属性值的话,这里主要介绍下面两种方法
更改 data-* 属性值来更改伪元素的 content 值
data-*
是 HTML5
新增的 DOM
元素属性,作用大致可以理解为标记,伪元素的 content
属性值除了常规赋值外,还有一种特殊的 attr()
方法来获取
1 | <div class="test" data-text="AAA" data-color="red"></div> |
1 | .test::before { |
另外 content
其实可以多个 attr
连写,而且 attr()
内的可以是 DOM
元素的任意属性(比如 class
等,甚至非 W3C
标准属性也支持,不过不推荐这么做)
1 | /* 注意用空格连接,不要用 + 号拼接 */ |
需要注意,目前只有
content
属性支持 这个方法
创建多个 class,通过切换 class 来达到改变样式的目的
这个方法的优点是简单好用且无兼容性问题,缺点是多了一些其实用处不大的 class