缘起

这一切由下面两端段代码引发的

第一段

展示效果是第一行内容为蓝色

第二段

第一行文字变成了,绿色。

看解释说::first-line只对行内元素生效。评论里讲把br标签去掉,后半段就变成了蓝色。

那么真实原因应该不是这个,又另外的规则,而且这个效果在不同内核的浏览器上面表现的效果非常一致。所以推测可能对标准理解有偏差。

寻根

原始css标准文档 The ::first-line pseudo-element 。英文能力强的自己再读一读

文档中讲到,::first-line伪元素只对block-like类似容器有效果,且只对first-formatted-line起作用。
其中7.1.1也明确定义了何为first-formatted-line(第一个格式化过的行)。
为什么叫格式化过的,而不是直接叫first-line,这个formatted也就是应用样式后。我的理解是代码里的一行,显示时候因为字多可能显示好几行,也可能是个换行符;然后::first-line伪元素也有样式或导致一行显示多少内容发生变化,所以要以计算样式后的结果为准,取第一行。

文档里面提到了个很重要的一点就是伪元素对应的虚拟结构,比如<DIV::first-line>。

::first-line的”dom结构”

接下来看下面的情况

当::first-line的子元素还是容器时,遵循的是块级元素(block-level element)就近传递
原话是这么说的: ::first-line pseudo-elements were nested just inside the innermost enclosing block-level element
具体参考下面两个例子

案例1,子元素是块级元素,那么传递。

案例2,子元素是行内元素。

有了这个节点结构作支撑,再来思考样式的问题。就非常简单了。

回溯

为什么span标签设置了绿色之后,蓝色就消失了。我们映射下完整的虚拟结构,如下:

对应上面的结构我觉得都不需要再解释那个样式覆盖那个样式了。

另外就是伪元素样式定义里使用!important是没有效果的,具体参考标准的原文:

During CSS inheritance, the portion of a child element that occurs on the first line only inherits properties applicable to the ::first-line pseudo-element from the ::first-line pseudo-element. For all other properties inheritence is from the non-pseudo-element parent of the first line pseudo element. (The portion of a child element that does not occur on the first line always inherits from the parent of that child.)

延展

继续观察其他伪元素::first-letter::section::before::after这些伪元素,其实对应的虚拟结构其实是一样的,因此这个思路可能很好理解各种复杂组合,比如一个节点同时具备::first-line::first-letter::before,会是什么效果自然就可推导出来了。

4.5 4 votes
Article Rating
Subscribe
提醒
guest
0 评论
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x