今天在写一个小的 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-mode
  • background-blend-mode
  • filter

其他问题

这个 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 失效问题的更多相关文章

  1. cordova 导致css中绝对定位top:0会被顶到视图之外

    IOS7+ webview全屏导致状态栏悬浮在页面上 解决方案:打开 ios项目/classes/MainViewController.m,修改viewWillAppear方法 - (void)vie ...

  2. CSS混合模式

    前面的话   层叠上下文z-index只是解决两个元素覆盖,谁离用户更近的问题.而CSS混合模式,则是处理两个元素覆盖部分如何混合的问题.如果了解photoshop的话,对这种现象应该不陌生.CSS3 ...

  3. 解决ie9以下浏览器对html5新增标签的不识别,并导致CSS不起作用的问题

    https://www.cnblogs.com/yangjie-space/p/4816279.html html5shiv.js和respond.min.js 做页面常用的东西,写这里用的时候省点去 ...

  4. 简单说 通过CSS的滤镜 实现 火焰效果

    说明 上次我们了解了一些css滤镜的基础知识, 简单说 CSS滤镜 filter属性 这次我们就来用css的滤镜实现一个 火焰的效果. 解释 要实现上面的火焰效果,我们先来了解一些必要的东西. 上次我 ...

  5. Webkit内核探究【2】——Webkit CSS实现

    注:[转载请注明文章来源.保持原样] 出处:http://www.cnblogs.com/jyli/archive/2010/01/31/1660364.html 作者:李嘉昱 CSS在Webkit中 ...

  6. [转]CSS遮罩——如何在CSS中使用遮罩

    特别声明:此篇文章由D姐根据Christian Schaefer的英文文章原名<CSS Masks – How To Use Masking In CSS Now>进行翻译,整个译文带有我 ...

  7. CSS学习笔记01 CSS简介

    1.CSS定义 CSS 指层叠样式表 (Cascading Style Sheets),是一种样式表语言,用来描述 HTML 或 XML(包括如 SVG.XHTML 之类的 XML 分支语言)文档的呈 ...

  8. CSS3与页面布局学习笔记(五)——Web Font与CSS Sprites(又称CSS精灵、雪碧图)技术

    一.web font web font是应用在web中的一种字体技术,在CSS中使用font-face定义新的字体.先了解操作系统中的字体: a).安装好操作系统后,会默认安装一些字体,这些字体文件描 ...

  9. CSS高效开发实战:CSS 3、LESS、SASS、Bootstrap、Foundation --读书笔记(1)设定背景图

    技术的新发展,除计算机可以接入互联网之外,平板电脑.智能手机.智能电视等其他设备均可访问互联网.在多设备时代,构建多屏体验也不是听说的那么难. 但是这也增加了学习CSS的难度?不知道如何上手,只懂一点 ...

随机推荐

  1. 关于Linux虚拟化技术KVM的科普 科普二(KVM虚拟机代码揭秘)

    代码分析文章<KVM虚拟机代码揭秘--QEMU代码结构分析>.<KVM虚拟机代码揭秘--中断虚拟化>.<KVM虚拟机代码揭秘--设备IO虚拟化>.<KVM虚拟 ...

  2. Spring support optimize

    https://github.com/alibaba/fastjson/pull/1337

  3. Array.prototype.slice.call()方法详解

    在很多时候经常看到Array.prototype.slice.call()方法,比如Array.prototype.slice.call(arguments),下面讲一下其原理: 1.基本讲解 1.在 ...

  4. MySQL使用细节

    ************************************************************************ MySQL使用细节,包括部分常用函数以及注意如何提高数 ...

  5. SPU和SKU有什么区别

    SPU = Standard Product Unit (标准产品单位)SPU是商品信息聚合的最小单位,是一组可复用.易检索的标准化信息的集合,该集合描述了一个产品的特性.通俗点讲,属性值.特性相同的 ...

  6. Java基础系列--基础排序算法

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9082138.html 一.概述 基础排序算法包括:桶排序.冒泡排序.选择排序.插入排序等 ...

  7. Linux下全局安装composer

    下载composer curl -sS https://getcomposer.org/installer | php 将composer.phar文件移动到bin目录以便全局使用composer命令 ...

  8. python+appium 查找某个元素find_element()并click()点击,正向判断与反判断的方法封装

    使用场景: 在自动化测试过程中,难免会用到反判断,包括异常情况的处理,比如:find_element_by_name('测试') 判断"测试"是否存在,存在则点击,不存在则执行其他 ...

  9. CSS3实例分享之多重背景的实现(Multiple backgrounds)

    CSS3的诞生为我们解决了这一问题,在CSS3里,通过background-image或者background可以为一个容器设置多张背景图像,也就是说可以把不同背景图象只放到一个块元素里. 首先我们来 ...

  10. Docker 集群

    1.  理解swarm swarm(译:集群) 一个swarm是一组运行着Docker的机器,它们一起加入到一个集群.swarm中的机器既可以是物理机,也可以是虚拟机.在加入到一个swarm后,每台机 ...