ライブデモ Live Demo
進捗トラックの幅はアクティブステップインデックスから算出され、CSS width トランジションで適用されます。ドットは `is-active` / `is-complete` クラスで塗りつぶし状態を切り替えます。
The progress track width is derived from the active step index and applied to a CSS width transition. Dots receive `is-active` / `is-complete` classes to toggle their filled state.
AI向け説明 AI Description
`N-002` はフレックスレイアウトのステッパーに、絶対位置の進捗トラックを組み合わせます。アクティブステップのインデックスからトラック幅を算出し、CSS `width` トランジションで適用します。ドットは `is-active` / `is-complete` クラスで状態を制御します。
`N-002` combines a flex-based stepper with an absolute-positioned progress track. Track width is derived from the active step index and applied via a CSS `width` transition. Dot states are controlled by `is-active` / `is-complete` classes.
調整可能パラメータ Adjustable Parameters
- step count — ステップ数を調整してバリエーション作成 adjust step count for different workflows
- transition duration — `transition-duration` で塗りつぶし速度調整 adjust `transition-duration` for faster/slower fills
- labels — ステップタイトルやツールチップを追加 attach step titles or tooltips
- reduced motion — モーション制限下で瞬時変化に切り替え switch to instant changes under reduced motion
実装 Implementation
HTML + CSS + JS
<div class="stepper" data-stepper>
<div class="stepper__track"></div>
<div class="stepper__progress"></div>
<button class="stepper__dot is-active" data-step="1">1</button>
<button class="stepper__dot" data-step="2">2</button>
<button class="stepper__dot" data-step="3">3</button>
<button class="stepper__dot" data-step="4">4</button>
</div>
<style>
.stepper {
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
}
.stepper__track {
position: absolute;
top: 50%;
left: 32px;
right: 32px;
height: 2px;
background: rgba(255, 255, 255, 0.2);
transform: translateY(-50%);
}
.stepper__progress {
position: absolute;
top: 50%;
left: 32px;
height: 2px;
background: linear-gradient(90deg, #5c6ac4, #22d3ee);
transform: translateY(-50%);
transition: width 0.35s ease;
}
.stepper__dot {
width: 48px;
height: 48px;
border-radius: 50%;
border: 2px solid rgba(255, 255, 255, 0.35);
position: relative;
cursor: pointer;
}
.stepper__dot.is-active { border-color: #22d3ee; color: #22d3ee; }
.stepper__dot.is-complete::after {
content: "";
position: absolute;
inset: 6px;
border-radius: 50%;
background: linear-gradient(135deg, #5c6ac4, #22d3ee);
opacity: 1;
}
</style>
<script>
const dots = document.querySelectorAll(".stepper__dot");
const progress = document.querySelector(".stepper__progress");
dots.forEach((dot, i) => {
dot.addEventListener("click", () => goToStep(i));
});
function goToStep(index) {
dots.forEach((d, i) => {
d.classList.toggle("is-complete", i < index);
d.classList.toggle("is-active", i === index);
});
const first = dots[0], current = dots[index];
progress.style.width =
(current.offsetLeft + current.offsetWidth / 2) -
(first.offsetLeft + first.offsetWidth / 2) + "px";
}
</script>
React (JSX + CSS)
// react/N-002.jsx
import { useState, useRef, useEffect } from "react";
import "./N-002.css";
export default function StepperDotProgress({ steps = 4 }) {
const [active, setActive] = useState(0);
const stepperRef = useRef(null);
const [progressWidth, setProgressWidth] = useState(0);
useEffect(() => {
const dots = stepperRef.current?.querySelectorAll(".stepper__dot");
if (!dots?.length) return;
const first = dots[0], current = dots[active];
setProgressWidth(
current.offsetLeft + current.offsetWidth / 2 -
(first.offsetLeft + first.offsetWidth / 2)
);
}, [active]);
return (
<div className="stepper" ref={stepperRef}>
<div className="stepper__track" />
<div className="stepper__progress" style={{ width: progressWidth }} />
{Array.from({ length: steps }).map((_, i) => (
<button
key={i}
className={`stepper__dot ${i < active ? "is-complete" : ""} ${i === active ? "is-active" : ""}`}
onClick={() => setActive(i)}
>
{i + 1}
</button>
))}
</div>
);
}
AIへの指示テンプレート AI Prompt Template
以下のテンプレートをコピーしてAIアシスタントに貼り付けると、このパターンの実装を依頼できます。 Copy the template below and paste it into your AI assistant to request an implementation of this pattern.
注意とバリエーション Notes & Variations
同じ構造でラベル付きタイムラインや2段ステッパーも作成できます。マークアップを変更せずに `aria-current="step"` などのARIA状態でアクセシビリティを向上させられます。
The same structure powers labeled timelines or dual-row steppers. Add ARIA states such as `aria-current="step"` to enhance accessibility while keeping the markup unchanged.