타임라인

Timeline

시간 순서대로 일어난 일들을 점과 세로선으로 이어 보여주는 목록.

다른 이름: Activity feedHistory timelineEvent timeline
···
html
<ol class="tl" id="tl">
  <li data-lit><time datetime="2026-09-20">9월 20일</time><b>주문 접수</b></li>
  <li><time datetime="2026-09-22">9월 22일</time><b>결제 완료</b></li>
  <li><time datetime="2026-09-24">9월 24일</time><b>배송 시작</b></li>
  <li><time datetime="2026-09-26">9월 26일</time><b>배송 완료</b></li>
</ol>
css
.tl{list-style:none;margin:0;padding:0 0 0 18px;width:min(220px,90%);position:relative}
.tl::before{content:"";position:absolute;left:4px;top:5px;bottom:5px;width:2px;background:var(--line)}
.tl li{position:relative;padding-bottom:16px;font-size:11px}
.tl li:last-child{padding-bottom:0}
.tl li::before{content:"";position:absolute;left:-18px;top:2px;width:9px;height:9px;border-radius:50%;background:var(--line);border:2px solid var(--bg);transition:background .3s}
.tl li[data-lit]::before{background:var(--accent)}
.tl time{display:block;color:var(--muted);font-size:10px}
.tl b{color:var(--fg);opacity:.35;transition:opacity .3s}
.tl li[data-lit] b{opacity:1}
js
const items = [...document.querySelectorAll('#tl li')];
let n = 1;
function paint() { items.forEach((li, i) => li.toggleAttribute('data-lit', i < n)); }
paint();
setInterval(() => { n = n >= items.length ? 1 : n + 1; paint(); }, 1100);

순서가 의미를 가지므로 마크업은 <ol>로 하고, 각 사건의 시각은 <time datetime="2026-01-01">처럼 기계가 읽을 수 있는 형식으로 명시합니다. 점과 선은 배경 이미지나 border로 장식만 하면 되고 별도의 ARIA 역할은 필요 없습니다.

스테퍼와 헷갈리기 쉽지만 방향과 확정성이 다릅니다. 스테퍼는 "배송지 → 결제 → 완료"처럼 미래를 향해 정해진 순서로 진행 중인 몇 단계를 보여주지만, 타임라인은 이미 일어난 임의 개수의 사건(커밋 로그, 주문 이력, 알림 피드)을 과거 방향으로 기록합니다. 브레드크럼과는 아예 목적이 다릅니다 — 브레드크럼은 계층 위치를, 타임라인은 시간을 다룹니다.

실시간으로 새 사건이 추가되는 피드라면 목록 컨테이너에 aria-live="polite"를 둬서 새 항목이 조용히 알려지게 합니다.