by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=5569
css
在2年前介绍currentColor变量的时候就提过Safari的问题,就是伪元素hover时候的currentColor不渲染,html
像这种IE浏览器均可以正常渲染的CSS,Safari竟然出现各类匪夷所思的问题,对的,是各类,并且全都是与渲染相关的,这也难怪为何Safari浏览器被称为“新时代的IE6”了!css3
补充于2016-08-09
Safari font-size的px单位和vm单位计算不支持,须要是百分比单位,可参见这篇文章。
Safari 渐变,从#fff到transparent会有灰色带,其余浏览器都是白色到透明。浏览器
或许,很早的时候,Safari和IE有段暧昧不清的过往(看下图的攻受表情):微信
本文即将介绍的渲染问题,也是仅Safari浏览器才有的,是我同事遇到的,我以为颇有意思,忍不住拿来和你们分享下。app
在Safari浏览器下,此Safari浏览器包括iOS的Safari,iPhone上的微信浏览器,以及Mac OS X系统的Safari浏览器,当咱们使用3D transform变换的时候,若是祖先元素没有overflow:hidden/scroll/auto等限制,则会直接忽略自身和其余元素的z-index层叠顺序设置,而直接使用真实世界的3D视角进行渲染。wordpress
咱们直接看例子,若是您如今用的是iMac或air或iPad或iPhone之类的苹果设备浏览本文,您能够狠狠地点击这里:Safari浏览器下3D transform和z-index层级渲染demospa
若是高度不够页面滚动,请双指放大页面比例,让图片和红色条子(fixed定位)发生重叠,就会看到颇有趣的渲染效果。3d
若是您是window系统的浏览器上浏览本文,可是手上有iPhone,也可使用微信等app扫描访问:code
不出意外,滚动页面,会看到相似下面这样的渲染效果:
会看到,红色的块状条子,从图片中心穿过去了。实际上,这个红色条子是层级99的position:fixed
定位的元素:
.bar { position: fixed; /* Safari下z-index无效 */ z-index: 99; }
而图片就是一个小白图片,没有定位属性的设置,就一个简单的带有视角的3D旋转变换:
img { transform: perspective(300px) rotateY(40deg); }
按照CSS规范上的说明,红色条子应该在图片上面,相似下面这样:
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旋转,那天然红色条子就从中心穿过,并且视角背后的内容是看不见的。
算了,别继续开脑洞了,来看看这个问题该如何解决吧~~
方法1:
父级,任意父级,非body级别,设置overflow:hidden
可恢复和其余浏览器同样的渲染。
方法2:
以毒攻毒。有时候,页面复杂,咱们不能给父级设置overflow:hidden
,怎么办呢?
杨过的情花剧毒怎么解的?断肠草啊,另外一种剧毒。这里也是相似。既然“穿越”的渲染问题是由3D transform变换产生的,那么,要解决此问题,咱们也可使用3D transform变换。
那具体该如何作呢?
我在“好吧,CSS3 3D transform变换,不过如此!”一文中就科普过z轴的概念。
咱们仔细观察下面这张效果截图:
咱们的红色条子在z轴位置0
处,对不对,因此才从图片的中心穿过。而z轴是咱们眼睛看屏幕这条轴,在z轴的值越大,就离用户的眼睛越近;值越小,里用户眼睛越小。所谓近大远小(若是指定了视角perspective),就是这么回事。
因此,咱们要想让红色条子覆盖在图片上,只要设置一个足够大的translateZ
值就能够,如100px
:
.bar { position: fixed; z-index: 99; /* 以毒攻毒 */ transform: translateZ(100px); }
结果:
咦,尴尬,好像仍是不够大,图片还有一点点位置在红色条的上面~~
赶快用120px
试试:
.bar { position: fixed; z-index: 99; /* 以毒攻毒 */ transform: translateZ(120px); }
结果:
喔噢,这下图片彻底被红色的长条子覆盖了,这下,全部浏览器的表现都是如出一辙的啦!