为什么:before和:after伪元素需要'content'属性? [英] Why do the :before and :after pseudo-elements require a 'content' property?
问题描述
在以下情况下,为什么:after
选择器为什么需要content属性才能起作用?
Given the following scenario, why does the :after
selector require a content property to function?
.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属性之前如何看不到伪元素:
Notice how you do not see the pseudo element until you specify the content property:
.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调试器中看到样式.但是,它们不会显示在页面上.
Why is this the intended functionality? You would think that the display block would force the element to show up. Oddly enough, you can actually see the styles inside web debuggers; however, they do not display on the page.
推荐答案
每个::before
和/或::after
伪元素都需要content: ''
声明的原因是,content
的初始值为normal
,在::before
和::after
伪元素上计算为none
.参见规范.
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.
content
的初始值不是一个空字符串,而是为::before
和::after
伪元素计算为none
的值的原因有两个:
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:
-
在每个元素的开头和结尾处都有空的内联内容是很愚蠢的.请记住,
::before
和::after
伪元素的原始目的是在原始元素的主要内容之前和之后插入生成的内容.当没有要插入的内容时,创建一个仅插入任何内容的附加框是没有意义的.因此,none
值用于指示浏览器不要打扰创建附加框.
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 thenone
value is there to tell the browser not to bother with creating an additional box.
仅出于布局美学目的,使用空的::before
和::after
伪元素创建其他盒子的做法是相对较新的,因此一些纯粹主义者甚至可能甚至称其为hack. .
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.
在每个元素的开头和结尾处都有空的内联内容,这意味着每个(不可替换的)元素(包括html
和body
)默认情况下不会生成一个框,但最多会生成三个框(如果元素已经生成了不仅仅是主体框的元素,则为 more ,例如具有列表样式的元素).您将实际使用每个元素两个额外的盒子中的多少个?这可能是三倍的布局成本,而收益却很小.
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.
实际上,即使在这个十年中,页面上不到10%的元素将永远需要::before
和::after
伪元素进行布局.
Realistically, even in this decade, less than 10% of the elements on a page will ever need ::before
and ::after
pseudo-elements for layout.
因此,这些伪元素被选为加入-因为将其选为退出不仅浪费了系统资源,而且给定了它们的原始目的,这仅仅是不合逻辑的.性能原因也是为什么我不建议使用::before, ::after
为每个元素生成伪元素.
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
.
但是随后您可能会问:为什么::before, ::after
的display
属性默认设置为none
?简单:因为display
的初始值不是none
;它是inline
.在::before, ::after
上将inline
计算为none
的操作不是一种选择,因为那样一来您就无法内联显示它们.不能将display
的初始值设置为::before, ::after
的none
,因为属性只能具有一个初始值. (这就是content
的初始值始终为normal
的原因,并且将其简单定义为在::before, ::after
上计算为none
的原因.)
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
.)
这篇关于为什么:before和:after伪元素需要'content'属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!