Web制作実務役立ち

フォームのデフォルトCSSを初期化してオリジナルフォームをアクセシビリティ配慮で作る方法【リセットCSS】

フォームのデフォルトCSSを初期化してオリジナルフォームをアクセシビリティ配慮で作る方法【リセットCSS】
本ページにはプロモーションが含まれています。
まさひろくん

フォームの見た目を全ブラウザで統一したい、どうすればいいのか教えて欲しい。

こんな疑問に答えます。

まずは以下のCSSを一切当てていない、HTMLだけのフォームを見てみて下さい。

全然細部が違います笑

やばいなーと思うのは、なんとMacのSafariとiPhoneのSafariでも表示が異なるのです!!

これを全部同じ表示にするのが、「デザインカンプから正確にコーディングするコーダーの使命」というわけです。

この記事ではフォームパーツのデフォルトCSSを初期化した上で、オリジナルデザインにする方法をサンプルを元に解説します。

しょーご

この記事を書いたのは
しょーご@samurabrass

このブログ「しょーごログ」の運営者。2018年からエンジニアとしてサイト制作やシステム開発を行いつつ、ブログとYouTubeで情報発信を行っている。駆け出しエンジニアのコーディング課題添削も行う。

フォームコーディングの注意点

リセットCSSについて

各ブラウザにはデフォルトでCSSがついていますが、これを初期化するために、通常「リセットCSS」が用いられます。

個人的に好きな「destyle.css」もフォームのスタイルを全て消すので、まっさらな状態になります。

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/destyle.css@4.0.0/destyle.css" />

今回はリセットCSSを導入していない前提になるので、個々人によって表示が記事通りにならない可能性がありますが、その場合はご自身のリセットCSSの初期化処理と見比べてみて下さい。

キーボードだけで操作できるフォームにすべき

今回紹介するコードはアクセシビリティに配慮して、全要素にタブで移動しつつ、キーボードだけで入力完了できる形式にしています。

マウスが使えない人もいるので、そういった方向けの配慮です。

今回のフォームの見本

フォームに関係ない見た目整理のコードは書いていません。利用する際は別個見た目整理のCSSコードを付け加えてください。

See the Pen アクセシビリティ・フォーム by samuraibrass (@samuraibrass) on CodePen.

inputのブラウザデフォルトCSS初期化

input系は以下のコードでOKです。全部リセットすると見えなくなるので、borderだけつけていますが、リセット部分以外はお好みで。

<input type="text" class="input-text" placeholder="name">
<input type="email" class="input-email" name="" id="" placeholder="sample@gmail.com">
.input-text, .input-email, .input-file, .input-submit {
  padding: 0;
  border: none;
  border-radius: 0;
  outline: none;
  background: none;
  box-shadow: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  /* リセットじゃない部分 */
  border: 1px solid rgba(0, 0, 0, 0.16);
}
.input-text:focus,
.input-email:focus {
  outline: 2px solid #3498db;
  /* 自由な色に変更可能 */
  outline-offset: 0;
}

アクセシビリティの観点で、特にキーボードのみのユーザーの場合、focusのアウトラインを保持するか、スタイル設定することが重要です。

フォームのデフォルトCSSを初期化してオリジナルフォームを作る方法【リセットCSS】

outline: none;にする場合は、代わりにborderをつけてください。

チェックボックス(checkbox)のブラウザデフォルトCSSの初期化と疑似要素

オリジナルデザインを再現する上で、チェックボックスはかなりトリッキーです。

標準で出力されるチェックボックスは見えなくして独自のチェックボックスを擬似要素で作るのですが、キーボード操作などのアクセシビリティにも考慮する必要があります。

フォームのデフォルトCSSを初期化してオリジナルフォームを作る方法【リセットCSS】

検索上位記事のいくつかに見られる、input[type=”checkbox”]display:none で非表示にするのはご法度です。

