タイムライン
縦の連結線とノードで出来事を時系列に並べる見本。現在地のノードだけ藍で強調し、各項目に時刻・見出し・説明を添えます。読み込みで各項目がふわっと現れます。
プレビュー
操作動きのない質感・レイアウトの見本です。
仕様書
- 向く場面
- 配送状況・承認フローの進捗
- 更新履歴・沿革など一方向の並び
- 現在地を 1 つ強調したい手順表示
- 避ける場面
- 分岐や差し戻しがあるフロー
- 10 件を超えて 1 画面に収まらない履歴
- 構成要素
- 縦の連結線
- ノード
- 時刻
- 見出し
- 説明
- 持っている状態
- 通常
- 押下中
- キーボード
操作要素なし(表示のみ)
- 支援技術
ol で順序を伝え、ノードは aria-hidden。現在地の li に aria-current=step と隠しテキスト「現在」を付け、色とリングだけに頼らない。reduced-motion で出現アニメを止め即時表示
- 動き
各項目が 450ms ease-out で下から 6px 浮かび上がり、100ms ずつ遅れて上から順に現れる
デザインの要点
- 縦線は疑似要素でノードの中心(left 6px)を通す。ノードの半径ぶん top/bottom を詰めて隙間を無くす
- 完了は灰の塗り、現在は藍+4px の外輪、未来は白抜き。3 状態を塗り・色・輪の 3 つで分ける
- 出現は 100ms ずつ遅らせて上から順に。同時に出すと時系列の「流れ」が消える。reduced-motion は即時
- 現在地は色だけでなく aria-current=step と「現在」の隠しテキストで示す。時刻表記が無い用途でも判別できる
使いどころ
注文の配送状況、申請の承認フロー、記事の更新履歴など、「時系列に並んだ複数のステップのうち、今どこまで進んだか」を見せる場面に向く。デモはEC注文の配送追跡だが、オンボーディングの進捗表示や、経歴・沿革のような一方向に進む情報の並びにも転用できる。逆に、時系列ではあっても双方向に行き来する状態(下書き⇄公開のような)や、分岐するフロー(承認/差し戻しの両方があるプロセス)には単純な縦一列のタイムラインでは表現しきれず、状態遷移図など別の見せ方が要る。項目数が10件を超えると1画面に収まらずスクロールが長くなるため、直近の数件だけを表示して「すべて見る」で展開する設計と組み合わせるとよい。
仕組み
構造は<ol>のリストで、各<li>にtl-item is-done/is-activeの状態クラスを付けて完了・進行中・未着手を出し分ける。縦線はtl-item::beforeの疑似要素で、left: 6px(ノードの中心に合わせた位置)に2px幅の単色線を敷き、topとbottomの値をノードの半径分だけ内側に寄せることで隣接ノード同士の隙間を線が正確に埋める。ノード(tl-node)は14px角の円で、is-doneは塗りつぶし、is-activeはブランドカラー(#2b50c7)に加えてbox-shadowで外側にもう一段リング状の光彩(0 0 0 4px #eef1fb)を足し、未着手のノードとの差を強めている。読み込み時の出現はtl-contentにtl-revealアニメーションを付け、nth-childごとにanimation-delayを0.05〜0.35秒でずらすことで上から順に現れる効果を出しており、prefers-reduced-motionでは全て即時表示に切り替わる。
実装の注意
落としやすいのは、is-activeの「現在地」をノードの色とbox-shadow、テキスト色(tl-item.is-active .tl-time { color: #2b50c7; })という視覚表現だけで示してしまうこと。それだけだとDOM上にも支援技術向けにも「これが現在のステップだ」という明示的な情報が無く、4件のうちどれが「今」なのかを判別する手掛かりはテキストの内容("14:05"のような時刻表記と"予定"という文言の違い)に頼ることになり、時刻表記を伴わない汎用的な使い方に転用すると判別できなくなる。この見本はis-activeのliにaria-current="step"と隠しテキスト「現在」を持たせてあるので、複製するときはクラスと一緒にこの2つも移すこと。またtl-item::beforeの縦線は最後の項目でdisplay: noneにして消しているが、項目を動的に追加・削除するSPAで使う場合はlast-childの判定がDOM操作のたびに再計算される前提を崩さないよう注意が要る。
アクセシビリティ
<ol>を使っている点は評価できる実装で、リストとして読み上げられるため「4件中の何番目か」が自動的に伝わり、順序性を持つ情報であることも暗黙に示せる。ノードのspan(tl-node)にはaria-hidden="true"が付いており、装飾的な丸印が空の要素として読み上げられることを防いでいる。進行状況を示すパターンとして使えるaria-current属性は、現在地のli要素にaria-current="step"として付けてあり、あわせて視覚的に隠したテキスト(tl-sr)で「現在」の一言を補っているので、色や位置に頼らず現在地を伝えられる。is-activeのクラスを別の項目へ移すときは、aria-currentと隠しテキストも同じ項目へ移す(JSで状態を進める実装にするなら、この3つを1つの関数で同時に切り替える)。リスト構造そのものに意味を持たせられているので、この一手を落とさなければ完成度は保てる。
調整して使う
変更しやすいのは3点。縦線とノードの色(既定は#e6dcc7の線に#c8c2b8の完了ノード)を差し替えれば、ブランドカラーに合わせた印象に調整できる。次に向きで、デモは縦一列だが広い画面では横方向のステップバー(進捗ドットを横に並べる形)に組み替えることもでき、その場合はtl-item::beforeのleft/top/bottomをtop/left/rightに置き換える程度の改修で対応できる。最後に出現演出で、nth-childごとのanimation-delayの間隔(既定0.1秒刻み)を詰めるとキビキビした印象に、広げると余韻のある演出になる。ノードの中に✓やアイコンを入れて「完了」をより明示的に見せるバリエーションも、tl-nodeをdivにしてSVGを子要素として追加するだけで実現できる。
コード(コピーして使えます)
<div class="tl-wrap">
<ol class="tl-list">
<li class="tl-item is-done">
<span class="tl-node" aria-hidden="true"></span>
<div class="tl-content">
<span class="tl-time">09:12</span>
<p class="tl-title">注文を受け付けました</p>
<p class="tl-desc">ご注文の確認メールを送信しました。</p>
</div>
</li>
<li class="tl-item is-done">
<span class="tl-node" aria-hidden="true"></span>
<div class="tl-content">
<span class="tl-time">11:40</span>
<p class="tl-title">商品を準備中</p>
<p class="tl-desc">倉庫で梱包作業を行っています。</p>
</div>
</li>
<li class="tl-item is-active" aria-current="step">
<span class="tl-node" aria-hidden="true"></span>
<div class="tl-content">
<span class="tl-sr">現在: </span><span class="tl-time">14:05</span>
<p class="tl-title">配送センターを出発</p>
<p class="tl-desc">お届け先エリアへ向けて輸送中です。</p>
</div>
</li>
<li class="tl-item">
<span class="tl-node" aria-hidden="true"></span>
<div class="tl-content">
<span class="tl-time">予定</span>
<p class="tl-title">お届け</p>
<p class="tl-desc">本日中のお届けを予定しています。</p>
</div>
</li>
</ol>
</div>