为了演示,在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; } }
HTML:
<span class="blink_me"> </span>
如何使其与选择器上的浮动一起工作?
BOUNTY信息:只是奖励现有的答案当然值得更多的升值.
解决方法
这绝对是因为Webkit中的层创建和加速渲染过程.在开发工具中启用“显示绘制矩形”和“显示合成图层边框”选项后,请查看此答案中的所有演示.
当任何一个演示运行时,您会看到一些绿色和橙色的盒子.绿色框是油漆矩形,而橙色框是由渲染引擎用于加速渲染创建的合成图层.在渲染过程中,Webkit(和Blink)并不总是重绘整个页面.页面的受影响区域(图层)只能重新绘制(用于演示).
与浮动:
在这段代码中,您会看到渲染引擎创建一个绘制矩形,页面的合成图层和一个绘图矩形,跨度元素的合成图层(“Some Content”).由于span是一个内联元素,它不会生成包含其后代的框和生成的内容的principal block-level box.这(根据我的理解)使伪元素相对于根元素浮动.这也意味着伪元素在屏幕上的位置不依赖于父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; } }
<span class="blink_me">Some content</span>
没有浮动:
此外,引擎还会创建两层两个颜色矩形,但是由于没有浮点,伪元素也是内联的,并且是父范围的一部分(您将看到一个框包含“Blink”和“Some content”)) .现在由于伪的内容也是父层的一部分,父类上的动画也会影响伪元素的内容.
.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; } }
<span class="blink_me">Some content</span>
解决方案:
执行以下任何一种操作会导致伪元素的内容被视为父元素层的一部分,因此父类的动画也影响到该子元素.当应用这些设置中的任何一个时,您将再次注意到覆盖了span元素内容和伪元素内容的橙色边框.
>在伪元素上设置任何位置(相对或绝对或甚至固定).
.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; } }
<span class="blink_me">Some content</span>
>在伪元素上设置不同于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; } }
<span class="blink_me">Some content</span>
>设置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; } }
<span class="blink_me">Some content</span>
或者,另一个解决方案是直接在伪元素上设置动画,因为它会获得自己的合成图层,只有该图层受到影响.
.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; } }
<span class="blink_me"> </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; } }
<span class="blink_me"> </span>
概要
在引用下提供的第二个链接中,您将看到渲染过程如何从Web节点(和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
这里,一旦动画开始,跨度就会获得渲染层,因为它是半透明的(由于不透明度),并且它由于具有不透明度动画而获得合成图层.伪没有自己的渲染层,因为它不满足任何所需的标准,因此也不会获得合成图层.它成为第一个祖先的渲染合成图层的一部分.在合成期间,伪的内容也受到影响,因为它也是图层的一部分.
伪元素上有float时:
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
与以前相同,但是由于浮点并不属于跨度,因此伪不是其合成层的一部分,因此在合成操作期间不会被修改.
伪元素定位时:
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
当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
与上一个类似的情况.这里的伪具有小于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
在这里,伪也有自己的合成层,因为它有一个3D变换,由于它是跨度的孩子,它的层在跨度的层之上.这意味着在合成期间,跨度和伪元素的层都被修改,因此动画也会影响伪.
当伪元素直接动画时:
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
在这里,由于opacity动画在伪元素上,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
这与伪元素浮动的情况非常相似,但是由于这里的span是块级元素,它会为其后代和生成的内容生成主块级别框.因此,伪成为跨度合成层的一部分,因此在合成过程中受到影响.
Note: The whole rendering process is very complex as you could see from the reference links and I’ve tried my best to explain the process. There are chances that I could have some of the intricate details wrong but on the overall you’d find that the explanation tallies with the Dev tools output.
参考文献:
您可以找到有关如何启用“显示绘制矩形”,“显示合成图层边框”选项以及加速渲染过程如何通过参考以下链接的更多信息:
> HTML5 Rocks – Accelerated Rendering in Chrome
> GPU Accelerated Compositing in Chrome.