一個有趣的 Chrome 自動觸發 transition 轉場動畫 bug
備註:2024/2/16 發現這個 bug 終於已經被 Chrome 修復
某天我在製作 css transition 的時候意外發現,transition 效果居然在網頁載入的時候就自行觸發,效果如上面 iframe 嵌入所示,iframe 連結在此 reproduce link,而其中 html css 內容如下:
.foo {
box-sizing: border-box;
width: 280px;
padding: 20px;
font-size: 24px;
height: 210px;
display: flex;
align-items: center;
justify-content: center;
margin: 0;
background-color: #bb0000;
color: #ddd;
border: 20px solid #ddd;
border-radius: 1em;
transition-duration: 5s;
}
<html>
<head>
<meta charset="utf-8" />
<title>Chromium's Blink bug demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/img/bug.css" />
</head>
<body>
<p class="foo">如果在 Chrome 看到自動播放的動畫,代表這個 bug 還沒修好。</p>
<form hidden="">
<input />
</form>
</body>
</html>
而根據 css 的 spec ,transition 轉場動畫應該會在 css property value 發生變化的時候才會觸發
Normally when the value of a CSS property changes, the rendered result is instantly updated, with the affected elements immediately changing from the old property value to the new property value. This section describes a way to specify transitions using new CSS properties. These properties are used to animate smoothly from the old state to the new state over time.
可以觀察到自動觸發的 transition 動畫是從 user-agent stylesheet default 值變化成 css 設定值。本來懷疑是不是我在 js 的操作中有不小心讓瀏覽器 reflow 導致 transition 被觸發,但發現這樣的行為只有在 Chrome 瀏覽器上第一次載入頁面的時候才會發生,而載入後重新整理後這樣的行為就會自動消失了,需要過了一段時間重新整理才會重現,而且在其他瀏覽器都無法重現這樣的行為,因此才懷疑是不是 Chrome 的 bug。
經過一番努力 google 以後,在 stackoverflow 上看到這個問題,解答指出這是一個從 2012 躺到現在尚未修復 Chrome 的 bug ,觸發條件相當特別:
- 網頁上必須要有
<input />
tag - transition element style 必須是要靠 external css 如
<link rel="stylesheet" href="style.css">
- 頁面中沒有 inline script 如
<script></script>
這時候原本預期必須等到 style value 改變的才會觸發的轉場動畫,就會在 page load 的時候自動觸發。
reproduce 的頁面: https://lab.laukstein.com/bug/input
work around #
像我遇到的是 transform 類的 transition 被自動觸發,我使用的 work around 的解法就是調整 element 的初始位置讓一開始的 transform 為 0,就不會有位置上的轉場,或者讓頁面使用 inline style 或 inline script 讓其條件不滿足也可以修正這樣的行為。