探究 CSS 混合模式\滤镜导致 CSS 3D 失效问题
今天在写一个小的 CSS Demo,一个关于 3d 球的旋转动画,关于 CSS 3D,少不了会使用下面这几个属性:
{
transform-style: preserve-3d;
perspective: 1000;
transform: translate3d();
}
这个 Demo 你可以戳这里,大概是这样:CodePen Demo - 3D ball:

嗯,大概到了这个效果,想到了 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;
}

效果从 CSS 3D 变成了 2D。

这就很蹊跷了,预想中的混合并没有发生,取而代之的是 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

随后,在 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:

黄色代表 CSS 渲染时候的 GraphicsLayer 层, 蓝色网格表示瓦片(tile),你可以把它们当作是层的单元(并不是层),Chrome 内核可以将它们作为一个大层的部分上传给 GPU 进行渲染加速。
- 正常 3D 模式下,开启 Layer borders 效果:

- 添加了
mix-blend-mode的 3D 模式下,开启 Layer borders 效果:

可以看到,在 mix-blend-mode 的 3D 模式下,确实在整个球形元素之外,又多了一层蓝色 tile。也就是上文提到的独立的渲染平面,也就是因为这个渲染平面不支持 preserve-3d 的原因,我们最终得到了一个 2D 平面图形。
滤镜也会导致 CSS 3D 失效
完了吗?没有。不是吧,这谁顶得住啊。

那么如果是因为 mix-blend-mode 多生成了一个独立渲染平面导致的 3D 失效,那么是否有其他元素也会导致同样的结果呢?
带着疑惑,去掉了 mix-blend-mode,我又给设置了 3d 的元素添加了一个滤镜:
{
- mix-blend-mode: lighten;
+ filter: blur(1px);
}
果然,出现了同样的问题,3D 失效:

