【CSS】特定のtransitionを共通的に設定したかった

テーマカラーを実現するために、テーマ切替時にはcssの色変数の値を書き換えるようにしています。

そのときに背景色も文字色も同時に変数を変更しているので、期待値としては実際に表示される各色も同タイミングで変更されるものだと思っていました。

でも実際には実装方法によってはタイミングがずれるらしいです。

現象

transitionで設定したものの変化にdelayがかかっている

サンプルCSSは下記になります。

:root {
    --text: white; // 色変更処理でblackになる
    --bg: black; // 色変更処理でwhiteになる
}

* {
    transition: inherit;
}

html {
    transition: background-color 0.2s, color 0.2s;
}

body {
    background-color: var(--bg);
}

p {
    color: var(--text);
 }

深いところにある要素の変化が遅い?

上記の動画を見てもわかるように、文字色が単純に遅い……というわけでもなく、同じ文字色でも場所によって開始タイミングがずれています。 上のFURUTSUBAKIとしたのカードの部分ですね。 何なら背景色も左右で微妙にずれています。

指定方法は特に違いはないので、差異があるとしたら遅い部分は階層が深いということです。

てことで検証

.text {
    color: var(--color-theme-text-primary);
}
<div class="text">浅い文字</div>
<div class="text"><div><div><div><div><div><div><div>深い文字</div></div></div></div></div></div></div></div>

こんな階層のことなる文字を用意して試してみました。

結果はごらんの有様。 読みどおり、階層が深いと色の変化の開始タイミングが遅くなっています。

というかdurationも明らかに長い。

原因

色変数で管理しているため、色を指定する箇所はcolor: var(--text);などでcss変数を設定するだけでテーマ切り替えに対応できるようにしています。

ただそのままだとtransitionが効かないため、色変数を使用している箇所に毎回transitionを記載しないといけなくなり面倒だなぁと思って下記の設定をしました。

* {
    transition: inherit;
}

親のtransitionの値を使用するってことですね。

ただどうやらこの書き方をすると、colorなどのtransitionの対象になっているプロパティが無い階層でもすべての階層ごとにtransitionの処理が入ってしまうらしく、階層 x duration分、実際に変化が起こっている要素の開始タイミングが遅れるようです。

なので素直にcolor: var(--text);を記載したら同じところにtransition: color 0.2s;を記載する必要がありそうです。

対処策

記事を書いてて思ったのですが、そもそもcolorが指定されている要素直下にテキストがないのが行けないのではと思って試してみました。

<div class="text">浅い文字</div>
<div><div><div><div><div><div><div><div class="text">深い文字(color指定の直下に文字を記載)</div></div></div></div></div></div></div></div>

微妙にずれていますが、著しいずれはなくなってますね。

ちなみにinheritを使用せずに各要素に直接transitionを指定すればズレは起きません。

* {
    // transition: inherit;
}

.text {
    transition: color 0.2s;
    color: var(--color-theme-text-primary);
}

結論

transitionを共通的に設定するは無理っぽい

コメント

コメントは承認制となっていますので、コメントを頂いても直ぐには表示されません。

なお、不適切な内容(スパムや悪意ある内容等)のコメントは公開されませんので、ご了承ください。

名もなき名無しさん
内容