CSS

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

作ったもの

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

See the Pen JedJZa by ymmt (@ymmt1994) on CodePen.

問題

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ちゃん