続・table要素でお問い合わせフォームを作成する方法

前回の続きですが、今回はtable
要素で作成したお問い合わせフォームにさらに装飾を加えて、より分かりやすいフォームに仕上げていきたいと思います。
table要素でお問い合わせフォームを作成する方法
私は個人のブログに加えて会社のホームページも作成していますが、コーポーレートサイトで重要なのがこのお問い合わせフォームです。お客様からの反響やお問い合わせをもれなくキャッチするためには、お客様にとって分かりやすく、入力し […]

https://neatdesignjournal.com/inquiry-form-1/

まずは完成品をご覧ください。
See the Pen Inquiry-2 by ryskyshd (@ryskyshd) on CodePen.
HTML
<table class="inquiry">
<tbody>
<tr>
<th>
<label for="your_name">
<span class="label_required">必須</span>
<span class="label_item">お名前</span>
</label>
</th>
<td>
<input type="text" id="your_name" name="your_name" />
<span class="notice">例)山下 太郎</span>
</td>
</tr>
<tr>
<th>
<label for="your_tel">
<span class="label_optional">任意</span>
<span class="label_item">電話番号</span>
</label>
</th>
<td>
<input type="tel" id="your_tel" name="your_tel" />
<span class="notice">例)0123456789</span>
</td>
</tr>
<tr>
<th>
<label for="your_email">
<span class="label_required">必須</span>
<span class="label_item">メールアドレス</span>
</label>
</th>
<td>
<input type="email" id="your_email" />
<span class="notice">例)yamashita@sample.com</span>
</td>
</tr>
<tr>
<th>
<label for="your_message">
<span class="label_optional">任意</span>
<span class="label_item">お問い合わせ内容</span>
</label>
</th>
<td>
<textarea id="your_message"></textarea>
</td>
</tr>
</tbody>
</table>
項目名をlabel要素で囲む
<label for="your_name">
<span class="label_required">必須</span>
<span class="label_item">お名前</span>
</label>
項目名の箇所ですが、それぞれlabel
要素で囲むようにマークアップしました。こうすることで、項目名をクリックすると自動的に入力欄にフォーカスされるためアクセシビリティ的に良くなります。label
要素のfor
属性に、後に出てくるinput
要素のid
属性の値と同じ値を入れておくことで先の連動が実現できます。
入力欄に注釈を入れる
<input type="text" id="your_name" name="your_name" />
<span class="notice">例)山下 太郎</span>
続いて入力欄ですが、先述のとおりlabel for="..."
で指定した値をinput id="..."
にも同じものを指定します。また、入力欄の下には注釈を入れるようにします。input
要素のplaceholder
属性でもいいんですが、途中で見えなくなったりしてアクセシビリティ的に問題あるので今回のようにした方が丁寧だと思います。
CSS
.inquiry {
--color-gray: #7c8187;
--color-pale-gray: #c7ccd1;
--color-light: #f9fbfc;
--color-key: #4ba3f2;
--color-accent: #0077e6;
--color-accent-dark: #004ea2;
--color-required: #f39800;
--color-optional: #8ec31f;
inline-size: 100%;
border: 1px solid var(--color-pale-gray);
border-collapse: collapse;
& tr {
border-block-end: 1px solid var(--color-pale-gray);
&:last-child {
border-block-end: none;
}
}
:is(th, td) {
display: block;
padding: 1rem;
@media (width >= 1024px) {
display: table-cell;
}
}
& th {
--th-inline-size: 30%;
text-align: left;
background-color: rgb(from var(--color-pale-gray) r g b / 0.2);
border-block-end: 1px solid var(--color-pale-gray);
@media (width >= 1024px) {
inline-size: var(--th-inline-size);
border-inline-end: 1px solid var(--color-pale-gray);
}
& label {
display: flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
:is(.label_required, .label_optional) {
color: var(--color-light);
font-size: 0.875rem;
padding-block: 0.125rem;
padding-inline: 0.75rem;
border-radius: 4px;
}
.label_required {
background-color: var(--color-required);
}
.label_optional {
background-color: var(--color-optional);
}
}
}
& td {
@media (width >= 1024px) {
inline-size: calc(100% - var(--th-inline-size));
}
.notice {
color: var(--color-gray);
font-size: 0.875rem;
}
}
}
input {
&:is([type="text"], [type="tel"], [type="email"]) {
padding-block: 1rem;
padding-inline: 0.75rem;
inline-size: 100%;
font-size: 1rem;
background-color: rgb(from var(--color-pale-gray) r g b / 0.2);
border: none;
border-radius: 2px;
box-sizing: border-box;
&:focus {
outline: 2px solid var(--color-accent);
}
}
}
textarea {
padding-block-start: 1rem;
padding-block-end: 10rem;
padding-inline: 0.75rem;
display: block;
inline-size: 100%;
font-size: 1rem;
line-height: 1.5;
background-color: rgb(from var(--color-pale-gray) r g b / 0.2);
border: none;
border-radius: 2px;
box-sizing: border-box;
resize: vertical;
&:focus {
outline: 2px solid var(--color-accent);
}
}
/* 装飾用 */
body {
margin-block: 10svh;
margin-inline: auto;
max-inline-size: min(90vw, 960px);
}
基本的には前回の分にlabel
要素が加わった感じです。
label部分
label {
display: flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
:is(.label_required, .label_optional) {
color: var(--color-light);
font-size: 0.875rem;
padding-block: 0.125rem;
padding-inline: 0.75rem;
border-radius: 4px;
}
.label_required {
background-color: var(--color-required);
}
.label_optional {
background-color: var(--color-optional);
}
}
label
要素の直下には、label_required
またはlabel_optional
というclass名を付与した「必須」とか「任意」と表示するラベルと項目名があります。この2つの要素を横並びにするためにdisplay: flex;
を指定します。ただ、そもそもspan
でマークアップされているので何もしなくても横並びなんですが、gap
を指定して少し間隔を空けた方が見やすいのでこうしています。でも、単純に間隔を空けるだけなら.label_item
にmargin-inline-start
などを指定する方法でもいいと思います。あとは文字の色、サイズ、余白などの見た目を調整してそれぞれの背景色を指定すればOKです。
注釈部分
.notice {
color: var(--color-gray);
font-size: 0.875rem;
}
注釈部分は文字の色を少し薄めにしてサイズを小さくしているだけです。この注釈部分があるかないかでアクセシビリティに大きな差が生まれると思いますので、ぜひとも実装したい部分ですね。
細かい調整
その他にも、前回の分からもう少し細かい部分での調整を入れていますのでザッとご紹介します。
th
とtd
の横幅指定方法input
要素とtextarea
要素の:focus
時のスタイル
まず、ビューポートが1024px
以上の時のth
とtd
の横幅についてなんですが、合計で100%
になるようにするので片方のサイズを変えても自動的にもう一方のサイズが変わるようにカスタムプロパティを使って計算式(calc
関数)を入れました。
/* thの横幅を変数化 */
--th-inline-size: 30%;
/* tdの横幅はcalc関数で自動計算 */
inline-size: calc(100% - var(--th-inline-size));
これで後々th
のサイズだけ変更すれば良いことになります。次にinput
要素とtextarea
の:focus
時のスタイルですが、
&:focus {
outline: 2px solid var(--color-accent);
}
このように、擬似クラスを使ってフォーカス時のアウトラインについてスタイリングしています。デフォルトの状態でもアウトラインは表示されるのですが、ブラウザによってアウトラインの色が違うこともあるようなのであえて明示する形にしています。
最後に
余談ですが、私が作成している会社のホームページは不動産会社のホームページなので、CodePenで紹介しているサンプルコードの中には不動産関連の用語が出てくることがあります。その辺はご了承ください。次回はtable
要素を使わずに実装していく方法もご紹介したいと思います。最終的にはWordPressのContact Form 7プラグインで使えるコードに変換していきたいなと考えていますので、良かったら最後までお付き合いください。