WithCodeMedia-1-pc
previous arrowprevious arrow
next arrownext arrow

WithCodeMedia-1-sp
previous arrowprevious arrow
next arrownext arrow

【2026年版】CSS transitionの使い方|hoverの動きをなめらかにするコピペコード集

Webサイトのボタンやメニューをホバーしたとき、色がパッと瞬間的に切り替わるのではなく、なめらかに変化するサイトを見たことはないでしょうか。あの「ふわっと動く」感覚を実現しているのが、CSSの transition プロパティです。

transition はJavaScriptを一切使わず、CSSだけで要素の変化をアニメーション化できる非常に強力なプロパティです。2026年現在、モバイルファーストのWeb制作においてtransitionはもはや必須知識であり、ユーザー体験を大きく左右する要素となっています。

この記事では、transition の基本的な書き方から、ホバーエフェクト・ボタンアニメーション・カードのふわっと浮く演出など実用的なサンプルコードまで、コピペですぐ動くコードとともに徹底解説します。「なんとなく動いているけど仕組みがわかっていない」という方から、「timing-functionを使いこなしたい」上級者まで対応しています。

先に、この記事の結論をまとめます。

  • transitionproperty / duration / timing-function / delay の4値で構成され、変化前後に値が必要
  • :hover などの状態変化と組み合わせることで、色・大きさ・位置などをなめらかにアニメーションできる
  • transition: all は手軽だが、パフォーマンスに注意が必要(個別指定が推奨)
  • timing-function の使い分けとボタン・カードの実用パーツコードを記事内でコピペ提供
目次

CSS transitionとは?基本の仕組みを理解する

transition は、CSSプロパティの値が変化するときにアニメーションを付与するプロパティです。たとえば、通常時は背景色が白いボタンが、ホバー時に青くなる場合、transition がなければ瞬間的にパッと切り替わります。transition を指定すると、その変化が指定した時間をかけてなめらかに進行します。

重要なのは、transitionはCSSプロパティの値が変わる「前の状態」と「後の状態」の両方が必要だという点です。このポイントが、あとで紹介する「効かない原因」の筆頭となります。

transitionの基本構文|4つの値を理解する

transition プロパティは次の4つの値で構成されます。

/* 書式 */
transition: property duration timing-function delay;

/* 例 */
transition: background-color 0.3s ease 0s;
役割省略時のデフォルト
property変化させるCSSプロパティ名(all で全て)all
duration変化にかかる時間(秒/ミリ秒)0s
timing-function変化の速度カーブease
delay変化が始まるまでの待機時間0s

各サブプロパティとして個別に書くこともできます。

/* 個別サブプロパティで書く方法 */
.button {
  transition-property: background-color;
  transition-duration: 0.3s;
  transition-timing-function: ease;
  transition-delay: 0s;
}

hoverと組み合わせた基本実装|色・背景色をなめらかに変える

最もよく使われるパターンが、:hover と組み合わせた色変化です。transition は変化の起点となる要素(通常状態)に記述します。

背景色のなめらか変化(完全コード)

<!-- HTML -->
<button class="btn-color">ホバーしてね</button>
/* CSS */
.btn-color {
  background-color: #d16176;
  color: #fff;
  border: none;
  padding: 12px 32px;
  font-size: 16px;
  border-radius: 4px;
  cursor: pointer;
  /* transitionは通常状態に記述 */
  transition: background-color 0.3s ease;
}

.btn-color:hover {
  background-color: #51322b;
}

このコードをブラウザで開き、ボタンをホバーすると0.3秒かけてピンクからダークブラウンへと背景色がなめらかに変化します。

文字色のなめらか変化

.link-animated {
  color: #d16176;
  text-decoration: none;
  transition: color 0.2s ease;
}

.link-animated:hover {
  color: #51322b;
}

大きさ(scale)をなめらかに変える

transform: scale() と組み合わせると、要素をなめらかに拡大縮小できます。

<!-- HTML -->
<img class="img-zoom" src="sample.jpg" alt="サンプル画像" width="300" height="200">
/* CSS */
.img-zoom {
  display: block;
  transition: transform 0.3s ease;
}

.img-zoom:hover {
  transform: scale(1.05);
}

transform を使う場合、GPUレンダリングが適用されるためパフォーマンスが高く、実務で推奨されるアプローチです。

transition: all の使い方と注意点

