とほほのCSSトランジション入門

目次

CSSトランジションとは

トランジションとアニメーションの違い

CSSの類似機能に アニメーション(animation) がありますが、下記のような差異があります。

トランジション(transition)
アニメーション(animation)

簡単な使用例(transition)

ホバー(:hover)スタイルを指定すると、マウスを乗せた時に大きさや色や太さが変化しますが一瞬で変化してしまいます。

CSS
.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;
}
HTML
<div class="my-transition-example"></div>
表示

スタイルに transition を加えることで指定した時間(下記の例では 0.3秒)の間に徐々に変化するトランジションを設定することができます。

CSS
.my-transition-example {
  /* 変更前のスタイル */
  transition: .3s;
}
.my-transition-example:hover {
  /* 変更後のスタイル */
}
表示

transition を変化前のスタイルに指定すると、変更前の状態から変更後の状態に遷移するタイミングと、変更後の状態から変更前の状態に戻るタイミングの両方でトランジションがかかります。変更後のスタイルに指定すると遷移時にはトランジションせず、戻る時のみトランジションします。変更前と変更後のスタイルに指定すると、遷移時は変更後のスタイルに設定したトランジションが、戻る時は変更前のスタイルに設定したトランジションがかかります。

トランジション可能なプロパティ

トランジション可能なプロパティには下記などがあります。

width, height, color, opacity, transform, translate, scale, rotate, margin, padding, background-color, border-color, border-width, font-size, ...

background-image など表示する・表示しないの2値しか持たないような離散値プロパティに関しては 離散値に対するトランジション で説明します。特に visibility:hiddendisplay:none は特別な動作となります。

また、height:auto のような auto 値に対しても通常はトランジションが効きません。対策については auto値に対するトランジション で説明します。

トランジションのトリガー

トランジションのトリガーには下記などがあります。

マウスを乗せた時(:hover)

CSS
.my-hover-example {
  padding: .5rem;
  width: 100px;
  background-color: #fcc;
  transition: .3s;
}
.my-hover-example:hover {
  width: 300px;
  background-color: #ccf;
}
HTML
<div class="my-hover-example">Test</div>
表示
Test

フォーカスがあたった時(:focus)

CSS
.my-focus-example {
  width: 100px;
  transition: .3s;
}
.my-focus-example:focus {
  width: 140px;
}
HTML
<input type="text" class="my-focus-example">
<input type="text" class="my-focus-example">
<input type="text" class="my-focus-example">
表示

ラジオボタンがチェックされた時(:checked)

CSS
.my-checked-example {
  width: 15px;
  height: 15px;
  transition: .3s;
}
.my-checked-example:checked {
  width: 30px;
  height: 30px;
}
HTML
<input type="checkbox" class="my-checked-example">
表示

クラスが追加・削除された時

JavaScript で要素にクラスを追加するタイミング、削除するタイミングでトランジションをかけることができます。toggle() はクラスリストにクラスが無ければ追加し、あれば削除するメソッドです。

CSS
.my-add-remove-example {
  padding: .5rem;
  width: 100px;
  background-color: #fcc;
  transition: .3s;
}
.my-add-remove-example.active {
  width: 300px;
  background-color: #ccf;
}
HTML
<button id="add-remove-btn">Add / Remove</button><br><br>
<div id="add-remove-example" class="my-add-remove-example">Test</div>
JavaScript
document.getElementById("add-remove-btn").addEventListener("click", (e) => {
  document.getElementById("add-remove-example").classList.toggle("active");
});


Test

JavaScript不要の任意タイミング

JavaScript 無しで任意のタイミングでトランジションをかけるテクニックとして、一般兄弟セレクタ(~) を用いてチェックボックスのチェックが On/Off になった時に、兄弟要素に対してトランジションをかける技があります。チェックボックスは display: none で消すこともできます。

CSS
#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%;
}
HTML
<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-durationtransition-delaytransition-propertytransition-timing-function プロパティを一括指定するショートハンドプロパティです。

時間(transition-duration)

時間(transition-duration) は上記の例でも指定してきたトランジションにかける時間です。

CSS
.my-transition-example {
  ...
  transition: .3s;
}

