CSSだけでも、読み込み中に表示するローディングアニメーションを作れます。
この記事では、CSSのみで作れるローディングアニメーションを20個まとめました。スピナー、ドット、バー、スケルトンローディング、ボタン内ローダーなど、HTMLとCSSをコピーして使いやすい形で紹介します。
1. 基本の回転スピナー
一番使いやすい、円が回転するローディングです。
<span class="loader-spinner" aria-label="読み込み中"></span>
.loader-spinner {
display: inline-block;
width: 36px;
height: 36px;
border: 4px solid #e5e7eb;
border-top-color: #2563eb;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
短い待ち時間にも使いやすい基本形です。
2. 2色リングのスピナー
少しだけ装飾感を出したい場合のスピナーです。
.loader-ring {
display: inline-block;
width: 40px;
height: 40px;
border: 4px solid #dbeafe;
border-right-color: #2563eb;
border-bottom-color: #2563eb;
border-radius: 50%;
animation: spin 0.75s linear infinite;
}
基本スピナーと同じ @keyframes spin を使えます。
3. 3つのドットが跳ねるローダー
小さく置きやすい、ドット型のローディングです。
<div class="loader-dots">
<span></span>
<span></span>
<span></span>
</div>
.loader-dots {
display: flex;
gap: 8px;
}
.loader-dots span {
width: 10px;
height: 10px;
background: #2563eb;
border-radius: 50%;
animation: dotBounce 0.8s ease-in-out infinite alternate;
}
.loader-dots span:nth-child(2) {
animation-delay: 0.15s;
}
.loader-dots span:nth-child(3) {
animation-delay: 0.3s;
}
@keyframes dotBounce {
to {
transform: translateY(-8px);
}
}
点の動きが順番にずれるため、読み込み中らしく見えます。
4. ドットがフェードするローダー
跳ねる動きより控えめなドットローダーです。
.loader-dots-fade {
display: flex;
gap: 7px;
}
.loader-dots-fade span {
width: 9px;
height: 9px;
background: #64748b;
border-radius: 50%;
animation: dotFade 1s ease-in-out infinite;
}
.loader-dots-fade span:nth-child(2) {
animation-delay: 0.15s;
}
.loader-dots-fade span:nth-child(3) {
animation-delay: 0.3s;
}
@keyframes dotFade {
0%,
100% {
opacity: 0.3;
}
50% {
opacity: 1;
}
}
動きが小さいので、テキスト横にも置きやすいです。
5. バーが流れるローディング
細いバーが左から右へ流れるローディングです。
.loader-bar {
width: 180px;
height: 6px;
overflow: hidden;
background: #e5e7eb;
border-radius: 9999px;
}
.loader-bar::before {
display: block;
width: 40%;
height: 100%;
content: "";
background: #2563eb;
border-radius: inherit;
animation: barMove 1s ease-in-out infinite;
}
@keyframes barMove {
from {
transform: translateX(-100%);
}
to {
transform: translateX(260%);
}
}
一覧やフォーム送信中の補助表示に使いやすいです。
6. 進捗バー風ローディング
実際の進捗率ではなく、処理中を示すループアニメーションです。
.loader-progress {
width: min(100%, 280px);
height: 8px;
overflow: hidden;
background: #e0f2fe;
border-radius: 9999px;
}
.loader-progress::before {
display: block;
width: 55%;
height: 100%;
content: "";
background: #0284c7;
border-radius: inherit;
animation: progressLoop 1.2s ease-in-out infinite;
}
@keyframes progressLoop {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(220%);
}
}
実際の進捗を表す場合は、値の更新が別途必要です。
7. テキストの後ろに点が増えるローディング
「読み込み中…」の点をCSSで変化させる例です。
<p class="loader-text">読み込み中<span></span></p>
.loader-text span::after {
content: "";
animation: loadingDots 1.2s steps(4, end) infinite;
}
@keyframes loadingDots {
0% {
content: "";
}
25% {
content: ".";
}
50% {
content: "..";
}
75%,
100% {
content: "...";
}
}
文字だけで軽く待機状態を見せたいときに便利です。
8. スケルトンローディングの基本
カードや一覧の読み込み中に使いやすい表現です。
<div class="skeleton-lines">
<span></span>
<span></span>
<span></span>
</div>
.skeleton-lines {
display: grid;
gap: 12px;
}
.skeleton-lines span {
display: block;
height: 16px;
overflow: hidden;
background: #e5e7eb;
border-radius: 4px;
}
.skeleton-lines span::before {
display: block;
width: 100%;
height: 100%;
content: "";
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent);
animation: skeletonMove 1.2s linear infinite;
}
@keyframes skeletonMove {
from {
transform: translateX(-100%);
}
to {
transform: translateX(100%);
}
}
テキストの読み込み前のプレースホルダーとして使えます。
9. カード型スケルトン
カードUIの読み込み前に使うスケルトンです。
.skeleton-card {
display: grid;
gap: 14px;
max-width: 320px;
padding: 16px;
border: 1px solid #e5e7eb;
border-radius: 8px;
}
.skeleton-card .image,
.skeleton-card .line {
overflow: hidden;
background: #e5e7eb;
border-radius: 6px;
}
.skeleton-card .image {
aspect-ratio: 16 / 9;
}
.skeleton-card .line {
height: 14px;
}
スケルトンの形を実際のカードに近づけると、読み込み後の違和感が減ります。
10. 画像プレースホルダーのローディング
画像が読み込まれる前の枠として使える表現です。
.image-placeholder {
position: relative;
overflow: hidden;
aspect-ratio: 16 / 9;
background: #e5e7eb;
border-radius: 8px;
}
.image-placeholder::before {
position: absolute;
inset: 0;
content: "";
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.65), transparent);
animation: skeletonMove 1.2s linear infinite;
}
画像比率を先に確保しておくと、読み込み後のレイアウトの揺れを抑えられます。
11. 四角が回転するローダー
少し個性的なローディングです。
.loader-square {
width: 34px;
height: 34px;
background: #2563eb;
border-radius: 6px;
animation: squareRotate 1s ease-in-out infinite;
}
@keyframes squareRotate {
50% {
transform: rotate(180deg) scale(0.75);
}
100% {
transform: rotate(360deg);
}
}
装飾性が高いので、ブランド感を出したい場所に向いています。
12. ボールが弾むローダー
丸い要素が上下に弾むシンプルなアニメーションです。
.loader-ball {
width: 24px;
height: 24px;
background: #0f766e;
border-radius: 50%;
animation: ballBounce 0.7s ease-in-out infinite alternate;
}
@keyframes ballBounce {
to {
transform: translateY(-16px);
}
}
動きが大きいので、表示時間が長い場所では控えめにします。
13. 3本バーが伸び縮みするローダー
音声波形のような見た目のローディングです。
<div class="loader-bars">
<span></span>
<span></span>
<span></span>
</div>
.loader-bars {
display: flex;
gap: 5px;
align-items: end;
height: 34px;
}
.loader-bars span {
width: 7px;
height: 14px;
background: #2563eb;
border-radius: 9999px;
animation: barScale 0.8s ease-in-out infinite;
}
.loader-bars span:nth-child(2) {
animation-delay: 0.15s;
}
.loader-bars span:nth-child(3) {
animation-delay: 0.3s;
}
@keyframes barScale {
50% {
height: 34px;
}
}
小さなローディング表示として使いやすい形です。
14. 画面中央にローディングを置く
ページ全体の読み込み中に、中央へローダーを置く例です。
<div class="loader-center">
<span class="loader-spinner"></span>
</div>
.loader-center {
display: grid;
place-items: center;
min-height: 240px;
}
中央寄せは、CSS中央寄せまとめ と関連します。
15. 全画面オーバーレイのローディング
処理中に画面全体を覆う例です。
.loader-overlay {
position: fixed;
inset: 0;
z-index: 999;
display: grid;
place-items: center;
background: rgba(255, 255, 255, 0.86);
}
処理が終わったら非表示にする制御が必要です。
16. ボタン内のローディング
送信中のボタン内に小さなスピナーを置く例です。
<button class="button-loading" type="button">
<span></span>
送信中
</button>
.button-loading {
display: inline-flex;
gap: 10px;
align-items: center;
padding: 12px 22px;
color: #fff;
font: inherit;
background: #111827;
border: 0;
border-radius: 6px;
}
.button-loading span {
width: 16px;
height: 16px;
border: 2px solid rgba(255, 255, 255, 0.35);
border-top-color: #fff;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
ボタンアニメーションは、CSSアニメーション付きボタン集 と分けて扱えます。
17. HTMLで読み込み中を伝える
見た目だけでなく、状態をテキストでも伝えます。
<div class="loader-with-text" role="status" aria-live="polite">
<span class="loader-spinner" aria-hidden="true"></span>
<span>読み込み中です</span>
</div>
.loader-with-text {
display: inline-flex;
gap: 10px;
align-items: center;
color: #334155;
}
ローダーだけでは意味が伝わりにくいため、テキストも用意します。
18. CSS変数で色とサイズを変える
複数ページで使い回すスピナーです。
.loader-variable {
--loader-size: 36px;
--loader-color: #2563eb;
display: inline-block;
width: var(--loader-size);
height: var(--loader-size);
border: 4px solid #e5e7eb;
border-top-color: var(--loader-color);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
色やサイズだけ変えたいときに便利です。
19. 動きを減らす設定
動きが苦手なユーザー向けに、アニメーションを止める設定を用意します。
@media (prefers-reduced-motion: reduce) {
.loader-spinner,
.loader-ring,
.loader-dots span,
.loader-bar::before,
.skeleton-lines span::before,
.image-placeholder::before,
.loader-square,
.loader-ball,
.loader-bars span {
animation: none;
}
}
常時動くUIでは、prefers-reduced-motion もセットで考えます。
20. ローディングの最小テンプレート
最後に、テキスト付きで使いやすい最小テンプレートです。
<div class="loading-template" role="status" aria-live="polite">
<span></span>
読み込み中です
</div>
.loading-template {
display: inline-flex;
gap: 10px;
align-items: center;
}
.loading-template span {
width: 28px;
height: 28px;
border: 3px solid #e5e7eb;
border-top-color: #2563eb;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
迷ったら、スピナーとテキストをセットで表示する形が使いやすいです。
ローディングの注意点
- 読み込みが終わったら非表示にする
- 動きが速すぎないようにする
- 重要な操作をローディングで隠し続けない
- 動きを減らす設定にも配慮する
- CSSだけで状態管理はできないため、表示切り替えは必要に応じてJavaScriptなどで行う
まとめ
CSSローディングは、スピナー、ドット、バー、スケルトンを使い分けると便利です。
アニメーションの基本は、CSSアニメーションの作り方 で補足できます。