薄荷新首頁上週五內測,花哥反饋在 MacBook Safari 瀏覽器下 滑鼠移動到第一個商品的時候後面幾個商品的文字會加粗。這是什麼鬼???
待我回到家開啟筆記本,滑鼠蹭蹭蹭的發現問題遠不止如此:
- Banner 以下的文字都會間歇性閃(chou)爍(feng)。
- 滑鼠移動到某個產品圖上,在該元素以後區域的文字也會閃爍,而之前的元素都沒問題。
通過現象可以觀察到文字閃爍基本和動畫有關,Banner 輪播圖用到了 transform: translate3d,產品展示圖縮放效果用到了transform: scale
那麼除了動畫以外影響字型渲染的CSS屬性還有這些:
font-style //字型樣式
font-variant //字型大小寫
font-weight //字型重量值
font-size //字型大小
font-family //字型型號
font-smoothing //字型平滑屬性
因為目前新版用到 BootStrap3,先確認下是自己的程式碼引發的問題還是 BootStrap3,帶著疑問去了躺 BootStrap3 官網,找到輪播圖的例子:
http://v3.bootcss.com/examples/carousel/
如果你在Mac Safari 開啟上面連結會發現輪播圖下方的文字都會隨著動畫而閃爍。
接下來分析是什麼原因導致了這個bug的出現,通過對比分析發現在 BootStrap3 中 container 和 row 元素都用到了 position:relative 屬性,而這兩個元素都是巢狀使用,那麼通過最簡程式碼來複現該問題:
html
<div class="box">
<p>CSS Animation triggers text rendering change in Safari</p>
</div>
<div class="animation"></div>
<div class="box">
<p>CSS Animation triggers text rendering change in Safari</p>
</div>
css
<style scoped="scoped">
.animation {
width: 100px;
height: 100px;
background-color: gray;
-webkit-transition:all 0.35s ease-in-out;
}
.animation:hover {
-webkit-transform: rotate(360deg);
}
.box, .box > p {
font-size: 20px;
position: relative;
}
</style>
上面的例子中,當滑鼠滑動到 animation 元素上,後面的 box 就會出現文字閃爍,而之前的元素沒有問題。
觸發 transform +transition 屬性的元素原本只會影響自身的字型渲染,從動畫開始到結束,分別經歷 Subpixel rendering -> Grayscale rendering -> Subpixel rendering,所以會出現閃爍現象,我們一般通過對自身設定 -webkit-backface-visibility: hidden 來解決。但是在Mac Safari 下還會影響其後面巢狀兩層以上CSS position取值為 relative、absolute 元素字型的渲染。
解決方案
// W3C官方已經廢棄該屬性
-webkit-font-smoothing: subpixel-antialiased
相關問題的回答
- How to prevent Webkit text rendering change during CSS
transition - Prevent flicker on webkit-transition of webkit-transform
- CSS Animation triggers text rendering change in Safari & Chrome (Webkit)
- Safari bug: text suddenly appears bold after css animation completes (antialiasing change)
相關問題的延伸閱讀