鉴于以下情况,为什么:after选择器需要内容属性才能运行?
.test {
width: 20px;
height: 20px;
background: blue;
position:relative;
}
.test:after {
width: 20px;
height: 20px;
background: red;
display: block;
position: absolute;
top: 0px;
left: 20px;
}
<div class="test"></div>
注意在指定content属性之前如何看不到伪元素:
.test {
width: 20px;
height: 20px;
background: blue;
position:relative;
}
.test:after {
width: 20px;
height: 20px;
background: red;
display: block;
position: absolute;
top: 0px;
left: 20px;
content:"hi";
}
<div class="test"></div>
为什么这是预期的功能?你会认为显示块会强制元素出现。奇怪的是,您实际上可以在Web调试器中看到样式;但是,它们不会显示在页面上。
答案 0 :(得分:21)
以下是对各种W3C规范和草案的一些参考:
'before'和':after'伪元素可用于在元素内容之前或之后插入生成的内容。
作者使用:before和:after伪元素指定生成内容的样式和位置。正如其名称所示,:before和:after伪元素指定元素文档树内容之前和之后的内容位置。 'content'属性与这些伪元素一起指定插入的内容。
首字母:无
此属性与:before和:after伪元素一起使用,以在文档中生成内容。值具有以下含义:
无 - 未生成伪元素。
应用于:: before和::之后伪元素的样式会影响生成内容的显示。 content
属性是这个生成的内容,如果没有它,则会假定默认值为content: none
,这意味着没有任何内容可以应用于该样式。
如果你不想多次重复content:'';
,你可以简单地通过全局样式化CSS中的所有:: before和:: after伪元素来覆盖它:JSFiddle example)< / p>
::before, ::after {
content:'';
}
答案 1 :(得分:7)
根据您对其他人答案的评论,我相信您的问题实际上是:
为什么必须在CSS中设置伪类的content属性,如 反对非伪类的内容,可以在其中设置 HTML还是CSS?
原因是:
<p>
这样的HTML元素也可以,但您可以使用标记(或与CSS声明)快速设置其内容属性。 采取这个简单的页面:
<body>
<p> </p>
</body>
我们知道此页面不会显示任何内容,因为<p>
元素没有文本。更准确的方法是, <p>
元素的内容属性没有值。
我们可以通过在HTML标记中设置h1元素的content属性来轻松更改此内容:
<body>
<p>This sentence is the content of the p element.</p>
</body>
现在将在加载时显示,因为<p>
元素的content属性具有值;该值是一个字符串:
"This sentence is the content of the p element."
或者,我们可以通过在CSS 中设置<p>
元素的content属性来显示<p>
元素:
p { content: "This sentence is the content of the p element set in the CSS."; }
这两种将字符串注入<p>
元素的方法是相同的。
现在,考虑使用伪类做同样的事情:
HTML:
<body>
<p class="text-placeholder">P</p>
</body>
CSS:
p:before { content: "BEFORE... " ; }
p:after { content: " ...and AFTER"; }
结果:
BEFORE... P ...and AFTER
最后,想象一下如何在没有使用CSS的情况下完成此示例。这是不可能的,因为无法在HTML标记中设置伪类的内容。
你可能很有创意,想象这样的事情可能有用:
<p:before>BEFORE... </p>
<p> P </p>
<p:after> ...and AFTER</p>
但是,它没有,因为<p:before>
和<p:after>
不是HTML元素。
总结:
答案 2 :(得分:5)
您需要为每个content: ''
和/或::before
伪元素::after
声明的原因是因为content
的初始值为normal
,在none
和::before
伪元素上计算::after
。请参阅spec。
content
的初始值不是空字符串,而是为none
和::before
伪元素计算::after
的值的原因,是双重的:
在每个元素的开头和结尾都有空的内联内容是相当愚蠢的。请记住,::before
和::after
伪元素的最初目的是在原始元素的主要内容之前和之后插入生成的内容。如果没有要插入的内容,创建一个仅插入任何内容的附加框是没有意义的。因此,none
值告诉浏览器不要打扰创建一个额外的框。
使用空的::before
和::after
伪元素来创建额外的盒子只是为了布局美学的做法相对较新,有些纯粹主义者甚至可能称之为因此而破解。
在每个元素的开头和结尾都有空的内联内容意味着每个(未替换的)元素 - 包括html
和body
- 默认情况下不会生成一个框,但是最多三个框(如果元素已经生成的不仅仅是主框,那么更多,就像列表样式的元素一样)。您实际使用的每个元素中有多少个额外的盒子?这可能会使布局成本三倍,但收益很少。
实际上,即使在这十年中,页面上只有不到10%的元素需要::before
和::after
伪元素进行布局。
所以这些伪元素是选择加入的 - 因为选择它们不仅浪费系统资源,而且仅仅因为它们的原始目的而显得不合逻辑。性能原因也是我不建议使用::before, ::after
为每个元素生成伪元素的原因。
但是你可能会问:为什么display
上的none
属性默认为::before, ::after
?很简单:因为display
的初始值不是none
;它是inline
。在inline
上none
计算到::before, ::after
不是一个选项,因为那时你永远不能将它们显示为内联。将display
的初始值设为none
不是::before, ::after
,因为属性只能有一个初始值。 (这就是为什么content
的初始值始终为normal
,并且它被简单地定义为在none
上计算为::before, ::after
。)
答案 3 :(得分:3)
在添加content: ...
之前,伪元素实际上不存在。
设置其他样式属性不足以强制浏览器创建元素。
答案 4 :(得分:0)
2020编辑
:before
CSS2的语法是更好的做法,您应该编写CSS3的最新语法,
::before
带有双分号
完整的答案和不同之处可以在这里找到: What is the difference between :before and ::before?