CSSで要素を点滅(ブリンク)させたい場面は意外と多く、通知バッジの点滅、エラーメッセージの強調、ローディングインジケーターなど、実務でもよく使われるテクニックです。
この記事では、@keyframes と animation を使った点滅アニメーションの基本から、opacity・visibility・color による表現の違い、速度・回数・遅延の制御、アクセシビリティ対応、JavaScript での動的制御まで、実務で使えるパターンを網羅的に解説します。
CSS で点滅させる基本の仕組み(@keyframes + animation)
CSSで要素を点滅させるには、@keyframes でアニメーションを定義し、animation プロパティで適用します。
CSS
/* キーフレームを定義 */
@keyframes blink {
0% { opacity: 1; }
50% { opacity: 0; }
100% { opacity: 1; }
}
/* 要素に適用 */
.blink {
animation: blink 1s infinite;
}
HTML
<p class="blink">この文字が点滅します</p>
animation プロパティの構文
animation: 名前 時間 繰り返し; がショートハンドです。個別に書く場合は以下の通りです。
animation-name ── キーフレーム名(例: blink)
animation-duration ── 1サイクルの時間(例: 1s)
animation-iteration-count ── 繰り返し回数(例: infinite)
animation-timing-function ── 速度カーブ(例: ease, linear)
opacity を使った点滅(フェードイン/アウト)
opacity(不透明度)を変化させる方法は、最も一般的な点滅の実装です。値を 0〜1 の間で変化させることで、フワッと消えてフワッと現れるなめらかな点滅が実現できます。
なめらかフェード点滅
CSS – フェード点滅
@keyframes fade-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.fade-blink {
animation: fade-blink 2s ease-in-out infinite;
}
半透明までの点滅(完全に消えない)
要素を完全に消したくない場合は、opacity の最小値を 0.3 程度にします。
CSS – 半透明点滅
@keyframes soft-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
.soft-blink {
animation: soft-blink 1.5s ease-in-out infinite;
}
ポイント:opacity の点滅は要素がなめらかに変化するため、ユーザーに優しい印象を与えます。UX を重視する場合はこの方法がおすすめです。
visibility を使った点滅(パッと切り替え)
visibility を使うと、要素がパッと消えてパッと現れるような、昔ながらの点滅が再現できます。opacity と違い中間状態がないため、カーソルの点滅のようなメリハリのある表現になります。
CSS – visibility 点滅
@keyframes blink-visibility {
0%, 100% { visibility: visible; }
50% { visibility: hidden; }
}
.blink-hard {
animation: blink-visibility 1s step-end infinite;
}
注意:visibility: hidden は要素が非表示になってもレイアウト上のスペースは保持されます。display: none のようにレイアウトが崩れることはありません。animation-timing-function に step-end を指定することで、なめらかな変化ではなくパッと切り替わる動作になります。
opacity と visibility の違い比較
| 項目 |
opacity |
visibility |
| 見た目 |
フワッと消える |
パッと消える |
| 中間値 |
0〜1 の間で遷移 |
visible / hidden のみ |
| レイアウト |
スペース保持 |
スペース保持 |
| クリック判定 |
opacity: 0 でも受ける |
hidden で受けない |
| 用途 |
なめらかな演出 |
カーソル風の点滅 |
color / background-color で点滅させる
文字色や背景色を変化させることで、要素自体は消えずに色だけが点滅する表現ができます。テキストの強調や、ボタンのアテンション演出に使われます。
文字色の点滅
CSS – 文字色の点滅
@keyframes blink-color {
0%, 100% { color: #e74c3c; }
50% { color: transparent; }
}
.blink-text {
animation: blink-color 1s infinite;
font-weight: bold;
}
背景色の点滅
CSS – 背景色の点滅
@keyframes blink-bg {
0%, 100% { background-color: #fff3cd; }
50% { background-color: #ffc107; }
}
.blink-highlight {
padding: 8px 16px;
border-radius: 4px;
animation: blink-bg 1.5s ease-in-out infinite;
}
border の点滅
CSS – ボーダーの点滅
@keyframes blink-border {
0%, 100% { border-color: #e74c3c; }
50% { border-color: transparent; }
}
.blink-border {
border: 2px solid #e74c3c;
padding: 12px;
animation: blink-border 1s infinite;
}
点滅速度の調整(animation-duration)
animation-duration の値を変えることで、点滅の速度を自由にコントロールできます。
CSS – 速度の違い
/* 高速点滅(0.3秒サイクル) */
.blink-fast {
animation: blink 0.3s infinite;
}
/* 通常点滅(1秒サイクル) */
.blink-normal {
animation: blink 1s infinite;
}
/* ゆっくり点滅(3秒サイクル) */
.blink-slow {
animation: blink 3s infinite;
}
| 速度 |
duration 値 |
用途 |
| 超高速 |
0.2s |
緊急アラート、エラー |
| 高速 |
0.5s |
通知バッジ、注意喚起 |
| 通常 |
1s |
一般的な点滅、カーソル |
| ゆっくり |
2s〜3s |
穏やかな演出、呼吸アニメーション |
ポイント:animation-timing-function も点滅の印象に大きく影響します。ease-in-out でなめらかに、linear で一定速度に、step-end でパッと切り替え、と使い分けましょう。
点滅回数を制限する(animation-iteration-count)
永遠に点滅し続けるのはユーザーにとって不快な場合があります。animation-iteration-count で回数を制限することで、注意を引いた後に点滅を自動で停止できます。
CSS – 点滅回数の制限
/* 3回だけ点滅 */
.blink-3times {
animation: blink 1s 3;
}
/* 5回点滅して最後は表示状態で停止 */
.blink-5times {
animation: blink 1s 5;
animation-fill-mode: forwards;
}
/* 小数も指定可能(1.5回 = 途中で止まる) */
.blink-half {
animation: blink 1s 1.5;
animation-fill-mode: forwards;
}
animation-fill-mode について
forwards ── アニメーション終了後、最後のキーフレームの状態を維持
backwards ── アニメーション開始前に最初のキーフレームの状態を適用
both ── forwards と backwards の両方を適用
none(デフォルト)── アニメーション前後の状態に影響しない
複数要素の時間差点滅(animation-delay)
animation-delay を使えば、複数の要素をずらして点滅させることができます。ローディングインジケーターやシーケンスアニメーションに便利です。
ローディングドットの時間差点滅
CSS – ローディングドット
@keyframes dot-blink {
0%, 80%, 100% { opacity: 0; }
40% { opacity: 1; }
}
.loading-dots {
display: flex;
gap: 8px;
}
.loading-dots span {
width: 12px;
height: 12px;
background: #3b82f6;
border-radius: 50%;
animation: dot-blink 1.4s ease-in-out infinite;
}
.loading-dots span:nth-child(1) { animation-delay: 0s; }
.loading-dots span:nth-child(2) { animation-delay: 0.2s; }
.loading-dots span:nth-child(3) { animation-delay: 0.4s; }
HTML
<div class="loading-dots">
<span></span>
<span></span>
<span></span>
</div>
テキストの1文字ずつ点滅
CSS + HTML – 1文字ずつ点滅
/* CSS */
@keyframes char-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0.2; }
}
.wave-text span {
display: inline-block;
animation: char-blink 1.5s ease-in-out infinite;
}
.wave-text span:nth-child(1) { animation-delay: 0s; }
.wave-text span:nth-child(2) { animation-delay: 0.1s; }
.wave-text span:nth-child(3) { animation-delay: 0.2s; }
.wave-text span:nth-child(4) { animation-delay: 0.3s; }
.wave-text span:nth-child(5) { animation-delay: 0.4s; }
<!-- HTML -->
<div class="wave-text">
<span>L</span>
<span>o</span>
<span>a</span>
<span>d</span>
<span>...</span>
</div>
animation-timing-function による点滅の印象の違い
animation-timing-function を変えると、同じキーフレームでも点滅の「雰囲気」が大きく変わります。
| timing-function |
印象 |
適した用途 |
ease |
自然な緩急 |
一般的な演出 |
ease-in-out |
ゆったりした呼吸感 |
ローディング、呼吸アニメーション |
linear |
一定速度で機械的 |
インジケーター、プログレス |
step-end |
パッと切り替え |
カーソル、ON/OFF 切替 |
steps(2, end) |
2段階で切り替え |
レトロな演出 |
CSS – timing-function の指定例
/* カーソル風のパッと点滅 */
.cursor-blink {
display: inline-block;
width: 2px;
height: 1.2em;
background: #333;
animation: blink 1s step-end infinite;
}
/* 呼吸するような点滅 */
.breathing {
animation: fade-blink 3s ease-in-out infinite;
}
text-decoration: blink が使えない理由
かつてCSSには text-decoration: blink というプロパティがありましたが、現在は全ブラウザで非推奨・廃止されています。
CSS – 使えないコード
/* これは動作しません */
.old-blink {
text-decoration: blink; /* 非推奨・廃止 */
}
注意:text-decoration: blink は CSS2 で定義されましたが、アクセシビリティの問題やユーザー体験の悪化を理由に CSS3 で廃止されました。Chrome・Firefox・Safari・Edge のいずれも対応していません。点滅が必要な場合は @keyframes + animation を使いましょう。
同様に、HTML の <blink> タグも廃止されており、使用できません。
| 廃止された方法 |
状態 |
代替手段 |
text-decoration: blink |
CSS3 で廃止 |
@keyframes + animation |
<blink> タグ |
HTML5 で廃止 |
@keyframes + animation |
<marquee> タグ |
HTML5 で非推奨 |
CSS animation + transform |
アクセシビリティの注意点(prefers-reduced-motion)
点滅アニメーションは視覚障害やてんかんを持つユーザーにとって深刻な問題を引き起こす可能性があります。WCAG(Web Content Accessibility Guidelines)2.1 では、1秒間に3回以上の閃光を避けることが求められています。
prefers-reduced-motion で点滅を無効化
prefers-reduced-motion メディアクエリを使うと、ユーザーが「アニメーションを減らす」設定をしている場合に点滅を自動で無効化できます。
CSS – アクセシビリティ対応
/* 通常時の点滅アニメーション */
.blink {
animation: blink 1s infinite;
}
/* モーション軽減設定時はアニメーションを無効化 */
@media (prefers-reduced-motion: reduce) {
.blink {
animation: none;
}
}
汎用的なリセット(全アニメーション対象)
CSS – 全アニメーション一括無効化
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
アクセシビリティのチェックリスト
prefers-reduced-motion: reduce でアニメーションを無効化する
- 1秒間に3回以上の閃光を避ける(
duration を 0.3s 未満にしない)
- 点滅は装飾目的のみに使い、情報伝達を点滅だけに頼らない
- 可能であれば点滅回数を制限し、一定時間で停止させる
- 色だけでなく、テキストやアイコンでも状態を伝える
実務で使えるユースケース集
通知バッジの点滅
CSS + HTML – 通知バッジ
/* CSS */
@keyframes badge-pulse {
0% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.7; }
100% { transform: scale(1); opacity: 1; }
}
.notification-icon {
position: relative;
display: inline-block;
font-size: 24px;
}
.notification-badge {
position: absolute;
top: -5px;
right: -5px;
width: 12px;
height: 12px;
background: #ef4444;
border-radius: 50%;
animation: badge-pulse 1.5s ease-in-out infinite;
}
<!-- HTML -->
<div class="notification-icon">
🔔
<span class="notification-badge"></span>
</div>
エラーメッセージの点滅強調
CSS + HTML – エラー表示
/* CSS */
@keyframes error-blink {
0%, 100% { background-color: #fef2f2; }
50% { background-color: #fecaca; }
}
.error-message {
padding: 12px 16px;
border: 1px solid #ef4444;
border-radius: 8px;
color: #dc2626;
font-weight: bold;
animation: error-blink 1s ease-in-out 3;
}
<!-- HTML -->
<div class="error-message">
入力内容にエラーがあります。
</div>
ポイント:エラー表示の点滅は animation-iteration-count: 3 のように回数を制限し、注意を引いた後は停止させるのがベストプラクティスです。永遠に点滅し続けるとユーザーのストレスになります。
ローディングスケルトンの点滅
CSS + HTML – スケルトンローディング
/* CSS */
@keyframes skeleton-pulse {
0% { background-color: #e2e8f0; }
50% { background-color: #f1f5f9; }
100% { background-color: #e2e8f0; }
}
.skeleton {
border-radius: 4px;
animation: skeleton-pulse 2s ease-in-out infinite;
}
.skeleton-title {
height: 24px;
width: 60%;
margin-bottom: 12px;
}
.skeleton-text {
height: 16px;
width: 100%;
margin-bottom: 8px;
}
<!-- HTML -->
<div style="max-width:400px;padding:20px;">
<div class="skeleton skeleton-title"></div>
<div class="skeleton skeleton-text"></div>
<div class="skeleton skeleton-text" style="width:80%;"></div>
</div>
録画中インジケーター(REC)
CSS + HTML – RECインジケーター
/* CSS */
.rec-indicator {
display: flex;
align-items: center;
gap: 8px;
font-weight: bold;
color: #dc2626;
}
.rec-dot {
width: 12px;
height: 12px;
background: #dc2626;
border-radius: 50%;
animation: blink 1s ease-in-out infinite;
}
<!-- HTML -->
<div class="rec-indicator">
<span class="rec-dot"></span>
REC
</div>
JavaScript で点滅を制御する(classList.toggle)
ユーザーの操作に応じて点滅のオン/オフを切り替えたい場合は、JavaScript の classList.toggle を使います。
ボタンクリックで点滅の切り替え
HTML + CSS + JavaScript
<!-- HTML -->
<button id="toggleBtn">点滅のON/OFF</button>
<p id="target">この文字が点滅します</p>
<!-- CSS -->
<style>
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.is-blinking {
animation: blink 1s infinite;
}
</style>
<!-- JavaScript -->
<script>
const btn = document.getElementById('toggleBtn');
const target = document.getElementById('target');
btn.addEventListener('click', () => {
target.classList.toggle('is-blinking');
});
</script>
一定時間後に点滅を自動停止
JavaScript – 自動停止
const element = document.querySelector('.alert-message');
// 点滅を開始
element.classList.add('is-blinking');
// 5秒後に点滅を停止
setTimeout(() => {
element.classList.remove('is-blinking');
}, 5000);
setInterval を使った点滅(CSS不要パターン)
CSSアニメーションを使わず、JavaScript だけで点滅させる方法もあります。
JavaScript – setInterval による点滅
const el = document.getElementById('blink-target');
let visible = true;
const blinkInterval = setInterval(() => {
visible = !visible;
el.style.opacity = visible ? '1' : '0';
}, 500);
// 停止する場合
// clearInterval(blinkInterval);
注意:setInterval による点滅はCSSアニメーションに比べてパフォーマンスが劣ります。CSSアニメーションはブラウザがGPUで最適化して描画しますが、JavaScript の setInterval はメインスレッドで実行されるため、処理が重い場面ではカクつく可能性があります。特別な理由がない限り、CSSアニメーションを優先しましょう。
CSS アニメーションと JavaScript の使い分け
| 比較項目 |
CSS animation |
JavaScript |
| パフォーマンス |
GPU最適化あり |
メインスレッド実行 |
| 制御の柔軟性 |
開始/停止程度 |
条件分岐や動的変更が自由 |
| コード量 |
少ない(CSS のみ) |
やや多い |
| おすすめ用途 |
固定的な点滅演出 |
動的な ON/OFF 制御 |
| ベストプラクティス |
CSS でアニメーションを定義し、JavaScript で classList.toggle して切り替える |
コピーして使えるテンプレート集
最後に、すぐにコピーして使えるテンプレートをまとめます。
基本テンプレート(opacity 点滅)
コピー用テンプレート
/* 点滅アニメーション */
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
/* 適用するクラス */
.blink {
animation: blink 1s infinite;
}
/* アクセシビリティ対応 */
@media (prefers-reduced-motion: reduce) {
.blink { animation: none; }
}
カーソル風テンプレート(step-end)
コピー用テンプレート
@keyframes cursor-blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.cursor {
display: inline-block;
width: 2px;
height: 1em;
background: currentColor;
vertical-align: text-bottom;
animation: cursor-blink 1s step-end infinite;
}
ローディングドットテンプレート
コピー用テンプレート
@keyframes dot-blink {
0%, 80%, 100% { opacity: 0; }
40% { opacity: 1; }
}
.dots { display: flex; gap: 6px; }
.dots span {
width: 10px; height: 10px;
background: #3b82f6;
border-radius: 50%;
animation: dot-blink 1.4s ease-in-out infinite;
}
.dots span:nth-child(2) { animation-delay: 0.2s; }
.dots span:nth-child(3) { animation-delay: 0.4s; }
<!-- HTML: <div class="dots"><span></span><span></span><span></span></div> -->
JS制御テンプレート(ON/OFF + 自動停止)
コピー用テンプレート
/* CSS */
@keyframes blink {
0%, 100% { opacity: 1; }
50% { opacity: 0; }
}
.is-blinking { animation: blink 1s infinite; }
/* JavaScript */
function startBlink(el, duration = 0) {
el.classList.add('is-blinking');
if (duration > 0) {
setTimeout(() => el.classList.remove('is-blinking'), duration);
}
}
// 使用例: 3秒間点滅
startBlink(document.querySelector('.alert'), 3000);
// 使用例: 永続点滅
startBlink(document.querySelector('.notification'));
まとめ
CSSで要素を点滅させる方法を改めて整理します。
| 方法 |
特徴 |
おすすめ用途 |
opacity |
なめらかなフェード |
一般的な点滅演出 |
visibility |
パッと切り替え |
カーソル風の点滅 |
color |
文字色だけ変化 |
テキストの強調 |
background-color |
背景色だけ変化 |
ボタン・バッジの注意喚起 |
border-color |
枠線だけ変化 |
フォーム入力エラー |
JS classList.toggle |
動的に ON/OFF |
ユーザー操作に連動 |
ポイント:
@keyframes + animation が現在の標準的な点滅の実装方法
text-decoration: blink と <blink> タグは廃止済み
animation-iteration-count で回数を制限するとユーザーに優しい
animation-delay で複数要素の時間差点滅が作れる
prefers-reduced-motion でアクセシビリティに必ず配慮する
- CSSで定義 + JavaScriptで
classList 切り替えがベストプラクティス