transition: all を指定すると、変化するすべてのCSSプロパティに対してアニメーションが適用されます。記述量が少なくて済みますが、意図しないプロパティにもアニメーションが付いてしまうことがあります。

/* transition: all の例 */
.card {
  background-color: #fff;
  color: #333;
  padding: 16px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.card:hover {
  background-color: #EFBDB7;
  color: #51322b;
  box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}

注意点:

  • widthheight など、アニメーションが不要なプロパティにも適用されてしまう場合がある
  • ブラウザが全プロパティの変化を監視するためCPU負荷がかかる場合がある
  • パフォーマンスを重視する場合は、必要なプロパティだけを個別に指定するのが推奨

timing-function(速度カーブ)の違いと使い分け

timing-function は、変化の「加速・減速のカーブ」を指定する値です。同じ0.3秒でも、カーブが違うと動きの印象がまったく変わります。

動き用途例
ease(デフォルト)最初ゆっくり→中間速い→最後ゆっくり汎用。大半のホバーエフェクトに適する
ease-in最初ゆっくり→だんだん速くなる要素が消えていく・フェードアウト系
ease-out最初速い→だんだんゆっくりになる要素が飛び込んでくる・フェードイン系
ease-in-out最初と最後ゆっくり・中間速いスライダー・モーダル開閉など滑らかな動き
linear一定速度で変化ローディングバー・回転アニメーション
cubic-bezier()自由にカーブを定義バウンス・オーバーシュートなど独自の動き
steps()パラパラ漫画のように段階的に変化スプライトアニメーション

cubic-bezierで独自カーブを作る

cubic-bezier(x1, y1, x2, y2) を使うと、4つのコントロールポイントで独自の速度カーブを定義できます。cubic-bezier.com というビジュアルツールで視覚的に調整できます。

/* バウンス感のある動き */
.bounce-btn {
  transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.bounce-btn:hover {
  transform: scale(1.1);
}

/* スパッと素早く終わる動き */
.snappy-btn {
  transition: background-color 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}

複数プロパティを別々の時間で変化させる

複数のプロパティに対して、それぞれ異なる時間やカーブを指定したい場合は、カンマ区切りで複数のtransitionを指定します。

/* 複数プロパティに個別のtransitionを指定 */
.multi-transition {
  background-color: #d16176;
  color: #fff;
  transform: translateY(0);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

  /* カンマで区切って複数指定 */
  transition:
    background-color 0.2s ease,
    transform 0.3s ease-out,
    box-shadow 0.3s ease;
}

.multi-transition:hover {
  background-color: #51322b;
  transform: translateY(-4px);
  box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2);
}

この例では、背景色は0.2秒・transformは0.3秒・box-shadowは0.3秒と、それぞれ異なる時間でアニメーションさせています。細かい時間差を付けることで、動きに深みが生まれます。

実用パーツ集|コピペで使えるtransitionコード

1. 定番ホバーボタン(色変化+上に浮く)

<!-- HTML -->
<a href="#" class="cta-button">詳しく見る</a>
/* CSS */
.cta-button {
  display: inline-block;
  background-color: #d16176;
  color: #fff;
  text-decoration: none;
  padding: 14px 40px;
  border-radius: 30px;
  font-size: 16px;
  font-weight: bold;
  letter-spacing: 0.05em;
  transition:
    background-color 0.25s ease,
    transform 0.25s ease,
    box-shadow 0.25s ease;
}

.cta-button:hover {
  background-color: #51322b;
  transform: translateY(-3px);
  box-shadow: 0 8px 20px rgba(81, 50, 43, 0.3);
}

2. カードがふわっと浮くエフェクト

<!-- HTML -->
<div class="hover-card">
  <h3>カードタイトル</h3>
  <p>カードの説明テキストが入ります。</p>
</div>
/* CSS */
.hover-card {
  background: #fff;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition:
    transform 0.3s ease,
    box-shadow 0.3s ease;
  cursor: pointer;
}

.hover-card:hover {
  transform: translateY(-8px);
  box-shadow: 0 16px 32px rgba(0, 0, 0, 0.15);
}

3. テキストリンクの下線アニメーション

下線が左から右にスライドするエフェクトです。::after 擬似要素と組み合わせます。

<!-- HTML -->
<a href="#" class="underline-link">アニメーションリンク</a>
/* CSS */
.underline-link {
  position: relative;
  color: #d16176;
  text-decoration: none;
  display: inline-block;
}

.underline-link::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 0;
  height: 2px;
  background-color: #d16176;
  transition: width 0.3s ease;
}

