タイムライン
縦の連結線とノードで出来事を時系列に並べる見本。現在地のノードだけ藍で強調し、各項目に時刻・見出し・説明を添えます。読み込みで各項目がふわっと現れます。
プレビュー
操作動きのない質感・レイアウトの見本です。
使いどころ
注文の配送状況、申請の承認フロー、記事の更新履歴など、「時系列に並んだ複数のステップのうち、今どこまで進んだか」を見せる場面に向く。デモは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"のような時刻表記と"予定"という文言の違い)に頼っている状態で、時刻表記を伴わない汎用的な使い方に転用すると判別できなくなる。またtl-item::beforeの縦線は最後の項目でdisplay: noneにして消しているが、項目を動的に追加・削除するSPAで使う場合はlast-childの判定がDOM操作のたびに再計算される前提を崩さないよう注意が要る。
アクセシビリティ
<ol>を使っている点は評価できる実装で、リストとして読み上げられるため「4件中の何番目か」が自動的に伝わり、順序性を持つ情報であることも暗黙に示せる。ノードのspan(tl-node)にはaria-hidden="true"が付いており、装飾的な丸印が空の要素として読み上げられることを防いでいる。一方で、進行状況を示すパターンとして本来使えるaria-current属性(例えばaria-current="step")が現在地のli要素に付いていないため、「現在のステップである」という状態は前述のとおりテキストの文脈でしか伝わらない。改善するなら、is-activeのliにaria-current="step"を追加し、可能であれば視覚的に隠したテキストで「現在」の一言を補うと、色や位置に頼らず現在地を伝えられる。リスト構造そのものは既に意味を持たせられているので、この一手を足すだけで完成度が上がる。
調整して使う
変更しやすいのは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">
<span class="tl-node" aria-hidden="true"></span>
<div class="tl-content">
<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>