このページの中身

確認ステップ付きフォーム

フォーム / パターン集トップ

入力→確認→完了の3段。確認画面は入力欄を置かず、値を文章で見せる

プレビュー#

この枠の中は出発点のCSSの上で動いています。下のコードは、そちらを先に貼ってから足してください。

コピーする#

上のプレビューでつまみを動かし、「生成する」で調整を反映したコードを作ってからコピーしてください。下の欄は生成の元になる型で、直接コピーするものではありません。

<!-- 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」にある */

確認する#

関連#

この資料は、Webサイトを作るときに引くためのものです。 何のために作ったか。作っているのは AK²Lab。