这是我参与更文挑战的第7天,活动详情查看: 更文挑战
关于伪元素选择器的一些小发现
主要参考文章:www.zhangxinxu.com/wordpress/2…
什么是伪元素选择器
简单来讲就是用css定义了一个不存在的元素。
如图,html代码里只有p元素,但是当用css定义了一个伪元素::first-line,就只会对p元素中的第一行起样式作用。
当前存在的伪元素选择器主要有以下几种:
- ::after:在元素之前创建伪元素
- ::before:在元素之后创建伪元素
- ::first-letter:选择元素的首字母
- ::first-line: 选择元素的首行
- ::selection: 选择用户选择的元素部分
生效的前提
-
元素的
display计算值必须是block,inline-block,table-cell,list-item或者table-caption对span使用伪元素选择器是不生效的。
猜想:是不是因为伪元素其实就是生成了一个inline元素?
-
一些特殊字符被认为是辅助字符,如下:
空格也会被认为是辅助字符,他们的表现如下:当设置::first-letter为红色时
辅助字符:
非辅助字符:
也就是说,辅助字符会和第一个字一起变为红色。
-
作用的字符不能display:inline-系列的属性,如inline-block,inline-flex,inline-table,inline-grid。
如果作用的字符属性是display:flex、grid、none。和float等属性,不会直接放弃,会为下一个符合规定的元素应用字符。
-
只对某些css属性生效
- 所有字体相关属性:
font,font-style,font-variant,font-weight,font-size,line-height以及font-family. - 所有背景相关属性:
background-color,background-image,background-position,background-repeat,background-size, 以及background-attachment. - 所有
margin相关属性:margin,margin-top,margin-right,margin-bottom,margin-left. - 所有
padding相关属性:padding,padding-top,padding-right,padding-bottom,padding-left. - 所有border相关属性:缩写的
border,border-style,border-color,border-width及普通书写的属性。 color属性。text-decoration,text-transform,letter-spacing,word-spacing(合适情境下),line-height,float,vertical-align(只有当float为none的时候)这些CSS属性们.
- 所有字体相关属性:
优先级问题
前面的那些东西其实也不会刻意去记哈哈哈,写在那里只是方便要用的时候来看看。下面才是我想说的,我想说如果用了first-letter或first-line而且样式生效的情况下,几乎没有什么能够覆盖它的样式。
如下:
我们给p设置important:
<head>
<style>
/*伪元素*/
p::first-letter {
color: pink;
}
p{
color: #abcdef !important;
}
</style>
</head>
<body>
<p>一行代码</p>
</body>
最后生成的样式是:一行代码
可以看到p上设置的important没生效,是不是不太符合逻辑?按照css2规范,伪元素选择器应该和标签选择器一样优先级属于1,而import是最高优先级。
为啥会这样呢,我们打开控制台,发现伪元素其实是被分离出来的:
所以我们暂时推测:伪元素其实是一个不存在于dom中的元素,是选择器作用的元素的子元素。
子元素是吧,好,我再弄个子元素。我们给p>span元素的color设置important:
<head>
<style>
/*伪元素*/
p::first-letter {
color: pink;
}
p>span{
color: #abcdef !important;
}
</style>
</head>
<body>
<p><span>一</span>行代码</p>
</body>
最后生成的样式是:一为粉红色,其余字体不变色。
既然伪元素是p的子元素,span也是p的子元素,那么为什么不会被span的样式覆盖呢?
如果在span上设置其他样式,效果会怎么样?
span{
font-weight: bolder;
color: #abcdef !important;
}
效果如下:
我们看到字体确实被加粗了(好像不太显眼但是确实起作用了~~),所以伪元素其实继承了span的font属性。可以推测,伪元素其实是作为span的子元素存在的。
再继续嵌套子元素其实也是一样的,他永远都是作为最底层的那个子元素存在,继承所有可继承的属性,所以不管span里面怎么设置important,他都只是优先于在span上设置的属性,而span的子元素会继承span上的所有可继承属性,在此基础上再添加自己的样式。
结论:伪元素选择器之所以覆盖important,不是因为伪元素选择器优先级高,而是因为伪元素是最底层的子元素。