この実装では<input>要素にフォーカルを当てることができないため、Tabキーで選択するようなキーボード操作ができない状態である上に、スクリーンリーダーがチェックボックスを認識できないので、アクセシビリティが悪いです。

なので、代わりにopacity:0;<input>を非表示にします。

<label class="check-label"><input class="check-test" type="checkbox" name="check-name"><span class="check-label-span">チェック1</span></label>
<label class="check-label"><input class="check-test" type="checkbox" name="check-name"><span class="check-label-span">チェック2</span></label>
<label class="check-label"><input class="check-test" type="checkbox" name="check-name"><span class="check-label-span">チェック3</span></label>
.check-test {
  position: absolute;
  opacity: 0;
  z-index: -1;
}

.check-label {
  position: relative;
  display: inline-block;
  padding-left: 30px;  /* カスタムチェックボックスにスペースを確保 */
  margin-bottom: 5px;
  cursor: pointer;
}

/* Custom Checkbox Design */
.check-label-span::before {
  content: "";
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2px solid #000; /* Border color */
  border-radius: 4px; /* Optional: for rounded corners */
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}

/* Custom Checkbox Checked State */
.check-test:checked + .check-label-span::before {
  border-color: #3498db; /* Border color when checked */
}

.check-test:checked + .check-label-span::after {
  content: "";
  display: block;
  width: 5px;
  height: 10px;
  border: solid #000;
  border-width: 0 2px 2px 0;
  position: absolute;
  top: 50%;
  left: 8px;  /* Adjusted position */
  transform: translateY(-50%) rotate(45deg);
}

/* Focus State */
.check-test:focus + .check-label-span::before {
  outline: 2px solid #3498db; /* Outline color when focused */
}

このコードでは、:focus疑似クラスを使用して、フォーカス時に<input>要素の隣の<span>要素の周囲にアウトラインを表示します。これで、キーボード操作でフォーカスが適切に表示されます。

ラジオボタン(radio)のブラウザデフォルトCSSの初期化と疑似要素

オリジナルデザインの場合、ラジオボタンもアクセシビリティに配慮する必要があります。

標準で出力されるラジオボタンは見えなくして独自のラジオボタンを擬似要素で作るのですが、キーボード操作などのアクセシビリティにも考慮する必要があります。

フォームのデフォルトCSSを初期化してオリジナルフォームを作る方法【リセットCSS】
<label class="radio-label"><input class="radio-test" type="radio" name="radio-name"><span
class="radio-label-span">ラジオ1</span></label>
<label class="radio-label"><input class="radio-test" type="radio" name="radio-name"><span
class="radio-label-span">ラジオ2</span></label>
<label class="radio-label"><input class="radio-test" type="radio" name="radio-name"><span
class="radio-label-span">ラジオ3</span></label>
/* Hide default radio button */
.radio-test {
  position: absolute;
  opacity: 0;
  z-index: -1;
}

/* Label positioning context */
.radio-label {
  position: relative;
  display: inline-block;
  padding-left: 30px;  /* Space for the custom radio button */
  margin-bottom: 5px;
  cursor: pointer;
}

/* Custom Radio Button Design */
.radio-label-span::before {
  content: "";
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 2px solid #000; /* Border color */
  border-radius: 50%; /* Rounded corners for radio button */
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}

/* Custom Radio Button Checked State */
.radio-test:checked + .radio-label-span::after {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  background-color: #000; /* Fill color when checked */
  border-radius: 50%; /* Rounded corners for checked state */
  position: absolute;
  top: 50%;
  left: 7px;  /* Centering the filled circle */
  transform: translateY(-50%);
}

/* Focus State */
.radio-test:focus + .radio-label-span::before {
  outline: 2px solid #3498db; /* Outline color when focused */
}

中の黒丸の位置はリセットCSSなどによりずれる可能性があるので、調整してください。

セレクトボックス(select)のブラウザデフォルトCSSの初期化

ラジオボタンもかなりブラウザ間の差異が大きいです。

