考虑下面的场景,为什么:后选择需要的内容属性的功能?
.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>
请注意,你怎么不看伪元素,直到您指定的内容属性:
.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>
为什么这是预期的功能? 你可能会认为这显示块将迫使元素展现出来。 奇怪的是,你可以看到网络里面的调试器的样式; 然而,他们不显示在页面上。
这里有各种W3C规范和草案一些参考:
选择3级
在“:前”和“:后”伪元素可以用来插入或前一个元素的内容后生成的内容。
的:before和:after伪元素
作者指定的样式和生成的内容的位置与:before和:伪元素之后。 正如其名称所表明,:before和:after伪元素和前一个元素文档树内容后指定的内容的位置。 的“内容”属性,在与这些伪元素一起,指定了插入。
内容属性
初始值: 无
该属性用于与所述:前和:后伪元素,以产生文档中的内容。 值的含义如下:
无 - 不产生伪元件。
造型施加到::和::后伪元素会影响所生成的内容的显示之前。 在content
属性是这样生成的内容,没有它目前的默认值content: none
假设,这意味着没有任何的样式被应用到。
如果你不想重复content:'';
多次,您可以通过之前和全球所有造型:: ::后你的CSS(中伪元素简单地覆盖这个的jsfiddle例子 ):
::before, ::after {
content:'';
}
基于别人的答案,你的意见,我相信你的问题其实是:
为什么必须为伪类的内容属性在CSS中设置,相对于非伪类的内容,可以在HTML或CSS设置?
其原因在于:
- 根据定义,伪类动态通过网页的HTML标记指定的每一个元素创建
- 所有的页面元素,包括伪类,必须要显示的内容属性。
- HTML元素,如
<p>
做的一样好,但你可以使用标记快速设置其内容属性( 或 CSS声明)。 - Howver, 不像非伪类元素 ,伪类不能在标记本身给定的值。
∴ 因此,所有的伪类是不可见的 (他们的“内容”的属性没有任何价值),除非你告诉他们不要 (给他们用CSS声明值)。
把这个简单的页面:
<body>
<p> </p>
</body>
我们知道这个页面会显示什么,因为<p>
元素没有文本。 重新表述这方面的一个更准确的方法,是使<p>
元素的内容属性没有值 。
我们可以很容易地改变这一点, 通过设置HTML标记 h1元素的内容属性:
<body>
<p>This sentence is the content of the p element.</p>
</body>
加载时这将现在显示的,因为内容属性<p>
元件具有的值; 该值是一个字符串:
"This sentence is the content of the p element."
可替代地,我们可以使<p>
通过设定的内容属性被显示元件<p>
在CSS元件:
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元素 。
结论:
- 伪类为每个标记元素存在。
- 他们在默认情况下不可见的,因为他们是没有内容的属性初始化。
- 你不能为伪类与HTML标记的内容属性。
∴ 要显示。因此,伪元素的内容属性必须以CSS声明中声明,为了。
The reason you need a content: ''
declaration for each ::before
and/or ::after
pseudo-element is because the initial value of content
is normal
, which computes to none
on the ::before
and ::after
pseudo-elements. See the spec.
The reason the initial value of content
isn't an empty string but a value that computes to none
for the ::before
and ::after
pseudo-elements, is twofold:
Having empty inline content at the start and end of every element is rather silly. Remember that the original purpose of the ::before
and ::after
pseudo-elements is to insert generated content before and after the main content of an originating element. When there's no content to insert, creating an additional box just to insert nothing is pointless. So the none
value is there to tell the browser not to bother with creating an additional box.
The practice of using empty ::before
and ::after
pseudo-elements to create additional boxes for the sole purpose of layout aesthetics is relatively new, and some purists might even go so far as to call it a hack for this reason.
Having empty inline content at the start and end of every element means that every (non-replaced) element — including html
and body
— would by default generate not one box, but up to three boxes (and more in the case of elements that already generate more than just the principal box, like elements with list styles). How many of the two extra boxes per element will you actually use? That's potentially tripling the cost of layout for very little gain.
Realistically, even in this decade, less than 10% of the elements on a page will ever need ::before
and ::after
pseudo-elements for layout.
And so these pseudo-elements are made opt-in — because making them opt-out is not only a waste of system resources, but just plain illogical given their original purpose. The performance reason is also why I do not recommend generating pseudo-elements for every element using ::before, ::after
.
But then you might ask: why not have the display
property default to none
on ::before, ::after
? Simple: because the initial value of display
is not none
; it is inline
. Having inline
compute to none
on ::before, ::after
is not an option because then you could never display them inline. Having the initial value of display
be none
on ::before, ::after
is not an option because a property can only have one initial value. (This is why the initial value of content
is always normal
and it is simply defined to compute to none
on ::before, ::after
.)
在您添加content: ...
,在伪元素实际上并不存在 。
设置其他样式属性是不够给力的浏览器创建的元素。
文章来源: Why do the :before and :after pseudo-elements require a 'content' property?