.underline-link:hover::after {
  width: 100%;
}

4. ナビゲーションメニューのホバーエフェクト

<!-- HTML -->
<nav>
  <ul class="nav-list">
    <li><a href="#" class="nav-item">ホーム</a></li>
    <li><a href="#" class="nav-item">サービス</a></li>
    <li><a href="#" class="nav-item">会社概要</a></li>
    <li><a href="#" class="nav-item">お問い合わせ</a></li>
  </ul>
</nav>
/* CSS */
.nav-list {
  display: flex;
  list-style: none;
  gap: 8px;
  margin: 0;
  padding: 0;
}

.nav-item {
  display: block;
  padding: 10px 20px;
  color: #51322b;
  text-decoration: none;
  border-radius: 4px;
  background-color: transparent;
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}

.nav-item:hover {
  background-color: #EFBDB7;
  color: #51322b;
}

5. フォーム入力欄のフォーカスアニメーション

<!-- HTML -->
<input type="text" class="animated-input" placeholder="お名前を入力">
/* CSS */
.animated-input {
  width: 100%;
  padding: 12px 16px;
  border: 2px solid #ddd;
  border-radius: 6px;
  font-size: 16px;
  outline: none;
  box-sizing: border-box;
  transition:
    border-color 0.2s ease,
    box-shadow 0.2s ease;
}

.animated-input:focus {
  border-color: #d16176;
  box-shadow: 0 0 0 3px rgba(209, 97, 118, 0.2);
}

6. ハンバーガーメニューアイコンの変化アニメーション

<!-- HTML -->
<button class="hamburger" id="hamburger">
  <span class="bar"></span>
  <span class="bar"></span>
  <span class="bar"></span>
</button>
/* CSS */
.hamburger {
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.bar {
  display: block;
  width: 28px;
  height: 3px;
  background-color: #51322b;
  border-radius: 2px;
  transition:
    transform 0.3s ease,
    opacity 0.3s ease;
}

/* .open クラスが付いたときにバツ印に変化 */
.hamburger.open .bar:nth-child(1) {
  transform: translateY(9px) rotate(45deg);
}

.hamburger.open .bar:nth-child(2) {
  opacity: 0;
  transform: scaleX(0);
}

.hamburger.open .bar:nth-child(3) {
  transform: translateY(-9px) rotate(-45deg);
}

transitionとanimationの使い分け

transitionanimation@keyframes)はどちらもCSSアニメーションの手段ですが、用途が異なります。適切に使い分けることで、メンテナンス性の高いコードが書けます。

比較項目transitionanimation(@keyframes)
発火のタイミング状態変化(:hover, :focusなど)が必要ページロード時など自動再生が可能
繰り返し基本的に1回のみ無限ループ(infinite)が可能
中間点の設定開始と終了の2点のみ0%〜100%で複数の中間点を設定可能
記述の簡便さシンプル(1行〜2行)@keyframesとanimationの両方が必要
適した用途ホバー・フォーカス・クリック時の変化ローディング・常時アニメーション・複雑な動き

まとめると、ユーザーの操作に連動した変化には transition、それ以外の自動再生・繰り返しアニメーションには animation が適しています。

/* transition が向いている例:ホバーで色が変わるボタン */
.btn {
  background-color: #d16176;
  transition: background-color 0.3s ease;
}
.btn:hover {
  background-color: #51322b;
}

/* animation が向いている例:常にくるくる回るローディングアイコン */
.spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #EFBDB7;
  border-top-color: #d16176;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

transitionが効かないよくある失敗と原因

初心者がつまずきやすいポイントをまとめます。transitionが動かないときは、まずこれらを確認してください。

失敗1:変化前後の値が設定されていない

transitionは「A(変化前)からB(変化後)」への移行をアニメーションします。どちらかの値がなければアニメーションしません。

/* NG例:通常状態にbackground-colorがない */
.btn {
  transition: background-color 0.3s ease;
  /* background-colorの初期値がないため動かない場合がある */
}
.btn:hover {
  background-color: #d16176;
}

/* OK例:通常状態にも値を明示する */
.btn {
  background-color: transparent; /* または具体的な色 */
  transition: background-color 0.3s ease;
}
.btn:hover {
  background-color: #d16176;
}

失敗2:display:noneとtransitionは相性が悪い