特に、アローアイコンがかなりやっかいなのです。

select-container::after疑似要素を使用して、CSSでアローアイコンを作成し、このアローアイコンは、ボーダーを使用して作成しています。

<div class="select-container">
  <select class="select-box" name="都道府県を選んで下さい。" id="">
    <option value="sample">サンプル1</option>
    <option value="sample">サンプル2</option>
    <option value="sample">サンプル3</option>
    <option value="sample">サンプル4</option>
    <option value="sample">サンプル5</option>
  </select>
</div>
/* Style for the select box container */
.select-container {
  position: relative;
  display: inline-block;
  width: 200px; /* Set a width */
  margin-bottom: 20px;
}

/* Style for the select box */
.select-box {
  padding: 10px;
  border: 2px solid #000;
  border-radius: 4px;
  outline: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: 100%; /* Make it fill the container */
  font-size: 16px;
  color: #000;
}

/* Arrow icon using a pseudo-element */
.select-container::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 10px;
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 5px solid #000;
  transform: translateY(-50%);
}

/* Focus State */
.select-box:focus {
  border-color: #3498db; /* Border color when focused */
}

optionのデザインを変えることは不可能なので、ここのオリジナルデザインが来たら相談してください。

テキストエリア(textarea)のブラウザデフォルトCSSの初期化

テキストエリアの初期化はシンプルです。

<textarea class="textarea-box" rows="5" cols="30"></textarea>
/* Style for the text area */
.textarea-box {
  width: 100%; /* Set the width */
  padding: 10px; /* Set padding */
  border: 2px solid #000; /* Set border */
  border-radius: 4px; /* Optional: for rounded corners */
  font-size: 16px; /* Set font size */
  resize: vertical; /* Allow vertical resize */
  outline: none; /* Remove outline */
  box-sizing: border-box; /* Include border and padding in the element's dimensions */
  margin-bottom: 20px;
}

送信ボタン(input submit)のブラウザデフォルトCSSの初期化

ボタンも癖がすごいですが、制御は容易です。

送信ボタンの無いフォームは存在しないので、デフォルトCSS初期化→オリジナル化の流れを必ずマスターしておきましょう!

<input type="submit" class="input-submit" value="送信する">
/* Style for the submit button */
.input-submit {
  padding: 10px 20px; /* Set padding */
  border: none; /* Remove border */
  border-radius: 4px; /* Optional: for rounded corners */
  background-color: #3498db; /* Set background color */
  color: #fff; /* Set text color */
  font-size: 16px; /* Set font size */
  cursor: pointer; /* Set cursor to pointer */
  transition: background-color 0.3s; /* Optional: for smooth color transition */
  text-align: center;
}

/* Hover State */
.input-submit:hover {
  background-color: #2980b9; /* Darken background color when hovered */
}

/* Active State */
.input-submit:active {
  background-color: #1c598a; /* Darken background color when active */
}

/* Focus State */
.input-submit:focus {
  outline: none; /* Remove outline */
  box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.5); /* Add a soft outline */
}

ファイル添付(input file)のブラウザデフォルトCSSの初期化

さて、最後の難関がinput type=”file”ですね。これが鬼門すぎる…

これはCSSだけでなんとかするのは不可能なので、JSを使用します。

また、選択したファイルをクリアするボタンも必要なので、追加しました。

オリジナルデザインに対応するために、<button>要素を使用し、そのクリックイベントで<input type="file">要素のclickイベントをプログラム的に発火させることで、ファイル選択ダイアログを開くことができます。

<div class="custom-file-upload">
  <input type="file" class="input-file" id="fileInput" aria-label="ファイルを選択">
  <button type="button" id="fileLabel" onclick="triggerFileInput()">ファイルを選択</button>
  <button type="button" onclick="clearFile()">クリア</button>
</div>
.custom-file-upload {
  position: relative;
  display: inline-block;
}

.input-file {
  display: none;
}

