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); }
結果:
喔噢,這下圖片徹底被紅色的長條子覆蓋了,這下,全部瀏覽器的表現都是如出一轍的啦!