CSS Animation triggers text rendering change in Safari

qieqing發表於2015-10-28

薄荷新首頁上週五內測,花哥反饋在 MacBook Safari 瀏覽器下 滑鼠移動到第一個商品的時候後面幾個商品的文字會加粗。這是什麼鬼???

待我回到家開啟筆記本,滑鼠蹭蹭蹭的發現問題遠不止如此:

  1. Banner 以下的文字都會間歇性閃(chou)爍(feng)。
  2. 滑鼠移動到某個產品圖上,在該元素以後區域的文字也會閃爍,而之前的元素都沒問題。

通過現象可以觀察到文字閃爍基本和動畫有關,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

相關問題的回答

相關問題的延伸閱讀

相關文章