display: none から display: block への変化はtransitionでアニメーションできません。要素の表示・非表示のアニメーションには opacityvisibility の組み合わせを使います。

/* NG例:display:none/blockのtransitionは動かない */
.menu {
  display: none;
  transition: display 0.3s ease; /* 効かない */
}
.menu.open {
  display: block;
}

/* OK例:opacity + visibility で代替する */
.menu {
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 0.3s ease,
    visibility 0.3s ease;
}
.menu.open {
  opacity: 1;
  visibility: visible;
}

失敗3:height: auto へのtransitionは動かない

height: 0 から height: auto への変化はtransitionできません。max-height を代わりに使うか、JavaScriptでpx値を動的に取得する方法を使います。

/* NG例 */
.accordion-content {
  height: 0;
  overflow: hidden;
  transition: height 0.3s ease; /* height:autoには効かない */
}
.accordion-content.open {
  height: auto; /* 動かない */
}

/* OK例:max-heightを使う(余裕のある値を設定する) */
.accordion-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.5s ease;
}
.accordion-content.open {
  max-height: 500px; /* コンテンツの最大高さより大きい値 */
}

失敗4:transitionが変化後の要素に書かれている

transitionは通常状態の要素に書くのが基本です。:hover側に書くと、「ホバーしたとき」のアニメーションは動いても「ホバーを外したとき」はアニメーションなしで瞬間的に戻ります。

/* △ 片方向だけアニメーションする(戻りは瞬間) */
.btn {
  background-color: #d16176;
}
.btn:hover {
  background-color: #51322b;
  transition: background-color 0.3s ease; /* ホバー時のみ効く */
}

/* OK:両方向ともなめらかにアニメーションする */
.btn {
  background-color: #d16176;
  transition: background-color 0.3s ease; /* 通常状態に書く */
}
.btn:hover {
  background-color: #51322b;
}

失敗5:transformとtransitionの両方が必要なのにどちらかが欠けている

/* NG例:transitionなしではパッと移動するだけ */
.card {
  /* transitionがない */
}
.card:hover {
  transform: translateY(-8px);
}

/* OK例 */
.card {
  transition: transform 0.3s ease;
}
.card:hover {
  transform: translateY(-8px);
}

パフォーマンスを意識したtransitionの書き方

transitionはブラウザのレンダリングパイプラインに影響します。パフォーマンスが高い順に、以下のプロパティのアニメーションが推奨されます。

パフォーマンスプロパティ理由
高い(推奨)transform, opacityGPUコンポジットレイヤーで処理される
中程度color, background-color, box-shadowペイントが発生するが影響は小さい
低い(注意)width, height, margin, padding, top, leftレイアウト再計算(リフロー)が発生する

要素を動かしたいときは margintop/left ではなく transform: translate() を使いましょう。視覚的な結果は同じでも、パフォーマンスに大きな差が出ます。

/* NG例:marginのアニメーション(リフロー発生) */
.card {
  margin-top: 0;
  transition: margin-top 0.3s ease;
}
.card:hover {
  margin-top: -8px;
}

/* OK例:transformのアニメーション(GPUで処理) */
.card {
  transform: translateY(0);
  transition: transform 0.3s ease;
}
.card:hover {
  transform: translateY(-8px);
}

will-changeでさらにパフォーマンスを最適化する

will-change プロパティを使うと、ブラウザに「このプロパティがアニメーションされる予定」という事前情報を与え、処理を最適化できます。ただし、乱用するとメモリ使用量が増えるため、アニメーションが多い要素に限定して使用します。

