Hen*_*son 14 css webkit css3 css-animations
我希望我的文本只使用CSS3闪烁.它工作正常.但是,如果我添加float:left到div的:before选择器,它会阻止动画在WebKit(Safari/Chrome)上运行.
为了演示,在WebKit上打开JSFiddle,删除它float:left以查看它是否正常工作.
CSS:
.blink_me:before {
content: "Blink";
}
.blink_me {
-webkit-animation: blinker 1.5s linear infinite;
-moz-animation: blinker 1.5s linear infinite;
-o-animation: blinker 1.5s linear infinite;
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% { opacity: 0.0; }
}
Run Code Online (Sandbox Code Playgroud)
HTML:
<span class="blink_me"> </span>
Run Code Online (Sandbox Code Playgroud)
如何使它与选择器上的浮点一起工作?
BOUNTY信息:只是奖励现有的答案,当然值得更多的赞成.
Har*_*rry 15
这似乎是因为Webkit中的图层创建和加速渲染过程.在Dev Tools中启用"Show Paint Rects"和"Show Composited Layer Borders"选项后,查看此答案中的所有演示.
运行任何一个演示时,您会看到一些绿色和橙色框.绿色框是绘制矩形,而橙色框是由渲染引擎创建的合成图层,用于加速渲染.在渲染过程中,Webkit(和Blink)并不总是重绘整个页面.只有页面的受影响区域(图层)才会重新绘制(以提高性能).
使用Float:
在这个片段中,您会看到渲染引擎创建了一个绘制矩形,一个页面的合成层和一个绘制矩形,该span元素的合成层("Some Content").由于span 是inline元素,因此它不会生成包含其后代框和生成内容的主要块级框.这(根据我的理解)使伪元素相对于根元素浮动.这也意味着伪元素在屏幕上的位置不依赖于父span元素(事实上,如果你给出一个负边距,span你会注意到内容重叠,而如果display: block设置为span负边距则移动伪元素 - 元素的内容也在左边).由于浮动元素的状态不会影响跨度,并且由于它也没有获得自己的合成图层,因此动画不会更改其不透明度.
.blink_me:before {
content: "Blink";
float: left;
}
.blink_me {
-webkit-animation: blinker 1.5s linear infinite;
-moz-animation: blinker 1.5s linear infinite;
-o-animation: blinker 1.5s linear infinite;
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0.0;
}
}Run Code Online (Sandbox Code Playgroud)
<span class="blink_me">Some content</span>Run Code Online (Sandbox Code Playgroud)
没有Float:
这里引擎创建了两个图层+两个绘制矩形,但由于没有浮动,因此伪元素也是inline父元素的一部分span(你会看到一个框覆盖"闪烁"和"一些内容").现在,由于伪的内容也是父级图层的一部分,因此父级上的动画也会影响伪元素的内容.
.blink_me:before {
content: "Blink";
}
.blink_me {
-webkit-animation: blinker 1.5s linear infinite;
-moz-animation: blinker 1.5s linear infinite;
-o-animation: blinker 1.5s linear infinite;
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0.0;
}
}Run Code Online (Sandbox Code Playgroud)
<span class="blink_me">Some content</span>Run Code Online (Sandbox Code Playgroud)
执行以下任何一项操作都会导致伪元素的内容被视为父元素图层的一部分,因此父元素上的动画也会影响子元素.当应用这些设置中的任何一个时,您再次注意到橙色边框覆盖了span元素的内容和伪元素的内容.
position在伪元素上设置任何值(相对或绝对或甚至固定).
.blink_me:before {
content: "Blink";
float: left;
position: relative;
}
.blink_me {
-webkit-animation: blinker 1.5s linear infinite;
-moz-animation: blinker 1.5s linear infinite;
-o-animation: blinker 1.5s linear infinite;
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0.0;
}
}Run Code Online (Sandbox Code Playgroud)
<span class="blink_me">Some content</span>Run Code Online (Sandbox Code Playgroud)
opacity在伪元素上设置1 以外的值(如0.99等).
.blink_me:before {
content: "Blink";
float: left;
opacity: 0.99;
}
.blink_me {
-webkit-animation: blinker 1.5s linear infinite;
-moz-animation: blinker 1.5s linear infinite;
-o-animation: blinker 1.5s linear infinite;
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0.0;
}
}Run Code Online (Sandbox Code Playgroud)
<span class="blink_me">Some content</span>Run Code Online (Sandbox Code Playgroud)
设置transform: translateZ(0px);伪元素.
.blink_me:before {
content: "Blink";
float: left;
transform: translateZ(0px);
}
.blink_me {
-webkit-animation: blinker 1.5s linear infinite;
-moz-animation: blinker 1.5s linear infinite;
-o-animation: blinker 1.5s linear infinite;
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0.0;
}
}Run Code Online (Sandbox Code Playgroud)
<span class="blink_me">Some content</span>Run Code Online (Sandbox Code Playgroud)
或者,另一种解决方案是直接在伪元素上设置动画,因为它然后获得自己的合成层,只有该层受到影响.
.blink_me:before {
content: "Blink";
float: left;
-webkit-animation: blinker 1.5s linear infinite;
-moz-animation: blinker 1.5s linear infinite;
-o-animation: blinker 1.5s linear infinite;
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0.0;
}
}Run Code Online (Sandbox Code Playgroud)
<span class="blink_me"> </span>Run Code Online (Sandbox Code Playgroud)
这是工作的另一个选项是设置display为inline-block或block母公司span.这也使得伪元素成为父元素的合成层的一部分,因此它也受到动画的影响.
.blink_me:before {
content: "Blink";
float: left;
}
.blink_me {
display: inline-block;
-webkit-animation: blinker 1.5s linear infinite;
-moz-animation: blinker 1.5s linear infinite;
-o-animation: blinker 1.5s linear infinite;
animation: blinker 1.5s linear infinite;
}
@keyframes blinker {
50% {
opacity: 0.0;
}
}Run Code Online (Sandbox Code Playgroud)
<span class="blink_me"> </span>Run Code Online (Sandbox Code Playgroud)
在参考文献下提供的第二个链接中,您将看到渲染过程如何在WebKit(和Blink)中从节点到渲染对象再渲染图层再到合成图层.
以下是对这些答案中所有演示的应用方式的总结,以及为什么它们按照它们的方式运行.
当伪元素上没有浮点数时:
Element | Node | Render Object | Render Layer | Compositing Layer
-----------------------------------------------------------------------------------------
Root | Yes | Yes | Yes | Yes (Descendant is a compositing layer)
span | Yes | Yes | Yes | Yes
:before | Yes | Yes | No | N/A
Run Code Online (Sandbox Code Playgroud)
这里span一旦动画启动就会获得渲染层,因为它是半透明的(由于不透明度),并且它获得了一个合成层,因为它具有不透明度动画.伪获取它自己的渲染层,因为它不满足任何所需的条件,因此也不会得到合成层.它成为第一个祖先的渲染+合成层的一部分.在合成期间,伪的内容也会受到影响,因为它也是图层的一部分.
当伪元素上有浮点数时:
Element | Node | Render Object | Render Layer | Compositing Layer
-----------------------------------------------------------------------------------------
Root | Yes | Yes | Yes | Yes (Descendant is a compositing layer)
span | Yes | Yes | Yes | Yes
:before | Yes | Yes | No | N/A
Run Code Online (Sandbox Code Playgroud)
与之前相同,但由于存在浮点而且它不是其中的一部分span,因此伪不是其合成层的一部分,因此在合成操作期间不会被修改.
当伪元素定位时:
Element | Node | Render Object | Render Layer | Compositing Layer
-----------------------------------------------------------------------------------------
Root | Yes | Yes | Yes | Yes (Descendant is a compositing layer)
span | Yes | Yes | Yes | Yes
:before | Yes | Yes | Yes | No
Run Code Online (Sandbox Code Playgroud)
当psuedo定位时,它会获得它自己的渲染层(因为它符合条件),但是没有得到合成层,因为它与所需的条件不匹配.此外,它的定位意味着它在屏幕上的位置受到跨度上任何变换的影响.看起来这使得伪元素也成为span的合成层的一部分,因此作为合成操作的一部分被修改.
当伪元素的不透明度小于1时:
Element | Node | Render Object | Render Layer | Compositing Layer
-----------------------------------------------------------------------------------------
Root | Yes | Yes | Yes | Yes (Descendant is a compositing layer)
span | Yes | Yes | Yes | Yes
:before | Yes | Yes | Yes | No
Run Code Online (Sandbox Code Playgroud)
类似于前一个案例.这里,不透明度小于1的伪意味着当它下面的层发生变化时需要改变(否则,透明度会被破坏).因此,这似乎被移动到合成层,因此在合成期间被修改.
当伪元素有变换时:
Element | Node | Render Object | Render Layer | Compositing Layer
-----------------------------------------------------------------------------------------
Root | Yes | Yes | Yes | Yes (Descendant is a compositing layer)
span | Yes | Yes | Yes | Yes
:before | Yes | Yes | Yes | Yes
Run Code Online (Sandbox Code Playgroud)
这里,伪也有自己的合成层,因为它有一个3D变换,因为它是子的span,它的层在跨度的层之上.这意味着在合成期间,跨度和伪元素的图层都会被修改,因此动画也会影响伪.
当伪元素直接动画时:
Element | Node | Render Object | Render Layer | Compositing Layer
-----------------------------------------------------------------------------------------
Root | Yes | Yes | Yes | Yes (Descendant is a compositing layer)
span | Yes | Yes | No | N/A
:before | Yes | Yes | Yes | Yes
Run Code Online (Sandbox Code Playgroud)
这里span没有渲染或合成图层,因为不透明度动画在伪元素上.由于pseudo获得了自己的合成层,因此在合成过程中它也会受到影响.
当span显示为块或内联块时:
Element | Node | Render Object | Render Layer | Compositing Layer
-----------------------------------------------------------------------------------------
Root | Yes | Yes | Yes | Yes (Descendant is a compositing layer)
span | Yes | Yes | Yes | Yes
:before | Yes | Yes | No | N/A
Run Code Online (Sandbox Code Playgroud)
这与伪元素浮动的情况非常相似,但由于此处span是块级元素,因此它为其后代和生成的内容生成主块级别框.因此,伪变为跨度合成层的一部分,因此在合成期间受到影响.
注意:整个渲染过程非常复杂,您可以从参考链接中看到,我已尽力解释该过程.有可能我错了一些错综复杂的细节,但总的来说,你会发现解释符合开发工具的输出.
您可以通过参考以下链接找到有关如何启用"显示绘制矩形","显示合成图层边框"选项以及加速渲染过程如何工作的更多信息: