ローディングアイコンの作り方|スピナーとドット

待ち時間を伝える3種のアニメーション

CSS の @keyframes で作る回転スピナー・ドット・不定形バーと、JavaScript で読み込み完了まで表示する制御を4パターンで解説します。各デモと同じ動きを再現できるHTML・CSS・JavaScriptを掲載しています。
HTML・CSS・JSコードプレビューツールでも動作を確認できます。

① 回転する円 — border の一部を濃くして回す

アニメーション: spin 1s linear infinite

HTML
<div class="ld-spin"></div>
CSS
.ld-spin {
  width: 60px;
  height: 60px;
  border: 6px solid rgba(0, 0, 0, 0.15);
  border-top: 6px solid #333;
  border-radius: 50%;
  animation: ldSpin 1s linear infinite;
}

@keyframes ldSpin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
border の一部だけを濃い色にして回転させる

薄いリングを border で作り、border-top だけ濃い色で上書きします。@keyframes で 0deg → 360deg に回すと、強調された部分がぐるぐる回るスピナーになります。速度ボタンを押すとデモとコピペ用CSSが同時に更新されます。

② ドットの拡大縮小 — animation-delay でリズムを作る

HTML
<div class="ld-dots">
  <div class="ld-dot"></div>
  <div class="ld-dot"></div>
  <div class="ld-dot"></div>
</div>
CSS
.ld-dots {
  display: flex;
  gap: 20px;
}

.ld-dot {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background-color: #4f46e5;
  animation: ldBounce 1.2s infinite ease-in-out;
}

.ld-dot:nth-child(1) {
  animation-delay: -0.24s;
}

.ld-dot:nth-child(2) {
  animation-delay: -0.12s;
}

.ld-dot:nth-child(3) {
  animation-delay: 0s;
}

@keyframes ldBounce {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.5);
  }
}
animation-delay の負の値でズレを作る

同じ @keyframes を3つのドットに適用し、animation-delay を -0.24s / -0.12s / 0s とずらすと波打つ動きになります。負の値はアニメーションを途中から始めるため、表示直後から動きが見えます。

③ 不定形プログレスバー — overflow ではみ出しを隠す

HTML
<div class="ld-bar-wrap">
  <div class="ld-bar-inner"></div>
</div>
CSS
.ld-bar-wrap {
  position: relative;
  width: 100%;
  max-width: 360px;
  height: 20px;
  overflow: hidden;
  border-radius: 5px;
  background-color: #e2e8f0;
}

.ld-bar-inner {
  position: absolute;
  width: 50%;
  height: 100%;
  background: linear-gradient(90deg, #7c3aed, #4f46e5);
  animation: ldBarMove 2s infinite;
}

@keyframes ldBarMove {
  0% {
    left: -50%;
  }
  50% {
    left: 25%;
  }
  100% {
    left: 100%;
  }
}
position + overflow: hidden でバーを枠内に収める

外枠に position: relative と overflow: hidden を付け、バーを absolute で動かします。left を枠外から枠外へ動かすと、はみ出しが隠れて終わりのない不定形バーになります。進捗%が分かるバーは プログレスバー記事 も参照してください。

④ 読み込み完了まで表示する — window load で制御

ページコンテンツ

2秒間のローディングが表示されます

HTML
<div class="ld-page-overlay">
  <div class="ld-page-spin"></div>
</div>

<main>
  <!-- ページ本体のコンテンツ -->
</main>
CSS
.ld-page-overlay {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background-color: #fff;
}

body.is-ready .ld-page-overlay {
  display: none;
}

.ld-page-spin {
  width: 60px;
  height: 60px;
  border: 6px solid rgba(0, 0, 0, 0.15);
  border-top: 6px solid #333;
  border-radius: 50%;
  animation: ldPageSpin 1s linear infinite;
}

@keyframes ldPageSpin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
JS
window.addEventListener('load', function() {
  document.body.classList.add('is-ready');
});
window load でクラスを付けて非表示にする

window の load は画像などを含むリソースの読み込み完了で発火します。このタイミングで body にクラスを付け、CSS でオーバーレイを非表示にします。デモの「ローディングを体験」は、同じ見え方を2秒間再現します。

注意点:フルスクリーンのオーバーレイは z-index が高く操作を遮ります。表示しっぱなしにならないよう、必ず load(または処理完了)で消してください。待ち時間が短いページでは、オーバーレイよりインラインのスピナーの方が邪魔になりにくいです。

スピナーとプログレスバーの違いは?

スピナーは「処理中」を伝えます。進捗%が分かる場合は決定型のプログレスバー、終わりが不明な場合は③の不定形バーやスピナーが向いています。

DOMContentLoaded との違いは?

DOMContentLoaded は HTML の解析完了時点です。load は画像などの読み込み完了後です。画像が多いページでオーバーレイを消すなら load の方が安全です。

動きを弱めたいときは?

prefers-reduced-motion: reduce で animation を止めるか、ゆっくりした動きに切り替えると配慮できます。

スケルトン表示との使い分けは?

レイアウトの骨組みを先に見せたいときは スケルトンスクリーン が向いています。単純な待ち表示ならスピナーで十分です。


当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次