開始遅延時間(transition-delay)

開始遅延時間(transition-delay)を指定するとマウスを乗せても 2秒 待ってからトランジションが始まります。

CSS
.my-transition-example {
  ...
  transition: .3s 2s;
}
表示
Test

プロパティ指定(transition-property)

下記の様に時間と CSSプロパティ名(transition-property)のペアをカンマ(,)区切りで複数記述すると、width は 0.3秒で変化、background-color は 5秒で変化など、プロパティ毎に時間や開始タイミングを変更することができます。

CSS
.my-transition-example {
  ...
  transition: .3s width, 5s background-color;
}
表示
Test

タイミング関数(transition-timing-function)

transition には transition-timing-function で指定可能なタイミング関数を設定することができます。それぞれのタイミング関数の詳細は animation-timing-function を参照してください。

CSS
.my-transition-example {
  ...
  transition: 2s ease;
}
表示
linear
linear(0, .1, 1)
ease
ease-in
ease-out
ease-in-out
step-start
step-end
steps
cubic-bezier

離散値に対するトランジション(transition-behavior, @starting-style, overlay)

background-image などの離散値に適用する例

width, height, opacity などの連続値を持つプロパティは連続的にトランジションすることができますが、background-image などのように表示する/しないの2値しかない離散値のプロパティは遷移が始まるタイミングで表示/非表示が切り替わります。

background-image: none

transition-behavior: allow-discrete で離散値に対してもトランジションを有効にすることでこのタイミングを進捗率 50% のタイミングにずらすことができます。

CSS
#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;
}
background-image: none

visibility: hidden に適用する例

離散値の中でも visibility:hiddendisplay:none は特別な動作となります。通常の離散値では移行の遷移が始まる瞬間と戻る遷移が始まる瞬間に切り替わりますが、visibility:hidden だけは戻る遷移が完了したタイミングで切り替わります。下記のような例では @starting-style は不要です。

visibility: hidden

display: none に適用する例

display:none の要素に対してはトランジション自体が効きません。瞬間的に切り替わってしまいます。

display: none

transition-behavior:allow-discrete で離散値に対するトランジションを有効にし、@starting-style で初期値を指定することにより、display:none の要素に対してもトランジションをかけることができるようになります。

CSS
#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;
  }
}
display: none

popover に適用する例

上記の display:none 要素に対してトランジションを有効にする術は popover のように自動的に display:none と 非none が切り替わる要素に対しても有効です。

CSS
[popover] {
  transform: scaleX(0);
  transition: .3s;
  transition-behavior: allow-discrete;
}
[popover]:popover-open {
  transform: scaleX(1);
  @starting-style {
    transform: scaleX(0);
  }
}
HTML
<button popovertarget="my-popover">Show popover</button>
<div popover="auto" id="my-popover">Popover Transition Example</div>
表示
Popover Transition Example

display:none 要素に対するトランジション設定で、各プロパティ毎にトランジションを設定している場合は、displayoverlay にもトランジション設定を行う必要があります。

[popover] {
  transition:
    transform .3s,
    opacity .3s,
    display .3s allow-discrete,
    overlay .3s allow-discrete;
}

<dialog>に適用する例

display:none が切り替わる <dialog> も同様に transition-behavior: allow-discrete@starting-style で初期値を指定することによりトランジションをかけることができるようになります。

CSS
dialog {
  transform: scaleX(0);
  transition: .3s;
  transition-behavior: allow-discrete;
}
dialog[open] {
  transform: scaleX(1);
  @starting-style {
    transform: scaleX(0);
  }
}
表示
Dialog Transition Example

auto に対するトランジション

height:auto のような auto 値に対しては通常ではトランジションは効きません。

CSS
#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;
}
AAA
AAA
AAA

auto 値に対しては calc-size() を用いることにより、トランジションの対象にすることができるようになります。

CSS
#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);
}
AAA
AAA
AAA

ページ間トランジション(@view-transition, view-transition-name)

あるページから別のページに遷移する際に、ページ内の画像などの要素に対してページ間トランジションすることが可能となりました。詳細は @view-transition のサンプルを参照してください。