コピペで使える滑らかなCSSアニメーションの完成形4選
すぐ使いたい場合は、まず transform と opacity を中心にした短いアニメーション から入るのが安全です。理由は、レイアウトを崩しにくく、見た目の変化も小さくまとめやすいからです。ここでは読み込み時のフェード、ボタンの浮き上がり、画像のズーム、通知バッジの点滅という、使う場面が明確な4例を先に出します。先に完成形を触ってから、次の章で「なぜ滑らかに見えるのか」を押さえる流れにすると理解しやすくなります。
以下のコードはすべて最小構成です。HTML と CSS を分けてそのまま置けば検証できます。まずは動きを確認し、そのあとで duration、translate、scale の値だけを少しずつ変えると、不自然な動きになりにくいです。
読み込み時にふわっと上がるフェードアップ
導入見出し
少し下から上へ移動しながら表示されます。
<section class="fade-up-box">
<h3 class="fade-up-box__title">導入見出し</h3>
<p class="fade-up-box__text">少し下から上へ移動しながら表示されます。</p>
</section>
.fade-up-box {
padding: 24px;
border-radius: 16px;
background: #282828;
animation: fadeUp 0.6s ease-out both;
}
.fade-up-box__title {
margin: 0 0 12px;
}
.fade-up-box__text {
margin: 0;
}
@keyframes fadeUp {
from {
opacity: 0;
transform: translateY(16px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
translateY(16px) のように移動量を小さくすると、登場演出が主張しすぎません。LPや記事一覧の見出しに向いています。
ボタンを少し浮かせるホバー演出
<a class="lift-button" href="#">詳細を見る</a>
.lift-button {
display: inline-block;
padding: 12px 20px;
border-radius: 999px;
background: #0078d4;
color: #ffffff;
text-decoration: none;
transform: translateY(0);
transition: transform 0.25s ease, box-shadow 0.25s ease;
box-shadow: 0 8px 16px rgba(0, 120, 212, 0.18);
}
.lift-button:hover,
.lift-button:focus-visible {
transform: translateY(-3px);
box-shadow: 0 14px 24px rgba(0, 120, 212, 0.24);
}
transition は状態変化に追従する場面で短く書けます。リンクやCTAボタンに適しています。
画像をなめらかにズームさせるカード
<a class="zoom-card" href="#">
<span class="zoom-card__media">
<img class="zoom-card__image" src="sample.jpg" alt="サンプル画像">
</span>
<span class="zoom-card__label">事例を見る</span>
</a>
.zoom-card {
display: inline-block;
width: 280px;
color: #cccccc;
text-decoration: none;
}
.zoom-card__media {
display: block;
overflow: hidden;
border-radius: 20px;
}
.zoom-card__image {
display: block;
width: 100%;
transform: scale(1);
transition: transform 0.4s ease;
}
.zoom-card:hover .zoom-card__image,
.zoom-card:focus-visible .zoom-card__image {
transform: scale(1.05);
}
拡大率を 1.05 程度に抑えると、視線誘導はできますが不自然な拡大にはなりにくいです。サムネイル一覧に向きます。
通知を控えめに目立たせるパルス
<span class="status-badge">NEW</span>
.status-badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 56px;
padding: 6px 10px;
border-radius: 999px;
background: #0078d4;
color: #ffffff;
animation: softPulse 1.8s ease-in-out infinite;
}
@keyframes softPulse {
0%,
100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.06);
opacity: 0.88;
}
}
常時動く演出は主張が強くなりやすいので、変化量を小さく保つのが前提です。通知や更新ラベルのように、軽く視線を集めたい場面で使います。
滑らかに見える理由を理解する基本原則4選
CSS アニメーションの品質は、構文の複雑さではなく 何をどれだけ動かすか で決まることが多いです。特に初学者がつまずきやすいのは、「派手にすれば滑らかに見える」と誤解して距離や時間を盛ってしまう点です。実際には、小さな変化を短い時間でつなぐほうが、UIに馴染みやすくなります。この章では、滑らかさを作る基本原則を4つの短い実装で確認します。
ここで押さえたいのは、transform、opacity、transition-timing-function、animation-fill-mode の役割です。動きが不自然なときは、複雑な書き換えより先に、これらの指定が過剰になっていないかを見るほうが早く直せます。
transform を使った横移動
<div class="slide-chip">横に少し動く要素</div>
.slide-chip {
display: inline-block;
padding: 10px 14px;
border-radius: 999px;
background: #0078d4;
color: #ffffff;
transform: translateX(0);
transition: transform 0.3s ease;
}
.slide-chip:hover {
transform: translateX(6px);
}
left を変えるより transform: translateX() のほうが、見た目の移動を素直に制御しやすいです。移動量も 6px 程度から始めると調整しやすくなります。
opacity だけで見せるフェード
ホバーすると透明度だけが変わります。
<p class="fade-text">ホバーすると透明度だけが変わります。</p>
.fade-text {
opacity: 0.7;
transition: opacity 0.2s linear;
}
.fade-text:hover {
opacity: 1;
}
透明度だけの変化は最も単純で、テキストや補助要素の強弱付けに向いています。派手さはありませんが、情報の優先順位を自然に伝えやすいです。
イージングの違いを確認する
<div class="ease-demo ease-demo--out">ease-out</div>
<div class="ease-demo ease-demo--inout">ease-in-out</div>
.ease-demo {
width: 180px;
margin-bottom: 12px;
padding: 12px 16px;
border-radius: 12px;
background: #0078d4;
color: #ffffff;
transform: translateX(0);
}
.ease-demo--out {
transition: transform 0.35s ease-out;
}
.ease-demo--inout {
transition: transform 0.35s ease-in-out;
}
.ease-demo:hover {
transform: translateX(12px);
}
ease-out は着地が穏やかなので、登場演出やボタンの反応と相性が良いです。ease-in-out は往復する動きや常時見えるUIに合わせやすいです。
終了状態を保つ both の指定
<div class="fill-mode-box">表示後も最終状態を維持します。</div>
.fill-mode-box {
padding: 20px;
border-radius: 16px;
border: 1px solid rgba(0, 120, 212, 0.4);
background: #21384b;
animation: fadeInKeep 0.5s ease-out both;
}
@keyframes fadeInKeep {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
animation-fill-mode: both; がないと、読み込み演出のあとに元の初期状態へ戻って見えることがあります。初回表示系のアニメーションでは入れておくと安全です。
transitionで実装しやすいUIパターン4選
transition は、ホバー、フォーカス、開閉のような 状態変化に応じて動けば十分なUI に向いています。記述量が少なく、HTMLへクラスを足さなくても成立しやすいので、運用中のサイトへ小さく追加したい場面で扱いやすいです。一方で、複数段階の動きや自動再生には向きません。この章では、実務で流用しやすい4パターンを紹介します。
共通する注意点は、transition を変化後のセレクタではなく 変化前の要素 に書くことです。戻るときの動きも含めて自然にしたいなら、この原則を外さないほうが安定します。
下線が伸びるテキストリンク
<a class="underline-link" href="#">詳しい手順を見る</a>
.underline-link {
color: #0078d4;
text-decoration: none;
border-bottom: 2px solid transparent;
transition: border-color 0.25s ease;
}
.underline-link:hover,
.underline-link:focus-visible {
border-color: currentColor;
}
テキストリンクを少しだけ強調したいときに有効です。線の太さを増やしすぎると可読性を落とすため、2px 程度が扱いやすいです。
カード全体を少し持ち上げる
<a class="service-card" href="#">
<strong class="service-card__title">サービス資料</strong>
<span class="service-card__text">概要と導入例を確認できます。</span>
</a>
.service-card {
display: block;
max-width: 320px;
padding: 24px;
border: 1px solid rgba(0, 120, 212, 0.42);
border-radius: 20px;
background: #282828;
color: #cccccc;
text-decoration: none;
transform: translateY(0);
transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}
.service-card:hover,
.service-card:focus-visible {
transform: translateY(-6px);
border-color: #0078d4;
box-shadow: 0 18px 32px rgba(0, 120, 212, 0.16);
}
カードに奥行きを出したいときの定番です。移動量を増やしすぎると、クリック前に要素が逃げる印象になるので注意してください。
アイコンが横に流れるボタン
<a class="arrow-button" href="#">
<span>申し込みへ進む</span>
<span class="arrow-button__icon" aria-hidden="true">→</span>
</a>
.arrow-button {
display: inline-flex;
align-items: center;
gap: 10px;
padding: 14px 20px;
border-radius: 999px;
background: #0078d4;
color: #ffffff;
text-decoration: none;
}
.arrow-button__icon {
transform: translateX(0);
transition: transform 0.2s ease;
}
.arrow-button:hover .arrow-button__icon,
.arrow-button:focus-visible .arrow-button__icon {
transform: translateX(4px);
}
ボタン全体を動かさず、視線を集めたい部分だけを少し動かすパターンです。情報設計を崩しにくいので使いやすいです。
補助テキストをふわっと出すツールチップ風表示
<span class="tooltip-wrap">
ヘルプ
<span class="tooltip-wrap__panel">入力例を確認できます。</span>
</span>
.tooltip-wrap {
position: relative;
display: inline-block;
}
.tooltip-wrap__panel {
position: absolute;
left: 50%;
bottom: calc(100% + 8px);
transform: translate(-50%, 6px);
padding: 8px 12px;
border-radius: 10px;
background: #0078d4;
color: #ffffff;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease, transform 0.2s ease;
}
.tooltip-wrap:hover .tooltip-wrap__panel,
.tooltip-wrap:focus-within .tooltip-wrap__panel {
opacity: 1;
transform: translate(-50%, 0);
}
opacity と translate を組み合わせると、単なる表示切り替えより自然に見えます。説明文や入力補助の補足に向いています。
@keyframesで作る自動アニメーション4選
@keyframes は、読み込み時の登場演出、ローディング、繰り返し、段階的な変化など、開始と終了の間に中間状態を持たせたいとき に向いています。transition では表現しにくい複数段階の動きを明示できるため、時間軸を設計しやすいのが利点です。ただし、常時動かすほど画面のノイズも増えるため、用途を絞って使う必要があります。
ここでは、登場、ローディング、順番表示、背景の呼吸感という4パターンを紹介します。どれも変化量を小さく抑えています。見せたいのは「動き」そのものではなく、読者の視線と状態変化です。
右から入るスライドイン
<aside class="slide-in-note">新機能の案内です。</aside>
.slide-in-note {
padding: 18px 20px;
border-radius: 14px;
border: 1px solid rgba(0, 120, 212, 0.4);
background: #21384b;
animation: slideInRight 0.45s ease-out both;
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(20px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
横からの登場は通知や補助パネルに向いています。移動距離が長いと視線を奪いすぎるため、20px 前後が基準にしやすいです。
3点が順に跳ねるローディング
<div class="dot-loading" aria-label="読み込み中">
<span class="dot-loading__dot"></span>
<span class="dot-loading__dot"></span>
<span class="dot-loading__dot"></span>
</div>
.dot-loading {
display: inline-flex;
gap: 8px;
}
.dot-loading__dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #0078d4;
animation: dotBounce 0.8s ease-in-out infinite;
}
.dot-loading__dot:nth-child(2) {
animation-delay: 0.1s;
}
.dot-loading__dot:nth-child(3) {
animation-delay: 0.2s;
}
@keyframes dotBounce {
0%,
100% {
transform: translateY(0);
opacity: 0.5;
}
50% {
transform: translateY(-6px);
opacity: 1;
}
}
ローディングは「待っている」状態を伝えるのが目的です。大きく跳ねさせるより、小さな上下移動と透明度差のほうが落ち着いて見えます。
順番に現れるリスト
- 要件整理
- デザイン調整
- 実装反映
<ul class="stagger-list">
<li class="stagger-list__item">要件整理</li>
<li class="stagger-list__item">デザイン調整</li>
<li class="stagger-list__item">実装反映</li>
</ul>
.stagger-list {
padding-left: 20px;
}
.stagger-list__item {
opacity: 0;
transform: translateY(10px);
animation: itemFadeUp 0.45s ease-out forwards;
}
.stagger-list__item:nth-child(2) {
animation-delay: 0.12s;
}
.stagger-list__item:nth-child(3) {
animation-delay: 0.24s;
}
@keyframes itemFadeUp {
to {
opacity: 1;
transform: translateY(0);
}
}
工程や特徴を順に見せたいときに使いやすいです。遅延を入れすぎると待ち時間が増えるため、0.1 秒台の差に抑えるほうが実務では扱いやすいです。
背景がわずかに呼吸するヒーロー
背景がわずかに変化します。
<section class="hero-glow">
<p class="hero-glow__text">背景がわずかに変化します。</p>
</section>
.hero-glow {
padding: 48px 24px;
border-radius: 24px;
background: #0078d4;
animation: heroGlow 4s ease-in-out infinite;
}
.hero-glow__text {
margin: 0;
}
@keyframes heroGlow {
0%,
100% {
transform: scale(1);
filter: saturate(100%);
}
50% {
transform: scale(1.01);
filter: saturate(108%);
}
}
ヒーロー領域の静止画感を少し和らげたい場面で使えます。ただし常時動くため、本文エリアや長文の近くでは多用しないほうが読みやすさを保てます。
失敗を避ける比較と調整の実装例
CSS アニメーションで失敗しやすいのは、構文ミスよりも 指定の盛りすぎ と 対象の広げすぎ です。特に transition: all;、長すぎる時間、移動量の過大設定、動きへの配慮不足は、コピペ直後には気づきにくいのに実務で問題になりやすいです。この章では、危険な書き方と調整例を並べて、最後の判断基準として整理します。
結論として、軽い演出なら 0.2 秒から 0.6 秒程度、移動量は 4px から 16px 程度を起点にするのが扱いやすいです。絶対の正解ではありませんが、情報閲覧の邪魔になりにくい範囲としては妥当です。迷ったら、強く見せるより 違和感を減らす方向 に調整してください。
transition: all; を避けて対象を絞る
<a class="safe-link" href="#">安全な指定例</a>
.safe-link {
color: #0078d4;
transition: color 0.2s ease, transform 0.2s ease;
}
.safe-link:hover,
.safe-link:focus-visible {
color: #0078d4;
transform: translateY(-1px);
}
all を使うと、意図していないプロパティまで動く可能性があります。保守しやすくするには、何を動かすかを明示したほうが安全です。
長すぎる時間を短くする
<button class="time-button" type="button">送信する</button>
.time-button {
padding: 12px 18px;
border: 0;
border-radius: 12px;
background: #0078d4;
color: #ffffff;
transition: transform 0.22s ease, background-color 0.22s ease;
}
.time-button:hover,
.time-button:focus-visible {
background: #4daafc;
transform: translateY(-2px);
}
軽いホバーに 0.8 秒以上を使うと、押すたびに待たされる感覚が出やすいです。操作系UIでは短めの設定が向いています。
動きを減らす設定を用意する
<div class="motion-panel">環境設定に応じて動きを止めます。</div>
.motion-panel {
padding: 20px;
border-radius: 16px;
border: 1px solid rgba(0, 120, 212, 0.4);
background: #21384b;
animation: fadeUp 0.5s ease-out both;
}
@media (prefers-reduced-motion: reduce) {
.motion-panel {
animation: none;
}
}
prefers-reduced-motion は、動きが苦手なユーザーへの配慮として有効です。主要導線や共通パーツでは入れておく価値があります。
使い分けを表で確認する
| 場面 | 向いている方法 | 理由 |
|---|---|---|
| ホバー、フォーカス、色変更 | transition | 状態変化に応じて動けば十分で、記述が短く保守しやすいからです。 |
| 読み込み時の登場、ループ、段階演出 | @keyframes | 開始、中間、終了を定義でき、時間軸を制御しやすいからです。 |
滑らかな CSS アニメーションをコピペで導入するなら、まずは用途に応じて手法を分けることが先です。状態変化なら transition、自動演出なら @keyframes と切り分け、そのうえで距離、時間、イージングを小さく調整すると破綻しにくくなります。
まとめ
CSSアニメーションは、JavaScriptを使わずに要素に動きや変化を加えられる手法で、サイトの視認性やユーザー体験を向上させるために活用されます。主に「@keyframes」と「animationプロパティ」を組み合わせて実装し、位置・透明度・サイズなどの変化を細かく制御できます。
この記事では、ホバー時の変化やスライド・フェードなど、実務でよく使う基本的なアニメーションから、少し応用的な動きまでを紹介しています。CSSのみで軽量に実装できるため、パフォーマンスを保ちながらリッチな表現が可能です。
また、アニメーションは見た目の演出だけでなく、ユーザーの注意を引いたり、操作のフィードバックとしても重要な役割を持ちます。一方で過剰な演出はUXを損なうため、目的に応じた適切な使い方が求められます。
総じて、CSSアニメーションはシンプルな実装で大きな表現力を持つため、Web制作において基本かつ重要なスキルの一つです。