こんにちは、Webディレクターの BigViです。
最近、私が対応したブログサイトのリニューアルで「読了率が低い」という問題がありました。記事は長いですが、途中で離脱するユーザーが多かったです。クライアントから「読者が最後まで読んでくれる工夫をしたい」という相談を受けました。
この課題に対して、私はセクション進捗表示を提案しました。ただし、常に表示されるプログレスバーではなく、「読んだ証拠」として点が灯る方式です。これが意外と効果がありました。
なぜ常時表示のプログレスバーじゃないのか
実は、最初は普通のプログレスバーを作りました。でもクライアントが「圧迫感がある」と言いました。確かに、常にゲージが見えると「まだこんなに残ってる」という気持ちになります。
そこで考え方を変えました。「進捗を見せる」のではなく「成果を見せる」方式です。章を読むたびに点が灯る。これなら「ここまで読んだ」という達成感があります。
実装の仕組み
今回の実装は3つの部分で構成されています。
- HTML構造(見出しとドット群)
- CSSスタイル(ドットのデザインと点灯アニメーション)
- JavaScript(IntersectionObserverで章の表示を監視)
HTML構造
各章の見出しの右側に、小さなドット群を配置します。ドットの数は章の総数と同じです。
<article class="blog-post">
<!-- 章1 -->
<section class="chapter" data-chapter="1">
<div class="chapter-header">
<h2>なぜ常時表示のプログレスバーじゃないのか</h2>
<div class="progress-dots">
<span class="dot" data-dot="1"></span>
<span class="dot" data-dot="2"></span>
<span class="dot" data-dot="3"></span>
<span class="dot" data-dot="4"></span>
</div>
</div>
<p>章の内容...</p>
</section>
<!-- 章2 -->
<section class="chapter" data-chapter="2">
<div class="chapter-header">
<h2>実装の仕組み</h2>
<div class="progress-dots">
<span class="dot" data-dot="1"></span>
<span class="dot" data-dot="2"></span>
<span class="dot" data-dot="3"></span>
<span class="dot" data-dot="4"></span>
</div>
</div>
<p>章の内容...</p>
</section>
<!-- 以下同様 -->
</article>
各セクションにdata-chapter属性を付けています。これで何番目の章かを判別できます。
CSSスタイル
ドットのデザインと点灯アニメーションを定義します。点灯時間は200msです。これがちょうどいい速さでした。
.chapter-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.5rem;
}
.progress-dots {
display: flex;
gap: 6px;
margin-left: 1rem;
}
.dot {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #e0e0e0;
transition: background-color 200ms ease-out;
}
.dot.active {
background-color: #2196F3;
}
最初は#e0e0e0(グレー)で、点灯すると#2196F3(青)になります。色は自由に変えられます。
JavaScriptの実装
IntersectionObserver APIを使います。これは要素が画面内に入ったかを検知するAPIです。各章が画面内に入ったときに、対応するドットを点灯させます。
// 各章要素を取得
const chapters = document.querySelectorAll('.chapter');
// IntersectionObserver の設定
const options = {
root: null, // ビューポートを基準
rootMargin: '-20% 0px -20% 0px', // 上下20%の位置で判定
threshold: 0
};
// 点灯済みドットを記録
const activatedDots = new Set();
// Observer のコールバック関数
const callback = (entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const chapterNum = entry.target.dataset.chapter;
// まだ点灯していないドットのみ処理
if (!activatedDots.has(chapterNum)) {
activatedDots.add(chapterNum);
// すべての章のドット群から該当番号のドットを点灯
const allDots = document.querySelectorAll(`.dot[data-dot="${chapterNum}"]`);
allDots.forEach(dot => {
dot.classList.add('active');
});
}
}
});
};
// Observer を作成して各章を監視
const observer = new IntersectionObserver(callback, options);
chapters.forEach(chapter => observer.observe(chapter));
ポイントはrootMargin: '-20% 0px -20% 0px'です。これで章が画面の中央付近に来たときに点灯します。上下20%をマージンにすることで、スクロール中にちょうどいいタイミングで灯ります。
一度点灯したら消えない仕組み
activatedDotsというSetで、すでに点灯したドット番号を記録しています。これで上にスクロールして戻っても、ドットは消えません。「読んだ証拠」として残り続けます。
実際の結果
この実装をクライアントのブログに導入しました。結果は良かったです。
- 平均読了率が約18%向上
- 次ページへの遷移率が約12%向上
- 直帰率が約9%減少
クライアントも「プログレスバーより圧迫感がない」と喜んでくれました。読者からも「どこまで読んだか分かりやすい」という声がありました。ちょっと面白かったのは、「全部の点を灯したい」という気持ちで最後まで読むユーザーがいることです。これは予想外でした。
応用できるパターン
このドット進捗は、ブログ以外にも使えます。実際に私が試した例を紹介します。
1. オンボーディング画面
アプリの初回利用時の説明画面で使いました。「3ステップ完了」という達成感を出せます。
2. ECサイトの商品説明
長い商品説明ページで使いました。「特徴」「仕様」「レビュー」の3セクションに対応するドットを表示。どこまで見たか分かりやすくなりました。
3. ドキュメントサイト
技術ドキュメントで使いました。読者が「どこまで学習したか」を視覚的に確認できます。
実装の注意点
実際に作ってみて気づいた注意点を書いておきます。
ドットの数は多すぎない
最初、10個のドットを表示しました。でも多すぎて見づらかったです。4〜6個がちょうどいいと思います。章が多い場合は、大きな章だけドットを付けるのがいいです。
モバイルでのサイズ調整
スマホでは見出しが長いと、ドットが下に落ちることがあります。レスポンシブ対応が必要です。
@media (max-width: 640px) {
.chapter-header {
flex-direction: column;
align-items: flex-start;
}
.progress-dots {
margin-left: 0;
margin-top: 0.5rem;
}
}
アクセシビリティの配慮
スクリーンリーダーを使う人のために、ドットに意味を持たせます。
<span class="dot" data-dot="1" aria-label="セクション1を読了" role="status"></span>
点灯したときに、状態が伝わるようにします。
まとめ
セクション進捗のドット表示について書きました。ポイントは以下の3つです。
- 常時表示ではなく「成果のフィードバック」として使う
- IntersectionObserverで章の表示を監視する
- 一度点灯したドットは消えない(読んだ証拠として残る)
実装はシンプルですが、効果は大きいです。ちょっとしたことだけど、お客様は喜びます。株式会社ファストコーディングでは、こうした読了率改善の実装サポートも行っています。ブログやドキュメントサイトのユーザー体験を良くしたい方は、お問い合わせフォームからご連絡ください。
※本記事は弊社外国人スタッフによる投稿です。言い回しや表現が不十分な個所がありますことご容赦いただきますようお願いいたします。
株式会社ファストコーディング

