Edited at

from(0%) から to(100%) だけではアニメーションしないことがある場合の理解


作ったもの

CSSアニメーションを使い、キャレット(縦棒)っぽいものを作りました。

demo.gif


問題

visibility: hiddenvisible を繰り返すことで点滅を実現しようとしたのですが、以下の記述では点滅しませんでした。


css


@keyframes caret {
from { visibility: hidden; }
to { visibility: visible; }
}

.caret {
animation: caret 1s linear infinite;
}



起きていること

visibilityプロパティの値は0(hidden)と1(visible)しか存在しないことから、0%から100%に向けて徐々に変化することはしません。

下表のように1%の時点でvisibleになり、アニメーションが終了してしまいます。

%
visibility

0% (from)
hidden

1%
visible
この時点で値が切り替わる

2%
visible


100% (to)
visible


解決策


❶ 段階を踏ませる

:red_circle: 0〜50%ではhidden

:large_blue_circle: 51〜100%ではvisible

このように明示的に段階を踏ませることで、visibilityの値が一瞬で変わるのを防ぎ、アニメーションを継続させることができます。


css


@keyframes caret {
0% { visibility: hidden; }
50% { visibility: hidden; }
100% { visibility: visible; }
}

.caret {
animation: caret 1s linear infinite;
}


%
visibility

0% (from)
hidden

1%
hidden


50%
hidden

51%
visible
この時点で値が切り替わる


100% (to)
visible


❷ stepsを使う

animation-timing-function: steps(n) を指定することで、visibilityの値が一瞬で変わるのを防ぐことができます。

stepsについては、こちらの記事に詳しく書かれています。


css

@keyframes caret {

from { visibility: hidden; }
to { visibility: visible; }
}

.caret {
animation: caret 1s steps(2) infinite;
}



疑問点


css


@keyframes caret {
from { visibility: hidden; }
to { visibility: visible; }
}

.caret {
animation: caret 1s linear infinite;
}


Q. アニメーションは繰り返し実行されているのに、hidden状態が目視できるのは最初の1回だけなのはどうして?

(こちらについて@bosekiさんがコメントくださっています。とても感謝!)


すぺしゃるさんくす

同期のNBさんとAZちゃん