.custom-file-upload button {
  padding: 10px;
  border: 2px solid #000;
  background-color: #f0f0f0;
  border-radius: 4px;
  cursor: pointer;
  color: #000;
}

.custom-file-upload button:hover {
  background-color: #d0d0d0;
}

.custom-file-upload button:focus {
  border-color: #3498db; /* Border color when focused */
  box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.5); /* Add a soft outline */
}
const fileInput = document.getElementById('fileInput');
    const fileLabel = document.getElementById('fileLabel');

    function triggerFileInput() {
        fileInput.click();
    }

    fileInput.addEventListener('change', () => {
        const fileName = fileInput.files[0] ? fileInput.files[0].name : 'ファイルを選択';
        fileLabel.textContent = fileName;
    });

    function clearFile() {
        fileInput.value = '';
        fileLabel.textContent = 'ファイルを選択';
    }

このコードでは、”ファイルを選択”ボタンのonclick属性にtriggerFileInput関数を割り当てています。

この関数は、<input type="file">要素のclickイベントをプログラム的に発火させ、ファイル選択ダイアログを開きます。

そして、”クリア”ボタンを使って選択されたファイルをクリアできます。

フォームのCSS初期化→オリジナルに成功すると…

フォントがバラバラだったので、フォントファミリーを指定した結果、以下の統一することに成功しました。

しょーご

いや〜大変ですなぁ…まあ一回雛形できたらコピペしてたらいいですからね…

Safariでラジオボタンとチェックボックスにフォーカスが当たらない場合

「Safari→設定→詳細」から、Tabキーを押した時に〜」をチェックできればOK。

しょーご

ユーザー側に設定してもらわないとフォーカスできないのに違和感あるけど。。。

まあフォーカスが必要なユーザーなら設定してますかね…^^;

アクセシビリティに配慮したフォームコーディングを

フォームのコーディングはかなりレビューやクライアントに指摘を受けやすい場所です。

なぜなら、サイト内で売上に最も近い場所だからです。

また、今回とは別にバリデーションだったり、EFO(入力フォーム最適化)なんてのもあったりするので、どんどんコーディングスキルを高めていきましょう。

全部入力しないと送信できない処理はこちらから

フォームに送信機能を付ける方法はこちら

即戦力になれるコーディング課題

HTML初心者からWordPress実案件レベルまでのコーディング演習課題を「専用ページ」にて公開しています。

デザインカンプからのコーディング練習課題【オリジナルポートフォリオを準備できるようになりました】
  1. Figma,Photoshopデザインからのコーディング
  2. サーバーアップロードでサイト公開
  3. プロによる最大3回の表示確認特典
  4. レビュー返しは爆速
  5. 2024年にデザイン刷新!被らないポートフォリオ

初級編」は初めてデザインからコーディングする方向け
中級編」はJavaScriptやjQueryの練習
上級編」はWordPressの実案件を模擬体験できるレベル感にしています。

中級者の方には高難易度課題を詰め合わせた「即戦力セット」も出しています。

全課題で「実務レベルの、プロの厳しいレビュー」を受けられるようにしています。

また、2024年には随時デザインの刷新をしており、完全リニューアル!!

他者と差をつけられるポートフォリオが準備できます!

コーディング課題 中級 中級Ex
しょーご

制作会社も使用する専用レビューツールで分かりやすく添削していきます!

基本的に「まとめて購入」していただくとかなりお得になります↓

コーディング課題
まとめて購入

全部盛りこちらから
中級以上こちらから
即戦力編こちらから

コーディングは書籍だけではなかなか実力がつかないので、ぜひ腕試しにご利用ください!!

\課題の購入はこちらから/

また、超実践編という鬼のようなコースもあるので、ほぼ実案件と同じ厳しい環境でコミュニケーション面までレビュー受けたい方がいれば、是非。

超実践編バナー

超実践編をとりあえず見てみる

あなたに是非読んでほしい記事です!