確認ステップ付きフォーム
フォーム / パターン集トップ
入力→確認→完了の3段。確認画面は入力欄を置かず、値を文章で見せる
プレビュー#
コピーする#
上のプレビューでつまみを動かし、「生成する」で調整を反映したコードを作ってからコピーしてください。下の欄は生成の元になる型で、直接コピーするものではありません。
<!-- 1画面目。入力。ここが受け持つのは段の表示と「確認へ」だけなので h1 は
置かない。入力画面の見出しは骨格(「フォーム基本レイアウト」)が持つ -->
<form class="form-confirm" action="/contact/confirm/" method="post" novalidate>
<ol class="form-confirm__steps" aria-label="進行">
<li aria-current="step">入力</li><li>確認</li><li>完了</li>
</ol>
<p class="form-note">「必須」の付いた項目は入力が必要です。</p>
<div class="field">
<label for="fc-name">お名前 <span class="req" aria-hidden="true">必須</span></label>
<input id="fc-name" name="name" type="text" autocomplete="name"
aria-describedby="fc-name-msg" required>
<p class="field__error" id="fc-name-msg" hidden></p>
</div>
<div class="field">
<label for="fc-mail">メール <span class="req" aria-hidden="true">必須</span></label>
<input id="fc-mail" name="email" type="email" autocomplete="email"
aria-describedby="fc-mail-msg" required>
<p class="field__error" id="fc-mail-msg" hidden></p>
</div>
<div class="field">
<label for="fc-body">内容 <span class="req" aria-hidden="true">必須</span></label>
<textarea id="fc-body" name="body" rows="4" aria-describedby="fc-body-msg" required></textarea>
<p class="field__error" id="fc-body-msg" hidden></p>
</div>
<p class="form-confirm__actions">
<!-- 入力画面の塗りはこの1つ。基本形・章分け・エラー表示から
持ち込んだ送信ボタンは、ここで消す -->
<button class="button button--primary" type="submit">確認へ</button>
</p>
</form>
<!-- 2画面目。確認。入力欄は置かず、送るものをそのまま読ませる。
画面が入れ替わるので、この画面の h1 はこちらが持つ -->
<form class="form-confirm" action="/contact/send/" method="post">
<ol class="form-confirm__steps" aria-label="進行">
<li>入力</li><li aria-current="step">確認</li><li>完了</li>
</ol>
<h1 class="form-confirm__title">この内容で送ります</h1>
<dl class="form-confirm__answers">
<div class="form-confirm__answer">
<dt>お名前</dt>
<dd>常盤野 千尋</dd>
</div>
<div class="form-confirm__answer">
<dt>メール</dt>
<dd>chihiro@example.com</dd>
</div>
<div class="form-confirm__answer">
<dt>内容</dt>
<dd>深煎りの豆を200g、月に2袋で申し込みたいです。</dd>
</div>
</dl>
<!-- 値はここで持ち回す。disabled にした欄は送信されないので hidden を使う -->
<input type="hidden" name="name" value="常盤野 千尋">
<input type="hidden" name="email" value="chihiro@example.com">
<input type="hidden" name="body" value="深煎りの豆を200g、月に2袋で申し込みたいです。">
<p class="form-confirm__actions">
<button class="button button--primary" type="submit">送信する</button>
<button class="button button--ghost" type="submit"
formaction="/contact/" formnovalidate>入力へ戻る</button>
</p>
</form>
.form-confirm {
display: grid;
gap: var(--space-5);
max-inline-size: 32rem;
}
.form-confirm__steps {
display: flex;
gap: var(--space-4);
margin: 0;
padding: 0;
list-style: none;
font-size: var(--text-sm);
color: var(--color-text-muted);
}
/* いま出している画面の項目にだけ aria-current を付け、見た目もその属性で切り替える。
別のところで色を変えると、見えている段と読み上げる段がずれる */
.form-confirm__steps [aria-current="step"] {
color: var(--color-accent-text);
font-weight: 700;
}
.form-note {
margin: 0;
font-size: var(--text-sm);
color: var(--color-text-muted);
}
.field {
display: grid;
gap: var(--space-2);
}
.field label {
font-size: var(--text-sm);
font-weight: 700;
}
.req {
font-weight: 400;
font-size: var(--text-sm);
color: var(--color-text-muted);
}
.field input,
.field textarea {
inline-size: 100%;
font: inherit;
padding: var(--space-2) var(--space-3);
border: 1px solid var(--color-border);
background: var(--color-bg);
color: var(--color-text);
min-block-size: 2.75rem;
}
.field textarea {
min-block-size: 6rem;
resize: vertical;
}
/* 不備が出たときだけ文字が入る。名前は全パターン共通の .field__error */
.field__error {
margin: 0;
font-size: var(--text-sm);
color: var(--color-danger);
}
.field--error input,
.field--error textarea {
border-color: var(--color-danger);
outline-color: var(--color-danger);
}
/* 確認画面でただ1つの見出し。入力画面の h1 は骨格が、完了画面の h1 は
「送信完了画面」が、それぞれ自分で持つ */
.form-confirm__title {
margin: 0;
font-size: var(--text-xl);
line-height: var(--leading-heading);
}
.form-confirm__answers {
margin: 0;
border-block-start: 1px solid var(--color-border);
}
.form-confirm__answer {
display: grid;
grid-template-columns: 7rem minmax(0, 1fr);
gap: var(--space-4);
padding-block: var(--space-3);
border-block-end: 1px solid var(--color-border);
}
.form-confirm__answer dt {
font-size: var(--text-sm);
color: var(--color-text-muted);
}
.form-confirm__answer dd {
margin: 0;
}
@media (max-width: 30rem) {
.form-confirm__answer {
grid-template-columns: minmax(0, 1fr);
gap: var(--space-1);
}
}
.form-confirm__actions {
display: flex;
flex-wrap: wrap;
gap: var(--space-3);
margin: 0;
}
/* .button の基底と派生は「出発点のCSS」にある */
確認する#
- ステップの aria-current="step" が、いま出している画面と一致している
- 確認画面に操作できる入力欄がない(値は文章で見せ、hidden で持ち回す)
- 値を持ち回すのに disabled を使っていない(disabled の欄は送信されない)
- 確認画面の h1 はこちらが持ち、1画面目は持たない(入力画面の見出しは骨格が持つ)
- 「入力へ戻る」で入力した値が消えない
- 塗りのボタンが1画面に1つ(入力は「確認へ」、確認は「送信する」)