HTML+CSS入门之CSS 混合模式\滤镜导致 CSS 3D 失效问题
沉沙 2018-12-29 来源 : 阅读 1235 评论 0

摘要:本篇教程探讨了HTML+CSS入门之CSS 混合模式\滤镜导致 CSS 3D 失效问题,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

本篇教程探讨了HTML+CSS入门之CSS 混合模式\滤镜导致 CSS 3D 失效问题,希望阅读本篇文章以后大家有所收获,帮助大家对相关内容的理解更加深入。

HTML+CSS入门之CSS 混合模式滤镜导致 CSS 3D 失效问题

<

今天在写一个小的 CSS Demo,一个关于 3d 球的旋转动画,关于 CSS 3D,少不了会使用下面这几个属性:
{
    transform-style: preserve-3d;
    perspective: 1000;
    transform: translate3d();
}
这个 Demo 你可以戳这里,大概是这样:CodePen Demo - 3D ball
:
3dball
嗯,大概到了这个效果,想到了 CSS 混合模式 mix-blend-mode,寻思着,利用混合模式,是否能让效果更上一层楼或者碰撞出一些其他火花。
    mix-blend-mode:我们通常称之为混合模式,利用混合模式将多个图层混合可以得到一个新的效果,mix-blend-mode 描述了元素的内容应该与元素的直系父元素的内容和元素的背景如何混合。
    关于混合模式的一些使用可以看这里:不可思议的混合模式 background-blend-mode (二)、不可思议的混合模式 background-blend-mode
CSS 3D 配合 mix-blend-mode
然而,给元素加上了一个混合模式之后,神奇的事情发生了,3D 效果消失了。
也就是在每个光点的 CSS 元素代码中添加这样一句:
{
    mix-blend-mode: lighten;
}
3dball2
效果从 CSS 3D 变成了 2D。
qq 20181217194534
这就很蹊跷了,预想中的混合并没有发生,取而代之的是 3D 的失效。我想,也许与内核有关,上面的效果是在 chrome 65.0.3325.181 试验得到的。
是否与浏览器内核有关?
带着这样的疑问,我又测试了下其他几个内核:
    firefox 64.0 -- 这次更加诡异,整个图案都不会再被渲染出来
    Safari 12.0.2 -- 渲染正常
Safari 是可以正常展示的,只能初略的认为,应该是与内核有关系的。那应该也有很多人遇到过同样的问题,带着这个疑惑,google 一下。
爆栈网也有同学提出类似的疑惑:StackOverflow -- mix-blend-mode is broken by 3D transformations on page
image
随后,在 chromium bug 提交网站上,找到了 15 年的一个 bug 单,也是对这个问题的疑问:
BUG -CSS mix-blend-mode turns off CSS perspective.
最终在 bug 单的最下面找到了可能靠谱的回答:
    When we have mix-blend-mode, the closest ancestor that creates stacking context will isolate blending. We create a render surface at the root of this isolated group and because render surfaces don't support preserve-3d(because they render into separate FBO), we see a flattened result.
    ajuma@ suggested that this bug maybe much easier to fix after Slimming paint v2 if we can somehow disentangle transforms from layers.
翻译一下,意思大概是:当我们使用 CSS 混合模式的时候,堆叠上下文会重新对这个使用了混合模式的元素的根节点处创建一个独立的渲染平面,但是很可惜,这个渲染平面是不支持 preserve-3d 的(因为它们渲染到单独的FBO中),所以我们看到是一个 2D 的平面效果。
验证 Layer borders
上面的那句话应该已经可以作为结论,我再使用 chrome 提供的工具验证一下,打开开发者工具的 Rendering -> Layer borders:
image
黄色代表 CSS 渲染时候的 GraphicsLayer 层, 蓝色网格表示瓦片(tile),你可以把它们当作是层的单元(并不是层),Chrome 内核可以将它们作为一个大层的部分上传给 GPU 进行渲染加速。
    正常 3D 模式下,开启 Layer borders 效果:
balllayer
    添加了 mix-blend-mode 的 3D 模式下,开启 Layer borders 效果:
balllayer2
可以看到,在 mix-blend-mode 的 3D 模式下,确实在整个球形元素之外,又多了一层蓝色 tile。也就是上文提到的独立的渲染平面,也就是因为这个渲染平面不支持 preserve-3d 的原因,我们最终得到了一个 2D 平面图形。
滤镜也会导致 CSS 3D 失效
完了吗?没有。不是吧,这谁顶得住啊。
qq 20181218111248
那么如果是因为 mix-blend-mode 多生成了一个独立渲染平面导致的 3D 失效,那么是否有其他元素也会导致同样的结果呢?
带着疑惑,去掉了 mix-blend-mode,我又给设置了 3d 的元素添加了一个滤镜:
{
-    mix-blend-mode: lighten;
+    filter: blur(1px);
}
果然,出现了同样的问题,3D 失效:
balllayer3
总结一下
嗯。那么应该可以初步得到一个结论就是所有这些在渲染时候需要再独立生成一个渲染平面,且包含了 preserve-3d 的属性,都会导致内部的 CSS 3D 失效。
暂时我发现的有下述几个属性,都会导致 CSS 3D 失效:
    mix-blend-mode
    background-blend-mode
    filter
其他问题
这个 bug 有什么影响
额,通常来说,很少会有人在使用 CSS 3D 的同时使用混合模式或者滤镜,这两个属性更多的锦上添花的作用,所以大部分时候,不使用它们就不会有问题, 所以影响不是很大。
上文中的 FBO 是什么?
上文的 FBO 准确而言是什么我也无法 100% 确定,推测应该是 Frame Buffer Object,帧缓存对象,存在于显存中。帧缓存是一些二维数组和 OpenGL 所使用的存储区的集合:颜色缓存、深度缓存、模板缓存和累计缓存。
各种三维场景现在渲染到屏幕上都是先放到一个 FBO 中,可以理解为一张离屛图片,用于加速渲染。
Bug 何时会被修复
在 chromium bugs 网站,上述 bug 被合并到 issue 575099,并且最终状态是 Untriaged,表示尚未分配优先级,意思是等待某人确定哪个人应该认领并修复该特定错误。所以,短期内可能无望解决。    

本文由职坐标整理发布,学习更多的相关知识,请关注职坐标IT知识库!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程