总结一下
嗯。那么应该可以初步得到一个结论就是所有这些在渲染时候需要再独立生成一个渲染平面,且包含了 preserve-3d 的属性,都会导致内部的 CSS 3D 失效。
暂时我发现的有下述几个属性,都会导致 CSS 3D 失效:
mix-blend-modebackground-blend-modefilter
其他问题
这个 bug 有什么影响
额,通常来说,很少会有人在使用 CSS 3D 的同时使用混合模式或者滤镜,这两个属性更多的锦上添花的作用,所以大部分时候,不使用它们就不会有问题, 所以影响不是很大。
上文中的 FBO 是什么?
上文的 FBO 准确而言是什么我也无法 100% 确定,推测应该是 Frame Buffer Object,帧缓存对象,存在于显存中。帧缓存是一些二维数组和 OpenGL 所使用的存储区的集合:颜色缓存、深度缓存、模板缓存和累计缓存。
各种三维场景现在渲染到屏幕上都是先放到一个 FBO 中,可以理解为一张离屛图片,用于加速渲染。
Bug 何时会被修复
在 chromium bugs 网站,上述 bug 被合并到 issue 575099,并且最终状态是 Untriaged,表示尚未分配优先级,意思是等待某人确定哪个人应该认领并修复该特定错误。所以,短期内可能无望解决。
最后
感谢耐心读完。更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
好了,本文到此结束,希望对你有帮助 :)
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
探究 CSS 混合模式\滤镜导致 CSS 3D 失效问题的更多相关文章
- cordova 导致css中绝对定位top:0会被顶到视图之外
IOS7+ webview全屏导致状态栏悬浮在页面上 解决方案:打开 ios项目/classes/MainViewController.m,修改viewWillAppear方法 - (void)vie ...
- CSS混合模式
前面的话 层叠上下文z-index只是解决两个元素覆盖,谁离用户更近的问题.而CSS混合模式,则是处理两个元素覆盖部分如何混合的问题.如果了解photoshop的话,对这种现象应该不陌生.CSS3 ...
- 解决ie9以下浏览器对html5新增标签的不识别,并导致CSS不起作用的问题
https://www.cnblogs.com/yangjie-space/p/4816279.html html5shiv.js和respond.min.js 做页面常用的东西,写这里用的时候省点去 ...
- 简单说 通过CSS的滤镜 实现 火焰效果
说明 上次我们了解了一些css滤镜的基础知识, 简单说 CSS滤镜 filter属性 这次我们就来用css的滤镜实现一个 火焰的效果. 解释 要实现上面的火焰效果,我们先来了解一些必要的东西. 上次我 ...
- Webkit内核探究【2】——Webkit CSS实现
注:[转载请注明文章来源.保持原样] 出处:http://www.cnblogs.com/jyli/archive/2010/01/31/1660364.html 作者:李嘉昱 CSS在Webkit中 ...
- [转]CSS遮罩——如何在CSS中使用遮罩
特别声明:此篇文章由D姐根据Christian Schaefer的英文文章原名<CSS Masks – How To Use Masking In CSS Now>进行翻译,整个译文带有我 ...
- CSS学习笔记01 CSS简介
1.CSS定义 CSS 指层叠样式表 (Cascading Style Sheets),是一种样式表语言,用来描述 HTML 或 XML(包括如 SVG.XHTML 之类的 XML 分支语言)文档的呈 ...
- CSS3与页面布局学习笔记(五)——Web Font与CSS Sprites(又称CSS精灵、雪碧图)技术
一.web font web font是应用在web中的一种字体技术,在CSS中使用font-face定义新的字体.先了解操作系统中的字体: a).安装好操作系统后,会默认安装一些字体,这些字体文件描 ...
- CSS高效开发实战:CSS 3、LESS、SASS、Bootstrap、Foundation --读书笔记(1)设定背景图
技术的新发展,除计算机可以接入互联网之外,平板电脑.智能手机.智能电视等其他设备均可访问互联网.在多设备时代,构建多屏体验也不是听说的那么难. 但是这也增加了学习CSS的难度?不知道如何上手,只懂一点 ...
随机推荐
- testng实现场景恢复
自动化测试过程中存在很多的不稳定性,例如网络的不稳定,浏览器无响应等等,这些失败往往并不是产品中的错误.那么这时我们需要对执行失败的场景恢复重新执行,确认其是否确实失败. 以前使用QTP的时候也使用了 ...
- MySQL复制进阶
Ⅰ.背景 搭建MySQL复制环境非常简单 你的系统是否也是像我之前那么搭建的呢? 那么,你的复制系统是否出现过以下的情况呢? 复制报错,例如:1062,1032 主从数据不一致 Ⅱ.真正高可靠复制环境 ...
- 阿里云部署java项目参考如下链接
http://www.cnblogs.com/softidea/p/5271746.html https://oneinstack.com/question/how-to-deploy-java-ap ...
- FPGA学习笔记(四)——Verilog基本语法
###### [该随笔部分内容转载自小梅哥] ######### 组合逻辑: 多路选择器.加法器.译码器.乘法器 时序逻辑: 计数器.分频器.定时器.移位寄存器 一.Verilog文件的基 ...
- [html]------行内元素与块级元素
块级元素(block element)div -最常用的块级元素dl - 和dt dd搭配使用的块级元素form - 交互表单h1 - 大标题hr - 水平分隔线ol - 排序表单p - 段落ul - ...
- kafka 三个配置文件
kafka的配置分为 broker.producter.consumer三个不同的配置 一 BROKER 的全局配置 最为核心的三个配置 broker.id.log.dir.zookeeper.c ...
- Java 读书笔记 (十) 循环
while循环 只要布尔表达式为true,循环就一直执行下去. public class Test( public static void main(String args[]){ int x=10; ...
- disk.go
package disk import "syscall" //空间使用结构体 type DiskStatus struct { Size uint64 Used ...
- go源文件中是否有main函数
import ( "go/parser" "go/token" "go/ast" ) func HasMain(file s ...
- Hibernate Annotation _List/Map
// Student.java 实体类 package com.tao.pojo; import java.util.List; public class Student { private int ...