とほほのCSSトランジション入門
- CSSトランジションとは
- 簡単な使用例(transition)
- トランジション可能なプロパティ
- トランジションのトリガー
- 詳細設定
- 離散値に対するトランジション(transition-behavior, @starting-style, overlay)
- auto に対するトランジション
- ページ間トランジション(@view-transition, view-transition-name)
CSSトランジションとは
- 英語の transition は 遷移 という意味を持ちます。
- マウスを乗せた(:hover)、フォーカスがあたった(:focus) などの状態変化が発生した際にアニメーションを行うCSS機能です。
トランジションとアニメーションの違い
CSSの類似機能に アニメーション(animation) がありますが、下記のような差異があります。
- トランジション(transition)
-
- 基本的にはマウスを乗せた時(:hover)、フォーカスした時(:focus)など一時的な状態変化に対してアニメーションを行うものです。
- ループしません。
- その状態に遷移する際のアニメーションと、その状態から戻る際のアニメーションがあります。
- A → B、B → A という単純な動きとなります。A → B → C → D といった複雑な動きはできません。
- アニメーション(animation)
-
- 基本的にはページを開いたときから繰り返しアニメーションを行うことが多いです。
- ループさせることができます。
- その状態になる、その状態に戻るという概念はありません。
- A → B → C → D など複雑なアニメーション遷移を行うことができます。
簡単な使用例(transition)
ホバー(:hover)スタイルを指定すると、マウスを乗せた時に大きさや色や太さが変化しますが一瞬で変化してしまいます。
.my-transition-example {
width: 40px;
height: 20px;
background-color: #fcc;
border: 1px solid #c99;
}
.my-transition-example:hover {
width: 80px;
height: 40px;
background-color: #ccf;
border: 5px solid #99c;
}
<div class="my-transition-example"></div>
スタイルに transition を加えることで指定した時間(下記の例では 0.3秒)の間に徐々に変化するトランジションを設定することができます。
.my-transition-example {
/* 変更前のスタイル */
transition: .3s;
}
.my-transition-example:hover {
/* 変更後のスタイル */
}
transition を変化前のスタイルに指定すると、変更前の状態から変更後の状態に遷移するタイミングと、変更後の状態から変更前の状態に戻るタイミングの両方でトランジションがかかります。変更後のスタイルに指定すると遷移時にはトランジションせず、戻る時のみトランジションします。変更前と変更後のスタイルに指定すると、遷移時は変更後のスタイルに設定したトランジションが、戻る時は変更前のスタイルに設定したトランジションがかかります。
トランジション可能なプロパティ
トランジション可能なプロパティには下記などがあります。
background-image など表示する・表示しないの2値しか持たないような離散値プロパティに関しては 離散値に対するトランジション で説明します。特に visibility:hidden と display:none は特別な動作となります。
また、height:auto のような auto 値に対しても通常はトランジションが効きません。対策については auto値に対するトランジション で説明します。
トランジションのトリガー
トランジションのトリガーには下記などがあります。
マウスを乗せた時(:hover)
.my-hover-example {
padding: .5rem;
width: 100px;
background-color: #fcc;
transition: .3s;
}
.my-hover-example:hover {
width: 300px;
background-color: #ccf;
}
<div class="my-hover-example">Test</div>
フォーカスがあたった時(:focus)
.my-focus-example {
width: 100px;
transition: .3s;
}
.my-focus-example:focus {
width: 140px;
}
<input type="text" class="my-focus-example"> <input type="text" class="my-focus-example"> <input type="text" class="my-focus-example">
ラジオボタンがチェックされた時(:checked)
.my-checked-example {
width: 15px;
height: 15px;
transition: .3s;
}
.my-checked-example:checked {
width: 30px;
height: 30px;
}
<input type="checkbox" class="my-checked-example">
クラスが追加・削除された時
JavaScript で要素にクラスを追加するタイミング、削除するタイミングでトランジションをかけることができます。toggle() はクラスリストにクラスが無ければ追加し、あれば削除するメソッドです。
.my-add-remove-example {
padding: .5rem;
width: 100px;
background-color: #fcc;
transition: .3s;
}
.my-add-remove-example.active {
width: 300px;
background-color: #ccf;
}
<button id="add-remove-btn">Add / Remove</button><br><br> <div id="add-remove-example" class="my-add-remove-example">Test</div>
document.getElementById("add-remove-btn").addEventListener("click", (e) => {
document.getElementById("add-remove-example").classList.toggle("active");
});
JavaScript不要の任意タイミング
JavaScript 無しで任意のタイミングでトランジションをかけるテクニックとして、後続兄弟結合子(~) を用いてチェックボックスのチェックが On/Off になった時に、兄弟要素に対してトランジションをかける技があります。チェックボックスは display: none で消すこともできます。
#page {
border: 1px solid #999;
overflow: hidden;
box-sizing: border-box;
}
#menu {
width: 5rem;
padding: .5rem;
background-color: #ddd;
}
#menu-switch {
/* display: none; */ /* チェックボックスを消したいとき */
}
#menu-switch ~ #menu {
translate: -100%;
transition: .3s;
}
#menu-switch:checked ~ #menu {
translate: 0%;
}
<div id="page">
<input type="checkbox" id="menu-switch"><label for="menu-switch">メニュー</label>
<div id="menu">
<div>メニュー#1</div>
<div>メニュー#2</div>
<div>メニュー#3</div>
</div>
</div>
詳細設定
transition は、transition-duration、transition-delay、transition-property、transition-timing-function プロパティを一括指定するショートハンドプロパティです。
時間(transition-duration)
時間(transition-duration) は上記の例でも指定してきたトランジションにかける時間です。
.my-transition-example {
...
transition: .3s;
}
開始遅延時間(transition-delay)
開始遅延時間(transition-delay)を指定するとマウスを乗せても 2秒 待ってからトランジションが始まります。
.my-transition-example {
...
transition: .3s 2s;
}
プロパティ指定(transition-property)
下記の様に時間と CSSプロパティ名(transition-property)のペアをカンマ(,)区切りで複数記述すると、width は 0.3秒で変化、background-color は 5秒で変化など、プロパティ毎に時間や開始タイミングを変更することができます。
.my-transition-example {
...
transition: .3s width, 5s background-color;
}
タイミング関数(transition-timing-function)
transition には transition-timing-function で指定可能なタイミング関数を設定することができます。それぞれのタイミング関数の詳細は animation-timing-function を参照してください。
.my-transition-example {
...
transition: 2s ease;
}
離散値に対するトランジション(transition-behavior, @starting-style, overlay)
background-image などの離散値に適用する例
width, height, opacity などの連続値を持つプロパティは連続的にトランジションすることができますが、background-image などのように表示する/しないの2値しかない離散値のプロパティは遷移が始まるタイミングで表示/非表示が切り替わります。
transition-behavior: allow-discrete で離散値に対してもトランジションを有効にすることでこのタイミングを進捗率 50% のタイミングにずらすことができます。
#cb2 ~ #ex2 {
background-color: #fcc;
width: 100px;
height: 25px;
transition: 2s;
transition-behavior: allow-discrete;
}
#cb2:checked ~ #ex2 {
width: 500px;
background-image: url(../image/ki4.gif);
background-size: 25px 25px;
}
visibility: hidden に適用する例
離散値の中でも visibility:hidden と display:none は特別な動作となります。通常の離散値では移行の遷移が始まる瞬間と戻る遷移が始まる瞬間に切り替わりますが、visibility:hidden だけは戻る遷移が完了したタイミングで切り替わります。下記のような例では @starting-style は不要です。
display: none に適用する例
display:none の要素に対してはトランジション自体が効きません。瞬間的に切り替わってしまいます。
transition-behavior:allow-discrete で離散値に対するトランジションを有効にし、@starting-style で初期値を指定することにより、display:none の要素に対してもトランジションをかけることができるようになります。
#cb5 ~ #ex5 {
background-color: #fcc;
width: 0px;
height: 25px;
display: none;
transition: 1s;
transition-behavior: allow-discrete;
}
#cb5:checked ~ #ex5 {
width: 500px;
display: block;
@starting-style {
width: 0px;
}
}
popover に適用する例
上記の display:none 要素に対してトランジションを有効にする術は popover のように自動的に display:none と 非none が切り替わる要素に対しても有効です。
[popover] {
transform: scaleX(0);
transition: .3s;
transition-behavior: allow-discrete;
}
[popover]:popover-open {
transform: scaleX(1);
@starting-style {
transform: scaleX(0);
}
}
<button popovertarget="my-popover">Show popover</button> <div popover="auto" id="my-popover">Popover Transition Example</div>
display:none 要素に対するトランジション設定で、各プロパティ毎にトランジションを設定している場合は、display と overlay にもトランジション設定を行う必要があります。
[popover] {
transition:
transform .3s,
opacity .3s,
display .3s allow-discrete,
overlay .3s allow-discrete;
}
<dialog>に適用する例
display:none が切り替わる <dialog> も同様に transition-behavior: allow-discrete と @starting-style で初期値を指定することによりトランジションをかけることができるようになります。
dialog {
transform: scaleX(0);
transition: .3s;
transition-behavior: allow-discrete;
}
dialog[open] {
transform: scaleX(1);
@starting-style {
transform: scaleX(0);
}
}
auto に対するトランジション
height:auto のような auto 値に対しては通常ではトランジションは効きません。
#acc-cb1 ~ #acc-content1 {
overflow: hidden;
padding: 0 .2rem;
width: 5rem;
height: 0;
background-color: #ddd;
transition: .3s;
}
#acc-cb1:checked ~ #acc-content1 {
height: auto;
}
auto 値に対しては calc-size() を用いることにより、トランジションの対象にすることができるようになります。
#acc-cb2 ~ #acc-content2 {
overflow: hidden;
padding: 0 .2rem;
width: 5rem;
height: 0;
background-color: #ddd;
transition: .3s;
}
#acc-cb2:checked ~ #acc-content2 {
height: auto; /* 未対応ブラウザへの配慮 */
height: calc-size(auto, size);
}
ページ間トランジション(@view-transition, view-transition-name)
あるページから別のページに遷移する際に、ページ内の画像などの要素に対してページ間トランジションすることが可能となりました。詳細は @view-transition のサンプルを参照してください。