/* transformとopacityのアニメーションを最適化 */
.animated-card {
  will-change: transform, opacity;
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.animated-card:hover {
  transform: translateY(-8px);
  opacity: 0.9;
}

レスポンシブデザインでのtransition考慮

モバイル端末ではホバー状態が発生しない(タップ)ため、ホバーエフェクトがスマホで意図せず残留する問題があります。@media (hover: hover) を使うことで、ホバーが有効な端末にだけエフェクトを適用できます。

/* ホバーが有効な環境でのみエフェクトを適用 */
@media (hover: hover) {
  .btn:hover {
    background-color: #51322b;
    transform: translateY(-3px);
  }

  .card:hover {
    transform: translateY(-8px);
    box-shadow: 0 16px 32px rgba(0, 0, 0, 0.15);
  }
}

/* transitionは常に記述(フォーカス時にも効くため) */
.btn {
  background-color: #d16176;
  transition: background-color 0.25s ease, transform 0.25s ease;
}

.card {
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

よくある質問(FAQ)

Q1. transitionはIE(Internet Explorer)でも使えますか?

IE 10・11ではベンダープレフィックスなしで transition が使えます。ただし、IE 9以下はtransitionに対応していません。2026年現在、Microsoftは2022年にIEのサポートを終了しており、IE対応は実務上ほぼ不要になっています。主要ブラウザ(Chrome・Firefox・Safari・Edge)では完全に動作します。

Q2. transitionとtransformは何が違いますか?

transition は「変化をなめらかにする仕組み」で、transform は「要素の移動・回転・拡大縮小を指定するプロパティ」です。別々の役割を持ちます。「transformをtransitionでアニメーションする」という形で組み合わせて使います。transition単体では何も変化せず、変化させるプロパティ(colorやtransformなど)が別途必要です。

Q3. transitionにdurationを指定しなかったらどうなりますか?

durationのデフォルト値は 0s(0秒)です。省略した場合は0秒で変化が完了するため、アニメーションなし(瞬間的な切り替わり)と同じ見た目になります。アニメーションを確認したい場合は必ずdurationを指定してください(例:0.3s)。

Q4. CSS transitionだけでモーダルの表示・非表示アニメーションを作れますか?

はい、作れます。ただし、display: nonedisplay: block の切り替えではtransitionが効かないため、opacityvisibility の組み合わせを使います。モーダルを非表示にするとき opacity: 0; visibility: hidden;、表示するとき opacity: 1; visibility: visible; とし、両方にtransitionを設定します。表示・非表示の切り替え自体はJavaScriptでクラスの付け外しを行います。

Q5. transitionのdelayはどのような場面で使いますか?

delayは「変化が始まるまでの待機時間」です。主な活用例は、複数要素を少しずつ時間差で表示するスタガーアニメーションや、ドロップダウンメニューをホバー後0.2秒待ってから開く(誤ホバー防止)用途などです。以下の例は、リストの各アイテムを時間差で表示するパターンです。

/* 各リストアイテムに時間差でアニメーション */
.list-item {
  opacity: 0;
  transform: translateY(20px);
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.list-item.visible {
  opacity: 1;
  transform: translateY(0);
}

.list-item:nth-child(1) { transition-delay: 0s; }
.list-item:nth-child(2) { transition-delay: 0.1s; }
.list-item:nth-child(3) { transition-delay: 0.2s; }
.list-item:nth-child(4) { transition-delay: 0.3s; }
.list-item:nth-child(5) { transition-delay: 0.4s; }

関連記事

CSS・Webデザイン実装の総まとめ

CSSの実装テクニックを「レイアウト・装飾・アニメーション・基礎・トラブル解決」の目的別に探せる総まとめページを用意しています。実装で迷ったときの索引としてどうぞ。

あわせて読みたい:CSS @keyframesの使い方|アニメーションの作り方 / CSSフェードインの実装方法|スクロールでふわっと表示

WithCodeを体験できる初級コース公開中!

WithCodeを体験できる初級コース公開中!

初級コース(¥49,800)が完全無料に!

  • 期間:1週間
  • 学習内容:
    ロードマップ/基礎知識/環境構築/HTML/CSS/LP・ポートフォリオ作成
    正しい学習方法で「確かな成長」を実感できるカリキュラム。

副業・フリーランスが主流になっている今こそ、自らのスキルで稼げる人材を目指してみませんか?

未経験でも心配することはありません。初級コースを受講される方の大多数はプログラミング未経験です。まずは無料カウンセリングで、悩みや不安をお聞かせください!

この記事を書いた人

WithCodeでWeb制作を習得後、フリーランスエンジニアとして活動。HTML/CSS・JavaScript・WordPress案件を中心に年間20件以上の制作実績を持つ。「難しい技術をわかりやすく」をモットーに、初心者〜中級者向けの技術記事を執筆。副業・フリーランス独立を目指す方に向けた情報発信に注力している。

– service –WithGroupの運営サービス

  • WithCode
    - ウィズコード -

    スクール

    「未経験」から
    現場で通用する
    スキルを身に付けよう!

    詳細はこちら
  • WithFree
    - ウィズフリ -

    実案件サポート

    制作会社のサポート下で
    実務経験を積んでいこう!

    詳細はこちら

公式サイト より
今すぐ
無料カウンセリング
予約!

目次