博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Safari 3D transform变换z-index层级渲染异常的研究
阅读量:6932 次
发布时间:2019-06-27

本文共 2094 字,大约阅读时间需要 6 分钟。

一、Safari是新时代的IE6

在2年前介绍的时候就提过Safari的问题,就是伪元素hover时候的currentColor不渲染,

像这种IE浏览器都可以正常渲染的CSS,Safari居然出现各种匪夷所思的问题,对的,是各种,而且全都是与渲染相关的,这也难怪为什么Safari浏览器被称为“新时代的IE6”了!

补充于2016-08-09

Safari font-size的px单位和vm单位计算不支持,需要是百分比单位,可参见。
Safari 渐变,从#fff到transparent会有灰色带,其他浏览器都是白色到透明。

或许,很早的时候,Safari和IE有段暧昧不清的过往(看下图的攻受表情):

Safari和IE

本文即将介绍的渲染问题,也是仅Safari浏览器才有的,是我同事遇到的,我觉得很有意思,忍不住拿来和大家分享下。

二、Safari 3D变换会忽略z-index的层级

在Safari浏览器下,此Safari浏览器包括iOS的Safari,iPhone上的微信浏览器,以及Mac OS X系统的Safari浏览器,当我们使用3D transform变换的时候,如果祖先元素没有overflow:hidden/scroll/auto等限制,则会直接忽略自身和其他元素的z-index层叠顺序设置,而直接使用真实世界的3D视角进行渲染。

我们直接看例子,如果您现在用的是iMac或air或iPad或iPhone之类的苹果设备浏览本文,您可以狠狠地点击这里:

如果高度不够页面滚动,请双指放大页面比例,让图片和红色条子(fixed定位)发生重叠,就会看到很有趣的渲染效果。

如果您是window系统的浏览器上浏览本文,但是手上有iPhone,也可以使用微信等app扫描访问:

demo页面二维码

不出意外,滚动页面,会看到类似下面这样的渲染效果:

渲染异常显示截图

会看到,红色的块状条子,从图片中心穿过去了。实际上,这个红色条子是层级99的position:fixed定位的元素:

.bar {    position: fixed;     /* Safari下z-index无效 */    z-index: 99;}

而图片就是一个小白图片,没有定位属性的设置,就一个简单的带有视角的3D旋转变换:

img {    transform: perspective(300px) rotateY(40deg);}

按照CSS规范上的说明,红色条子应该在图片上面,类似下面这样:

Chrome浏览器下截图

IE, Chrome, FireFox都是遵循这种渲染的,但是,Safari浏览器却自己任性了一把。直接把z-index:99给无视了,对无视了,在座的诸位也不要怀疑是不是99还不够大,就算是9999999这是这般渲染,因为Safari是忽略z-index,而不是IE6,IE7那种z-index计算bug.

根据我自己的理解,Safari的这种渲染或许并不能直接称之为bug, 因为,从某些角度讲,Safari的这种渲染挺符合符合现实3D世界。

我自己YY了一下,Safari如果没有overflow的限制,就会把2次元页面变成真实的3次元,原本图片和红色条子在一个面上,当图片进行了3D旋转,那自然红色条子就从中心穿过,而且视角背后的内容是看不见的。

算了,别继续开脑洞了,来看看这个问题该如何解决吧~~

三、Safari 3D变换会忽略z-index问题解决

方法1:

父级,任意父级,非body级别,设置overflow:hidden可恢复和其他浏览器一样的渲染。

方法2:

以毒攻毒。有时候,页面复杂,我们不能给父级设置overflow:hidden,怎么办呢?

杨过的情花剧毒怎么解的?断肠草啊,另一种剧毒。这里也是类似。既然“穿越”的渲染问题是由3D transform变换产生的,那么,要解决此问题,我们也可以使用3D transform变换。

那具体该如何做呢?

我在“”一文中就科普过z轴的概念。

我们仔细观察下面这张效果截图:

渲染异常显示截图

我们的红色条子在z轴位置0处,对不对,所以才从图片的中心穿过。而z轴是我们眼睛看屏幕这条轴,在z轴的值越大,就离用户的眼睛越近;值越小,里用户眼睛越小。所谓近大远小(如果指定了视角perspective),就是这么回事。

网页中z轴示意

所以,我们要想让红色条子覆盖在图片上,只要设置一个足够大的translateZ值就可以,如100px

.bar {    position: fixed;    z-index: 99;    /* 以毒攻毒 */    transform: translateZ(100px);}

结果:

translateZ(100px) 的效果截图

咦,尴尬,好像还是不够大,图片还有一点点位置在红色条的上面~~ 

赶快用120px试试:

.bar {    position: fixed;    z-index: 99;    /* 以毒攻毒 */    transform: translateZ(120px);}

结果:

translateZ(120px)效果截图

喔噢,这下图片完全被红色的长条子覆盖了,这下,所有浏览器的表现都是一模一样的啦!

转载地址:http://pfmjl.baihongyu.com/

你可能感兴趣的文章
将android工程作为另一个工程的库
查看>>
mongodb的php扩展安装
查看>>
老视窗 新体验——win 8体验报告(3)
查看>>
upupoo(网页壁纸)自主修改一:农历
查看>>
圣杯布局
查看>>
软件版本Beta,RC,Demo,Build,GA等是什么意思呢?
查看>>
MyBaits基本概念和原理
查看>>
博科:物理与虚拟网络的统一管理
查看>>
(转)TMG2010 日志队列
查看>>
桐庐县第一人民医院数据库容灾备份系统项目-存储网关
查看>>
android.os.NetworkOnMainThreadException
查看>>
Java基本语法(四)数组
查看>>
ocjp 91-100
查看>>
虚拟化用户***率不断提升 应用加速转化端到端
查看>>
图说:轻松让Windows 8有个印象中的“开始菜单”
查看>>
洛谷——P3387 【模板】缩点
查看>>
我的友情链接
查看>>
编程者的修仙之路
查看>>
使用IPSec虚拟隧道接口建立IPSec安全隧道
查看>>
洛谷—— P3372 【模板】线段树 1
查看>>