26
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Chrome の CSS transition がページロード時に動いてしまう問題の機序と対処

Last updated at Posted at 2019-06-14

TL;DR

外部 CSS を読み込んだら、何かしらスクリプトを走らせよう。

前置き

外部スタイルシートに CSS transition を記述した際、仕様上は初期状態への遷移は発生しないはずなのだけれど、Chrome だと、デフォルトのスタイルから初期状態への遷移が発生してしまう、という問題。

かなり以前から知られていた問題らしいのだけれど、未だに直っておらず、それぞれに対処法は考えられているものの、なぜそれで動くのかよくわからなかったので、少し追っかけてみた。

結果、全容を把握するに至らなかったのだけれど、おおよその機序と回避方法が分かったので、メモがてらに残しておく。

問題の発生する例

例えば、こんなスタイルシートがあって、

hoge.css
.anim {
    background-color: red;
    transition: background-color 5s ease-out 0s;
}
.anim:hover {
    background-color: blue;
}

こんな html を書く。

hoge.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <link rel="stylesheet" href="hoge.css">
    </head>
    <body>
        <p class="anim">hoge</p>
    </body>
</html>

最初は赤背景で、マウスオーバーしたら青に……というのを期待するのだけれど、
Chrome で実行すると、ページ読み込み時にデフォルト(透過)から赤への遷移アニメーションが挟まってしまう。

機序

どうやら Chrome さんは、外部スタイルシートを遅延解決しようとしているようで、
上記のような記述だとスタイルの適用が後回しにされる。
それが初期 DOM 構築後になると、新規にクラスが設定されたとして、遷移アニメーションが発火してしまう。

対処

初期 DOM 構築完了前に、外部スタイルシートを解決させる。
具体的には何かしらスクリプトを動かすだけで良い。
スクリプト実行前に、外部スタイルシートの解決を行ってくれる。

例えば以下のように。

hoge.html(改1)
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <link rel="stylesheet" href="hoge.css">
    </head>
    <body>
        <p class="anim">hoge</p>
        <script>console.log("ちゃんとスタイル適用してね。");</script>
    </body>
</html>

もちろん、link の直後でも良い。

hoge.html(改2)
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <link rel="stylesheet" href="hoge.css">
        <script>console.log("ちゃんとスタイル適用してね。");</script>
    </head>
    <body>
        <p class="anim">hoge</p>
    </body>
</html>

外部スタイルシートが複数あることを考えると、前者の body の最後に入れてしまう方法が汎用的でよい気がする。

なお、script 要素の中身は何でもいいが、空にするのはダメ(単にスキップされる)。
空白のみ、はアリだけれど、module bundler や minifier に消されてしまう可能性があるので注意。

追記: script 要素は外部スクリプトの読み込みでも大丈夫なようです。(コメント欄参照)

補遺

linkscript の前に置け、という対処方法が紹介されることもあった(し、誤りではない)けれど、link の前に script があること自体が問題を起こしているわけではない。

link の後に何かしら中身のある script を置く、ということが回避策になるようだ。

先人たち

https://qiita.com/yaegaki/items/46209320e7163cb638a9
https://intp.jp/?p=796
https://css-tricks.com/transitions-only-after-page-load/

26
17
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?