フォームへの高度なスタイル設定 - ウェブ開発を学ぶ

フォームへの高度なスタイル設定
===============

* 前のページ
* Overview: Forms
* 次のページ

この記事では、スタイル設定がより難しい、「不良」「劣悪」に分類される種類のフォームコントロールにスタイル設定するために、 CSS で何ができるかを見ていきます。前の記事で見たように、テキストフィールドやボタンでの CSS 使用はまったく問題がありません。ここからは、ウェブフォームへのスタイル設定の闇の部分を見ていきます。

|  |  |
| --- | --- |
| 前提条件: |
 基本的なコンピューターリテラシーと、
 HTML および
 CSS に対する基本的な理解。
  |
| 目的: | フォームのどの部分をスタイル設定するのが難しいのか、またなぜなのかを理解する。そこをカスタマイズするのに何ができるかを学ぶ。 |

始める前に、2 種類の HTML フォームウィジェットについておさらいしましょう。

**不良**: スタイルの設定が難しく複雑なトリックが必要であり、時に CSS の高度な知識が必要である要素です。

* チェックボックスやラジオボタン
* `<input type="search">`

**劣悪**: 一部の要素は CSS でスタイル設定できません。含まれているのは以下のものです。

* ドロップダウンウィジェットを作成する要素、 `<select>`, `<option>`, `<optgroup>`, `<datalist>` を含む
* `<input type="color">`
* `<input type="datetime-local">`のような日付関連コントロール
* `<input type="range">`
* `<input type="file">`
* `<progress>` および `<meter>`

最初に `appearance` プロパティについて説明します。これは上記のすべてをよりスタイル付けできるようにするためにかなり有用なプロパティです。

見た目: OS レベルのスタイル制御
------------------

前の記事では歴史的に、ウェブフォームのスタイル設定は OS で行われており、それがこのコントロールの見た目のカスタマイズの問題の一部となっていました。

`appearance` プロパティは OS やシステムレベルでウェブフォームのスタイル設定を制御する方法として作成されました。最も有用な値は、おそらく唯一使用することになるであろう `none` です。これは適用したコントロールがシステムレベルのスタイルを使用することを可能な限り止め、 CSS を使用して自分でスタイルを構築できるようにします。

例えば、次のコントロールを見てみましょう。

```html
<form>
  <p>
    <label for="search">search: </label>
    <input id="search" name="search" type="search" />
  </p>
  <p>
    <label for="text">text: </label>
    <input id="text" name="text" type="text" />
  </p>
  <p>
    <label for="date">date: </label>
    <input id="date" name="date" type="datetime-local" />
  </p>
  <p>
    <label for="radio">radio: </label>
    <input id="radio" name="radio" type="radio" />
  </p>
  <p>
    <label for="checkbox">checkbox: </label>
    <input id="checkbox" name="checkbox" type="checkbox" />
  </p>
  <p><input type="submit" value="submit" /></p>
  <p><input type="button" value="button" /></p>
</form>
```

次の CSS を適用してシステムレベルのスタイル設定を削除します。

```css
input {
  appearance: none;
}
```

下記の例ではお使いのシステムでどのように見えるかを示します。既定では左で、上記の CSS が適用されると右になります（その他のシステムでテストしたい場合はここも探してください）。

たいていの場合、効果は枠線を除去し、 CSS でのスタイル設定を少し簡単にしますが、それは本質できありません。いくつかの場合 — 検索やラジオボタン/チェックボックスでは、もっと便利です。これを見ていきましょう。

### 検索ボックスを変更する

`<input type="search">` は基本的に単なるテキスト入力ですが、なぜ `appearance: none;` が便利なのでしょうか? 答えは Safari では、検索ボックスにスタイル設定の制限があるからです。例えば `height` や `font-size` を自在に調整できません。

これは、我々の友人である `appearance: none;` を使用して修正することができます。これは既定の外見を無効化するものです。

```css
input[type="search"] {
  appearance: none;
}
```

下記の例では、2 つのスタイル設定された検索ボックスが見えます。右のものは `appearance: none;` が適用され、左はそうでありません。macOS の Safari で見ると左のものは正しいサイズでないように見えます。

興味深いことに、検索フィールドで border/background をセットしてもこの問題を解決できます。下記のスタイル設定された検索ボックスは `appearance: none;` が適用されていませんが、前の例と同じ Safari の問題に悩まされていません。

**メモ:** 検索フィールドでは、Edge と Chrome で入力がフォーカスされないときに "x" の削除アイコンが消えるが、Safari では残ることに気づくこともあるでしょう。CSS で消すには、`input[type="search"]::-webkit-search-cancel-button { display: none; }`を使用できますが、フォーカス時のアイコンも取り除き、見た目が元に戻らないようです。

### チェックボックスとラジオボタン

チェックボックスやラジオボタンのスタイル設定は、初期設定のままでは厄介です。チェックボックスやラジオボタンのサイズは初期設定のままでは変更できないようになっていますし、変更しようとするとブラウザーの反応もとても異なります。

例えば、シンプルなテストケースを考えてみます。

```html
<label
 ><span><input type="checkbox" name="q5" value="true" /></span> True</label
>
<label
 ><span><input type="checkbox" name="q5" value="false" /></span> False</label
>
```

```css
span {
  display: inline-block;
  background: red;
}

input[type="checkbox"] {
  width: 100px;
  height: 100px;
}
```

ブラウザーによってチェックボックスとスパンの扱いは異なっており多くは劣悪なものです。

| ブラウザー | 描画結果 |
| --- | --- |
| Firefox 71 (macOS) |  |
| Firefox 57 (Windows 10) |  |
| Chrome 77 (macOS), Safari 13, Opera |  |
| Chrome 63 (Windows 10) |  |
| Internet Explorer 11 (Windows 10) |  |
| Edge 16 (Windows 10) |  |

#### ラジオボタン/チェックボックスで appearance: none を使う

これまで見てきたように、チェックボックスやラジオボタンの既定の見た目を `appearance``:none;` で削除できます。この HTML の例を見てみましょう。

```html
<form>
  <fieldset>
    <legend>Fruit preferences</legend>

    <p>
      <label>
        <input type="checkbox" name="fruit" value="cherry" />
        I like cherry
      </label>
    </p>
    <p>
      <label>
        <input type="checkbox" name="fruit" value="banana" disabled />
        I can't like banana
      </label>
    </p>
    <p>
      <label>
        <input type="checkbox" name="fruit" value="strawberry" />
        I like strawberry
      </label>
    </p>
  </fieldset>
</form>
```

さて、これらを独自のチェックボックスデザインでスタイル設定しましょう。元のチェックボックスのスタイルを解除することから始めましょう。

```css
input[type="checkbox"] {
  appearance: none;
}
```

`:checked` と `:disabled` 擬似クラスを使用して、状態の変化に合わせてカスタムチェックボックスの外観を変更します。

```css
input[type="checkbox"] {
  position: relative;
  width: 1em;
  height: 1em;
  border: 1px solid gray;
  /\* Adjusts the position of the checkboxes on the text baseline \*/
  vertical-align: -2px;
  /\* Set here so that Windows' High-Contrast Mode can override \*/
  color: green;
}

input[type="checkbox"]::before {
  content: "✔";
  position: absolute;
  font-size: 1.2em;
  right: -1px;
  top: -0.3em;
  visibility: hidden;
}

input[type="checkbox"]:checked::before {
  /\* Use `visibility` instead of `display` to avoid recalculating layout \*/
  visibility: visible;
}

input[type="checkbox"]:disabled {
  border-color: black;
  background: #ddd;
  color: gray;
}
```

こうした擬似クラスなどは、次の記事で見つけられますが、上記は次のことをしています。

* `:checked` — チェックボックス (やラジオボタン) がチェックされた状態にあります — ユーザーがクリック/有効化しています。
* `:disabled` — チェックボックス (やラジオボタン) が無効な状態にあります — 操作することができますせん.

実際の結果が表示されます。

また、より多くのアイデアを提供するために、他の例もいくつか作成しています。

* Styled radio buttons: カスタムラジオボタンスタイル設定。
* Toggle switch example: トグルスイッチのようなチェックボックス。

`appearance` に対応していないブラウザーで、これらのチェックボックスを表示できます。カスタムデザインは失われますが、チェックボックスのままに見えて使用できます。

**メモ:** Internet Explorer はどのバージョンでも `appearance` に対応していませんが、`input[type=checkbox]::-ms-check` にて IE のみチェックボックスをターゲットにできます。この手法は、`-ms-check` という名前にもかかわらず、ラジオボタンでも機能します。

「劣悪」要素に何ができるか
-------------

今度は「劣悪」コントロールに注目しましょう。これは完全にスタイル設定するのが本当に難しいものです。簡単にいうと、これはドロップダウンボックス、 `color` や `datetime-local` のような複合コントロール型、 `<progress>` や `<meter>` のようなコントロール志向のフィードバックです。

問題は、要素はブラウザー同士でいろいろな既定の見た目があって、それにスタイル設定できても、内部のいくつかはスタイル設定できないことです。

ルック＆フィールの違いを受け入れる覚悟があれば、サイズ変更を一貫したものにするためのシンプルなスタイル設定や、 background-color のような単一スタイル設定、システムレベルのスタイル設定を除去できる appearance の使用などで逃げることもできます。

例を見てみましょう。たくさんの「劣悪」なフォーム機能をつぎつぎに表示しています。

この例では下記の CSS を適用しています。

```css
body {
  font-family: "Josefin Sans", sans-serif;
  margin: 20px auto;
  max-width: 400px;
}

form > div {
  margin-bottom: 20px;
}

select {
  appearance: none;
}

.select-wrapper {
  position: relative;
}

.select-wrapper::after {
  content: "▼";
  font-size: 1rem;
  top: 6px;
  right: 10px;
  position: absolute;
}

button,
label,
input,
select,
progress,
meter {
  display: block;
  font-family: inherit;
  font-size: 100%;
  margin: 0;
  box-sizing: border-box;
  width: 100%;
  padding: 5px;
  height: 30px;
}

input[type="text"],
input[type="datetime-local"],
input[type="color"],
select {
  box-shadow: inset 1px 1px 3px #ccc;
  border-radius: 5px;
}

label {
  margin-bottom: 5px;
}

button {
  width: 60%;
  margin: 0 auto;
}
```

**メモ:** 多数のブラウザーで同時にこの例をテストしたい場合、ライブ版をここで見つけてください (ソースコードも見てください)。

また JavaScript をページに追加してコントロール自身の下にあるファイルピッカー自身で選択されたファイルを一覧しているのを心に留めておいてください。これは `<input type="file">` リファレンスページの例を簡単にしたバージョンです。

見ての通り、最近のブラウザーでは統一された外見を確保することができました。

前の記事で述べたように、すべてのコントロールとそのラベルにグローバルな正規化 CSS を適用して、同じサイズになるようにし、親フォントを採用するなどの工夫をしています。

```css
button,
label,
input,
select,
progress,
meter {
  display: block;
  font-family: inherit;
  font-size: 100%;
  margin: 0;
  box-sizing: border-box;
  width: 100%;
  padding: 5px;
  height: 30px;
}
```

コントロールに統一した影と角丸も与えて、意味のあるようにします。

```css
input[type="text"],
input[type="datetime-local"],
input[type="color"],
select {
  box-shadow: inset 1px 1px 3px #ccc;
  border-radius: 5px;
}
```

範囲や、プログレスバーや、メーターはコントロールエリアの周りに美しくないボックスができるだけなので、意味はありません。

これらのコントロールタイプそれぞれの仕様と、ハイライトの難しさをこれからお話ししましょう。

### select とデータリスト

現代のブラウザーでは、select とデータリストは一般的に、既定のものからルック＆フィールを大きく変えたくないようにスタイル設定する場合は、悪くないものです。

これまで、ボックスの基本的な見た目をかなり均一で一貫性のあるものにしてきました。とにかくデータリストコントロールは `<input type="text">` なので、問題にならないことがわかっています。

2 つのものが多少問題をはらんでいます。まず最初に、 select がドロップダウンであることを示す "矢印" アイコンは、ブラウザーによって異なります。また select ボックスのサイズを増やしたり、変更したりすると、醜くなりがちです。これを修正するため、例では最初に旧友の `appearance: none` を使ってアイコンを除去しています。

```css
select {
  appearance: none;
}
```

次に生成されたコンテンツを使って独自のアイコンを作成します。コントロールの周りに特別なラッパーを置きました。それは`::before`/`::after` が `<select>` 要素では動作しないためです（これは生成されたコンテンツが要素がフォーマットするボックスに対し相対的に配置されますが、フォーム入力は置換された要素 — 表示がブラウザーによって生成されて順番に配置されるもの — として動作するので、1 つもないためです）。

```html
<label for="select">Select a fruit</label>
<div class="select-wrapper">
  <select id="select" name="select">
    <option>Banana</option>
    <option>Cherry</option>
    <option>Lemon</option>
  </select>
</div>
```

次に生成されたコンテンツを使って小さな下向き矢印を作り、正しい場所に配置します。

```css
.select-wrapper {
  position: relative;
}

.select-wrapper::after {
  content: "▼";
  font-size: 1rem;
  top: 6px;
  right: 10px;
  position: absolute;
}
```

2 つ目の、もう少し大きな問題は、 `<select>` ボックスをクリックして開いたときに現れる、選択肢の入ったボックスを操作することができないことです。選択肢は親に設定されたフォントを引き継がないことに気がつくでしょう。また、余白の設定や色なども一貫して設定することができません。例えば、 Firefox では `color` と `background-color` が `<option>` 要素に適用できますが、 Chrome ではそうなりません。どちらも余白（例えば `padding`）を適用できません。同じことはデータリスト用に出てくる自動補完リストにも当てはまります。

本当に選択肢をスタイル設定する必要がある場合、カスタムコントロールを生成するライブラリーを使用するか、独自のカスタムコントロールを作成するかのどちらかが必要で、あるいは `multiple` 属性を使う select の場合、これはページ上に出てくるすべての選択肢を作成し、この特殊な問題を避けることができます。

```html
<label for="select">Select fruits</label>
<select id="select" name="select" multiple>
  …
</select>
```

もちろんこれでも進めているデザインには合わない可能性もありますが、注目に値します。

### 日付入力型

日付/時間の入力型 (`datetime-local`, `time`, `week`, `month`) にはすべて同じ重大な関連した問題があります。実際のボックスは、テキスト入力と同様に簡単にスタイルを設定することができ、このデモではうまく表示されています。

しかし、コントロールの内部部品（日付をピックアップするのに使うポップアップカレンダー、値を増減するスピナーなど）はまったくスタイル設定できず、 `appearance: none;` を使ってもスタイルを除去できません。スタイル設定を完全に制御する必要がある場合は、カスタムコントロールを生成するライブラリーを使うか、自分で作らなければなりません。

**メモ:** ここでも`<input type="number">` は触れる価値があります、これもまた、値を増加/減少させるために使用することができるスピナーがあるので、同じ問題に悩まされる可能性があります。しかし、 `number` 型の場合、収集するデータはより単純で、代わりに `tel` 入力型を使用するのも簡単です。これは `text` のような外観ですが、タッチキーボードを搭載した機器ではテンキーを表示することができます。

### Range 入力型

`<input type="range">` はスタイル設定が困難です。以下のように使用することで、既定値のスライダートラックを完全に削除し、カスタムスタイル（この例では、細い赤のトラック）に置き換えることができます。

```css
input[type="range"] {
  appearance: none;
  background: red;
  height: 2px;
  padding: 0;
  outline: 1px solid transparent;
}
```

しかし、 range コントロールのドラッグハンドルのスタイルをカスタマイズすることはとても困難です。 range のスタイルを完全に操作するためには、複数の非標準的でブラウザー特有の擬似要素を含む、複雑な CSS コードを使用する必要があります。 Styling Cross-Browser Compatible Range Inputs with CSS で必要なものを細かく書くための CSS トリックを確認します。

### color 入力型

color 型の入力コントロールは悪いものではありません。対応しているブラウザーでは、小さな境界線付きの無地のブロックが表示されるだけです。

境界線を削除して、色のブロックだけにするには、次のようにします。

```css
input[type="color"] {
  border: 0;
  padding: 0;
}
```

しかし、大きく変わったものを得るには、カスタムソリューションが唯一の方法です。

### ファイル入力型

ファイル入力型は通常は OK です。例で見てきたように、ページの残りの部分に問題なくフィットする何かを作るのはとても簡単です。コントロールの一部分でもある出力行は、入力にそう指示している場合は親のフォントを継承して、カスタムリストに名前やサイズをお好みでスタイル設定できます。結局は作ってみました。

ファイルピッカーの唯一の問題は、ファイルピッカーを開くために押すボタンが、サイズや色を変更できず、異なるフォントも受け入れられず、完全にスタイル設定が不可能であることです。

これを回避する一つの方法は、フォームコントロールに関連付けられたラベルがある場合、そのラベルをクリックするとコントロールが有効になることを利用することです。そこで、次のような方法で実際のフォーム入力を非表示にすることができます。

```css
input[type="file"] {
  height: 0;
  padding: 0;
  opacity: 0;
}
```

次にボタンのように動作するラベルをスタイル設定し、そのラベルが押された時にファイルピッカーが期待通り開くようにします。

```css
label[for="file"] {
  box-shadow: 1px 1px 3px #ccc;
  background: linear-gradient(to bottom, #eee, #ccc);
  border: 1px solid rgb(169, 169, 169);
  border-radius: 5px;
  text-align: center;
  line-height: 1.5;
}

label[for="file"]:hover {
  background: linear-gradient(to bottom, #fff, #ddd);
}

label[for="file"]:active {
  box-shadow: inset 1px 1px 3px #ccc;
}
```

上記の CSS スタイル設定の結果は、下記のライブ実行の例で見ることができます（styled-file-picker.html のライブと、ソースコードも見てください）。

### meter とプログレスバー

`<meter>` と `<progress>` は多くの中で最悪かもしれません。先ほどの例で見たように、幅は比較的希望通りに設定することができます。しかし、それ以上に、どのような方法でもスタイルを設定することは本当に困難です。また、背景には色をつけることができますが、前面のバーには色をつけることができませんし、 `appearance: none` を設定すると、良くなるどころか悪化してしまいます。

スタイル設定を制御したい場合は、この機能のカスタムソリューションを作ったり、progressbar.js のようなサードパーティのソリューションを使ったりした方が簡単です。

スキルテスト
------

この記事の最後に達しましたが、最も大切な情報を覚えていますか？次に進む前に、この情報が身に付いたかどうかを確認するテストがあります。Test your skills: Advanced styling (en-US) を見てください。心に留めておくこととして、この評価シリーズでの質問は、次の記事の知識も前提していてるので、試す前にその記事に取り組むとよいかもしれません。

まとめ
---

HTML フォームで CSS を使用するのはまだ困難ですが、しばしばそれらを回避する方法があります。クリーンでユニバーサルな解決方法はありませんが、最新のブラウザーでは新しい可能性があります。今のところ、最良の解決策は、HTML フォームウィジェットに適用されたときに異なるブラウザーが CSS をサポートする方法の詳細を学ぶことです。

このガイドの次の記事では、現代のブラウザーでさまざまな状態のフォームをスタイル設定できるさまざまな UI 擬似クラスを見ていきます。

* 前のページ
* Overview: Forms
* 次のページ


基本的なネイティブフォームコントロール - ウェブ開発を学ぶ

基本的なネイティブフォームコントロール
===================

* 前のページ
* Overview: Forms
* 次のページ

一つ前の記事では、機能的なウェブフォームの例をマークアップし、いくつかのフォームコントロールとよくある構造要素を導入し、アクセシビリティのベストプラクティスを見てきました。次にさまざまなフォームコントロールやウィジェットの機能を詳しく見ていきます。 — 色々な種類のデータを集めるのにどんなオプションが使えるのかを見ていきます。とりわけこの記事では、ウェブの初期からありすべてのブラウザーで利用できる、元からあるフォームコントロールを見ていきます。

|  |  |
| --- | --- |
| 前提条件: |
 基本的なコンピューターリテラシーと、基本的な
 HTML の理解。
  |
| 目的: | データを収集するためにブラウザーで使用できる基本的なネイティブフォームコントロールの種類と、それらを HTML を使用して実装する方法を理解する。 |

既にいくつかのフォーム要素を見てきました。 `<form>`, `<fieldset>`, `<legend>`, `<textarea>`, `<label>`, `<button>`, `<input>` などです。この記事では、以下の要素を扱います。

* よく使われる入力型である button, checkbox, file, hidden, image, password, radio, reset, submit, text
* すべてのフォームコントロールに共通する属性のいくつか

**メモ:** 次の 2 回分の記事で、 HTML5 で追加された、もっと強力なフォームコントロールを取り上げます。より高度なリファレンスを読みたい方は、 HTML フォーム要素のリファレンス、全般的には `<input>` 型 のリファレンスを参照してください。

テキスト入力フィールド
-----------

テキスト入力 (`<input>`) フィールドは、最も基本的なフォームウィジェットです。これらはユーザーがあらゆる種類のデータを入力できるとても便利な方法です。

**メモ:** HTML フォームのテキストフィールドは単純なプレーンテキストの入力コントロールです。つまり、これらを使ってリッチテキストの編集（太字、斜体など）を実現することはできません。見かけるリッチテキストエディターは、すべて HTML、CSS、JavaScript で作成されたカスタムウィジェットです。

すべてのテキストフィールドに共通する動作があります。

* `readonly` （ユーザーは入力値が変更できないが、他のフォームデータとともに送信される）あるいは `disabled` （入力値が変更できず、他のフォームデータとともに送られない）とすることができます。
* `placeholder` を設定することができます。これは、ボックスの目的を簡単に説明する、ボックス内に表示されるテキストです。
* `size` （ボックスの物理的な大きさ）や `maxlength` （ボックスに入力できる最大文字数）による制限が可能です。
* ブラウザーが対応していれば、スペルチェックの便宜を図ることができます (`spellcheck`属性を用いて)。

**メモ:** `<input>` 要素は `type` 属性によってさまざまな形になるため、 HTML 要素の中でも独特です。単一行のテキストフィールド、時間と日付のコントロール、チェックボックス、ラジオボタン、カラーピッカー、ボタンのようなテキスト入力のないコントロールなど、ほとんどの種類のフォームウィジェットの作成に使用されます。

### 単一行のテキストフィールド

単一行のテキストフィールドを生成するには、 `<input>` 要素で `type` 属性値を `text` に設定するか、 `type` 属性を省略するかします (`text` が既定値です)。この属性の `text` の値は、 `type` 属性に指定した値をブラウザーに認識できない場合 (たとえば `type="color"` を指定した場合で、ブラウザーがネイティブの色ピッカーに対応していない場合) の代替値になります。

**メモ:** GitHub の single-line-text-fields.html に、すべての単一行テキストフィールド型の例があります (ライブで確認できます)。

基本的な単一行のテキストフィールドの例を示します。

```html
<input type="text" id="comment" name="comment" value="I'm a text field" />
```

単一行のテキストフィールドは、ひとつだけ厳密な制約があります。改行を含むテキストを入力した場合、ブラウザーはデータを送信する前に改行を取り除きます。

*下記のスクリーンショットは macOS での Firefox 71 と Safari、および Windows 10 の Chrome 79 と Edge 18 において、テキストフィールドが既定の場合、フォーカスされた場合、無効にされた場合を示しています。*

![Firefox、Safari、Chrome、Edge における、テキスト入力の disabled 属性と既定の :focus スタイルを表示したスクリーンショットです。](/ja/docs/Learn/Forms/Basic_native_form_controls/disabled.png)

**メモ:** 特定の検証制約を強制する `type` 属性の値、例えば color、email、url 入力型については、次の記事の HTML5 の入力型で説明します。

#### パスワードフィールド

元からあった入力型の一つが、 `password` テキストフィールド型でした。

```html
<input type="password" id="pwd" name="pwd" />
```

`password` の値は、入力されるテキストに特別な制約を加えるものではありませんが、フィールドに入力された値を (ドットやアスタリスクなどで) 不明瞭にして、他の人が簡単に読めないようにします。

これはユーザーインターフェイスの機能でしかないことに注意してください。テキストは JavaScript を使用してあなた自身でエンコードしなければ、平文で送信されてしまい、セキュリティ上で好ましくありません。 — 悪意のある第三者がデータを傍受し、パスワードやクレジットカード情報などを盗む可能性があります。このようなことからユーザーを保護する最善の方法は、フォームを含むページを安全な接続（すなわち、 `https://` ... を指すアドレス）でホストし、データを送信する前に暗号化することです。

ブラウザーは、安全でない接続でフォームデータを送信することのセキュリティ上の影響を認識しており、ユーザーが安全でないフォームを使用することを抑止するために警告を表示します。 Firefox が実装している機能の詳細については、安全でないパスワードを参照してください。

### hidden コンテンツ

もう一つの元からあるテキストコントロールは `hidden` 入力型です。これは、ユーザーには見えないが、送信されると他のフォームデータと一緒にサーバーに送信されるフォームコントロールを作成するために使用されます。 — 例えば、注文が行われた時のタイムスタンプをサーバーに送信したい場合などです。表示されないので、ユーザーは値を見ることも、意図的に編集することもできず、フォーカスを受けることもなく、スクリーンリーダーも知らせることはありません。

```html
<input type="hidden" id="timestamp" name="timestamp" value="1286705410" />
```

このような要素を作成する場合は、 `name` 属性と `value` 属性の設定が必要です。この値は JavaScript にて動的にセットできます。`hidden` 入力型には関連したラベルはありません。

その他のテキスト型、search, url, tel, は次のチュートリアルの HTML5 の入力型にて扱います。

チェック可能項目: チェックボックスとラジオボタン
-------------------------

チェック可能項目は、そのものや、関連したラベルをクリックすることで状態を変更できるコントロールです。チェック可能項目は 2 種類あります。チェックボックスとラジオボタンです。どちらもそのウィジェットが既定でチェック状態にするかどうかを示すために、 `checked` 属性を使用します。

これらのウィジェットは、他のフォームウィジェットと同じようには動作しない点が特徴です。ほとんどのフォームウィジェットでは、フォームを送信すると `name` 属性を持つすべてのウィジェットが、値が入力されていなくても送信されます。チェック可能項目では、チェックされている場合にのみ値が送信されます。チェックされていない場合は、 name も含めて何も送信されません。チェックされているが値がない場合、 name が *on* という値で送信されます。

**メモ:** この節の例は、checkable-items.html として GitHub にあります（ライブで確認できます）。

最大限のユーザビリティ/アクセシビリティを実現するために、関連項目の各リストを `<fieldset>` で囲み、リストの全体的な説明を示す `<legend>` で囲むことをお勧めします。 `<label>`/`<input>` 要素の個々のペアは、それぞれ独自のリスト項目（または同様のもの）に含める必要があります。関連した `<label>` はラジオボタンやチェックボックスの直後に、 `<legend>` の中身にラジオボタンやチェックボックスのグループの説明が置かれます。これは上の例に示されています。

### チェックボックス

チェックボックスは、 `<input>` 要素で `type` 属性を checkbox に設定して作成します。

```html
<input type="checkbox" id="questionOne" name="subscribe" value="yes" checked />
```

関連するチェックボックス項目には、同じ `name` 属性を使用してください。 `checked` 属性を含めると、ページが読み込まれたときにチェックボックスが自動的にチェックされます。チェックボックス自体または関連づけられたラベルをクリックすると、チェックボックスのオンとオフが切り替わります。

```html
<fieldset>
  <legend>Choose all the vegetables you like to eat</legend>
  <ul>
    <li>
      <label for="carrots">Carrots</label>
      <input
 type="checkbox"
 id="carrots"
 name="vegetable"
 value="carrots"
 checked />
    </li>
    <li>
      <label for="peas">Peas</label>
      <input type="checkbox" id="peas" name="vegetable" value="peas" />
    </li>
    <li>
      <label for="cabbage">Cabbage</label>
      <input type="checkbox" id="cabbage" name="vegetable" value="cabbage" />
    </li>
  </ul>
</fieldset>
```

下記のスクリーンショットは macOS での Firefox 71 と Safari、および Windows 10 の Chrome 79 と Edge 18 において、チェックボックスが既定の場合、フォーカスされた場合、無効にされた場合を示しています。

![Mac での Firefox 71 および Safari 13 と、 Windows 10 での Chrome 79 および Edge 18 の既定、フォーカス、無効状態のチェックボックス](/ja/docs/Learn/Forms/Basic_native_form_controls/checkboxes.png)

**メモ:** チェックボックスやラジオボタンで読み込み時に `checked` 属性が付いていれば、チェック状態が解除されても `:default` 擬似クラスに一致します。現在チェックされているものは ``:checked`` 擬似クラスに一致します。

チェックボックスにはオンとオフになるという性質があるため、チェックボックスはトグルボタンと考えられており、多くの開発者やデザイナーが既定のチェックボックスのスタイルを拡張して、トグルスイッチのように見えるボタンを作成しています。ここで動作する例を見ることができます（ソースコードも見られます）。

### ラジオボタン

ラジオボタンは、 `<input>` 要素の `type` 属性を `radio` に設定して生成します。

```html
<input type="radio" id="soup" name="meal" checked />
```

複数のラジオボタンを結びつけることができます。 `name` 属性の値が同じであれば、同じグループのボタンであるとみなされます。グループ内のボタンは同時に一つしかチェックできません。つまり、あるボタンがチェックされると、他のボタンは自動的にチェックが外されます。フォームが送信される際には、チェックされたラジオボタンの値のみが送信されます。一つもチェックされていない場合、ラジオボタンのグループ全体が未知の状態であるとみなされ、値はフォームと共に送信されません。同じ名前のグループのラジオボタンの一つがチェックされると、ユーザーはフォームをリセットせずに、すべてのボタンのチェックを外すことはできません。

```html
<fieldset>
  <legend>What is your favorite meal?</legend>
  <ul>
    <li>
      <label for="soup">Soup</label>
      <input type="radio" id="soup" name="meal" value="soup" checked />
    </li>
    <li>
      <label for="curry">Curry</label>
      <input type="radio" id="curry" name="meal" value="curry" />
    </li>
    <li>
      <label for="pizza">Pizza</label>
      <input type="radio" id="pizza" name="meal" value="pizza" />
    </li>
  </ul>
</fieldset>
```

下記のスクリーンショットは macOS での Firefox 71 と Safari、および Windows 10 の Chrome 79 と Edge 18 において、ラジオボタンがチェックされていない場合といる場合、フォーカスがある場合、無効にされていてチェックされていない場合といる場合を示しています。

![Mac の Firefox 71 と Safari 13 および Windows 10 の Chrome 79 と Edge 18 のラジオボタン](/ja/docs/Learn/Forms/Basic_native_form_controls/radios.png)

実際のボタン
------

ラジオボタンはその名に反して、実際のボタンではありません。実際のボタンを見てみましょう。ボタンを生成するための入力型は 3 種類あります。

`submit`

フォームデータをサーバーに送信します。 `<button>` 要素の場合、`type` 属性を省略した場合（または `type` の値が無効であった場合）、送信ボタンが表示されます。

`reset`

すべてのフォームウィジェットを既定値にリセットします。

`button`

自動的な効果のないボタンで、 JavaScript コードを用いてカスタマイズできるものです。

また、ボタンそのものを示す `<button>` 要素もあります。これは `type` 属性に `submit`, `reset`, `button` の値を取り、上記の 3 つの `<input>` 型を模倣できます。この 2 つの主な違いは、実際の `<button>` 要素の方がはるかにスタイル付けしやすいことです。

**メモ:** `image` 入力型もボタンとしてレンダリングされます。それについては後で触れます。

**メモ:** この節の例は button-examples.html として GitHub にあります（ライブで確認できます）。

以下に、それぞれのボタンの `<input>` 型と、同等の `<button>` 型の例を示します。

### submit

```html
<button type="submit">これは<strong>送信ボタン</strong>です</button>

<input type="submit" value="これは送信ボタンです" />
```

### reset

```html
<button type="reset">これは<strong>リセットボタン</strong>です</button>

<input type="reset" value="これはリセットボタンです" />
```

### ただのボタン

```html
<button type="button">これは<strong>ただのボタン</strong>です</button>

<input type="button" value="これはただのボタンです" />
```

ボタンは `<button>` 要素と `<input>` 要素のどちらを使用しても常に同じ動作になります。しかし、上記の例で分かるように、 `<button>` 要素は中身として HTML を使用することができ、これが `<button>` の開始・終了タグの間に挿入されます。一方で`<input>` 要素は空要素です。つまり `value` 属性に中身が挿入され、したがってプレーンテキストのコンテンツのみ使用できます。

下記の例は macOS での Firefox 71 と Safari 13、および Windows 10 の Chrome 79 と Edge 18 にて、ボタンの既定、フォーカス、無効状態を示しています。

![Mac 版の Firefox 71 と Safari 13、 Windows 版の Chrome 79 と Edge 18 の既定、フォーカス、無効状態の button 入力型](/ja/docs/Learn/Forms/Basic_native_form_controls/buttons.png)

### 画像ボタン

**画像ボタン**コントロールは `<img>` 要素とまったく同じように表示されますが、ユーザーがクリックすると送信ボタン（前述）のように動作します。

画像ボタンは、 `<input>` 要素の`type` 属性を `image` に設定することで作成します。この要素は `<img>` 要素とまったく同じ属性に対応しており、さらに他のフォームボタンが対応している属性にもすべて対応しています。

```html
<input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />
```

画像ボタンをフォームの送信に使用する場合、このウィジェットは自身の値を送信しませんが、代わりに画像上でクリックした位置の X 座標と Y 座標を送信します (座標は画像に対して相対的、つまり画像の左上隅が座標 (0, 0) になります)。座標は 2 つのキーと値の組として送信されます。

* X 値のキーは `name` 属性の値の後ろに文字列 "*.x*" をつけたもの、
* Y 値のキーは `name` 属性の値の後ろに文字列 "*.y*" をつけたものです。

サンプルをご覧ください。フォームの画像上の座標 (123, 456) でクリックすると、 `get` メソッド経由で送信されて、以下のような値の追加された URL が送信されます。
```

http://foo.com?pos.x=123&pos.y=456
```

これは「ホットマップ」を作成するためにとても便利な手段です。これらの値がどのように送信あるいは取得されるかについては、フォームデータの送信の記事で詳しく説明します。

ファイルピッカー
--------

初期の HTML にあった `<input>` 型がもう一つあります。ファイル入力型です。フォームで、ファイルをサーバーに送信することができます (この具体的な操作については、フォームデータの送信の記事でも詳しく触れます)。ファイルピッカーウィジェットで、ユーザーは送信するファイルを 1 つ以上選択することができます。

ファイルピッカーウィジェットを作成するには、 `<input>` 要素の `type` 属性を `file` に設定します。 `accept` 属性を使用して、受け入れるファイルの種類を制限することができます。加えて、ユーザーが複数のファイルを選択できるようにしたい場合は、 `multiple` 属性を付加します。

#### 例

以下の例では、画像ファイルを要求するファイルピッカーを作成しています。ユーザーは複数のファイルを指定できます。

```html
<input type="file" name="file" id="file" accept="image/\*" multiple />
```

いくつかのモバイル端末では、ファイルピッカーは、次のようにキャプチャー情報を `accept` 属性に追加することで、端末のカメラやマイクでキャプチャーされた写真、動画、音声にアクセスすることができます。

```html
<input type="file" accept="image/\*;capture=camera" />
<input type="file" accept="video/\*;capture=camcorder" />
<input type="file" accept="audio/\*;capture=microphone" />
```

共通の属性
-----

フォームコントロールの定義に使われる要素の多くは、それぞれ固有の属性を持っています。しかし、すべてのフォーム要素に共通する属性があります。これらの属性のいくつかはすでに見たことがあると思いますが、参考までに共通の属性を以下に列挙します。

| 属性名 | 既定値 | 説明 |
| --- | --- | --- |
| `autofocus` | false | この論理属性を使用すると、ページ読み込み時に自動的に要素に入力フォーカスを設定するように指定できます。この属性を指定できるのは、文書内の 1 つのフォーム関連要素だけです。 |
| `disabled` | false | この論理属性は、ユーザーが要素と対話できないことを示します。この属性が指定されていない場合、要素はそれを含む要素（例えば `<fieldset>`）からその設定を継承します。 `disabled` 属性が設定されている包含要素がない場合は、その要素が有効になります。 |
| `form` |  | ウィジェットが関連付けられている `<form>` 要素で、そのフォーム内に含まれていない場合に使用されます。属性の値は、同じ文書内の `<form>` 要素の `id` 属性でなければなりません。これにより、フォームコントロールをフォームに外側から、他のフォーム要素の中にあったとしても、関連付けることができます。 |
| `name` |  | 要素の名前。これはフォームデータとともに送信されます。 |
| `value` |  | 要素の初期値です。 |

スキルテスト
------

この記事の最後に到着しましたが、もっとも大事な情報を覚えていますか？ 次に進む前に、この情報を保持しているか検証するテストがあります — Test your skills: Basic controls (en-US) を見てください。

まとめ
---

この記事では古い入力型を扱ってきました。 — これは HTML の初期の頃に導入された元からのもので、すべてのブラウザーがよく対応しています。次の節では、もっと新しい `type` 属性の値を見ていきます。

* 前のページ
* Overview: Forms
* 次のページ


初めてのフォーム - ウェブ開発を学ぶ

初めてのフォーム
========

* Overview: Forms
* 次のページ

 このシリーズの最初の記事では、簡単なフォームの設計、HTML フォームコントロールとその他の HTML 要素を使用した正しい実装、 CSS によるとても簡単なスタイル付け、データをサーバーに送る方法を含めた、ウェブフォームを作成する本当に初歩的な経験をします。
 サブトピックは、モジュールの後で詳しく展開していきます。

|  |  |
| --- | --- |
| 前提条件: | 基本的なコンピューターリテラシーと、HTML を理解するを理解していること。 |
| 目的: | ウェブフォームとは何か、何に使うのか、どうデザインするのか、サンプル事例に必要な基本の HTML 要素について熟知する。 |

ウェブフォームとは何か?
------------

**ウェブフォーム**とは、ユーザーと ウェブサイトやアプリケーションとの対話の要となるもののひとつです。ユーザーはフォームによって、ウェブサイトへデータを送ることができます。それらのデータはたいてい ウェブサーバーに送られて処理、保存されたり（このモジュール後半のサーバーにデータを送るを見てください）、クライアント側ですぐにインターフェイスを更新する（例えば、リストに他の項目を追加したり、UI の機能を表示/非表示にしたりする）こともあります。

ウェブフォームは 1 つ以上の**フォームコントロール**（**ウィジェット**ともいいます）と、フォーム全体を構成するのに役立つ追加要素 — よく **HTML フォーム**と呼ばれます — とで作られます。それらのコントロールは単一行または複数行のテキストフィールド、ドロップダウンボックス、ボタン、チェックボックス、ラジオボタンがあります。たいていは `<input>` 要素を使って作成されますが、その他の要素もあります。

フォームコントロールは、特定フォームの値が入力されるのを強制するためにもプログラミングされ（**フォーム検証**）、目の見えるユーザーと目の不自由なユーザーの両方に対して用途を説明するテキストのラベルと対になります。

フォームを設計する
---------

コードを書き始める前に、そこから離れてフォームについて考える時間をとるとよいでしょう。簡単なモデルを作ると、ユーザーに入力を依頼したいデータの適切なセットを定義することの助けになります。ユーザー体験 (UX) の観点では、フォームが大規模になるとユーザーが不満を持って離れるリスクが高まると覚えておくことが重要です。簡単に、かつ集中するようにしてください。本当に必要なことだけを尋ねてください。

フォームの設計は、サイトやアプリケーションを構築する際の大切なステップです。フォームのユーザー体験まで扱うと本記事の対象を超えてしまいますが、そこまで踏み込みたい場合は以下の記事をご覧ください。

* Smashing Magazine にフォームの UX に関するよい記事がありますが、もっとも重要な記事は Extensive Guide To Web Form Usability でしょう。
* UXMatters もまた、基本的なベストプラクティスから複数ページのフォームといった複雑なことに至るまで、良いアドバイスを得られる、思慮深いリソースです。

本記事では、シンプルな問い合わせフォームを作成します。簡単に図を描いてみましょう。

![The form to build, roughly sketch](/ja/docs/Learn/Forms/Your_first_form/form-sketch-low.jpg)

このフォームには、3 つのテキストフィールドと 1 つのボタンがあります。要するに、ユーザーへ名前 (Name)、メールアドレス (E-mail)、送信したいメッセージ (Message) を尋ねます。ボタンを押すと、データをウェブサーバーへ送信します。

アクティブラーニング: フォームの HTML の実装
--------------------------

これで、HTML に移ってフォームのコードを書く準備ができました。問い合わせフォームを作るために、以下の HTML 要素、 `<form>`、`<label>`、`<input>`、`<textarea>`、`<button>` を使用します。

前に進む前に、簡単な HTML テンプレートをローカルにコピーします。 — ここにフォームの HTML を入力します。

### `<form>` 要素

すべてのフォームは、以下のように `<form>` 要素から始まります。

```html
<form action="/my-handling-form-page" method="post"></form>
```

これは、フォームを正式に定義します。これは `<section>` や `<footer>` 要素と同様にコンテナー要素ですが、フォームを含めるのに特化しています。フォームの動作方法を設定するための特有の属性にも対応しています。すべての属性は省略可能ですが、少なくとも `action` 属性と `method` 属性は常に設定するのがふつうです。

* `action` 属性は、フォームで収集したデータを送信すべき場所 (URL) を定義します。
* `method` 属性は、データを送信するために使用する HTTP メソッド（`get` または `post`）を定義します。

**メモ:** これらの属性がどのように働くかについて、詳しくはフォームデータの送信で説明しています。

今のところは、上の `<form>` 要素を HTML の `<body>` に追加します。

### `<label>`、`<input>`、`<textarea>` 要素

問い合わせフォームはとてもシンプルで、 3 つのテキストフィールドがあり、それぞれに対応する `<label>` がついています。

* 名前の入力フィールドは、基本的な単一行のテキストフィールドです。
* メールアドレスの入力フィールドは、email 型の入力フィールドです。メールアドレスだけを受け付ける単一行のテキストフィールドです。
* メッセージの入力フィールドは `<textarea>` です。複数行のテキストフィールドです。

これらのフォームウィジェットを実装するためには、 HTML コードとしては、以下のようなものが必要です。

```html
<form action="/my-handling-form-page" method="post">
  <ul>
    <li>
      <label for="name">Name:</label>
      <input type="text" id="name" name="user\_name" />
    </li>
    <li>
      <label for="mail">E-mail:</label>
      <input type="email" id="mail" name="user\_email" />
    </li>
    <li>
      <label for="msg">Message:</label>
      <textarea id="msg" name="user\_message"></textarea>
    </li>
  </ul>
</form>
```

フォームのコードを上記のようなものに更新してください。

`<li>` 要素はコードを扱いやすく構造化するとともに、スタイル設定を容易にするため (後述) に置いています。
 ユーザビリティとアクセシビリティのため、それぞれのフォームコントロールに明示的にラベルをつけます。
 `for` 属性をすべての `<label>` 要素に使用し、その値として関連付けるフォームコントロールの `id` を取ります。これで、フォームコントロールをラベルと関連付けることができます。

これには利点があります — フォームコントロールにラベルを関連付けて、ユーザーがマウス、トラックパッド、タッチ端末でラベルをクリックすると、対応するウィジェットがアクティブになり、スクリーンリーダーのユーザーに読み上げられるアクセシブルな名前が提供されます。この属性の利点をさらに知りたいのでしたら、 ウェブフォームの構築方法 の記事ですべてを詳しく説明しています。

`<input>` 要素において、もっとも重要な属性は、`type` 属性です。
 この属性は `<input>` 要素の見た目や動作を定義するため、とても重要です。
 これについてもっと詳しいことは、基本的なネイティブフォームコントロールの記事にあります。

* このシンプルな例では、最初の input に text という値を使用しています。これはこの属性の既定値です。
 これはあらゆるテキストを受け入れる、単一行のテキストフィールドを表します。
* 2 番目の input では、 email という値を使用しています。これは正しい形式のメールアドレスのみを受け付ける単一行のテキストフィールドを定義します。
 この値は基本的なテキストフィールドを、ユーザーによって入力されたデータをチェックするようにする「賢い」フィールドへと変化させます。
 また、スマートフォンのように動的なキーボードのある端末で、メールアドレスを入力するのにふさわしいキーボードレイアウト（例えば既定で @ 記号があるもの）が表示されるようにします。
 フォームの検証について詳しく知りたい場合は、データフォームの検証の記事をご覧ください。

 大事なことを言い忘れましたが、`<input>` と `<textarea></textarea>` の構文に注意してください。
 これは HTML の奇妙な点の 1 つです。
 `<input>` タグは空要素です。つまり、終了タグは不要です。
 一方 `<textarea>` は空要素ではないので、適切な終了タグで閉じる必要があります。これは HTML フォームの特定の機能、つまり既定値の定義方法に影響があります。
 `<input>` 要素の既定値を定義するには、次のように `value` 属性を使う必要があります。

```html
<input type="text" value="既定でこの要素にはこの文章が挿入されます" />
```

一方、 `<textarea>` の既定値を定義したい場合は、次のように既定値を `<textarea>` の開始タグと終了タグの間に書いてください。

```html
<textarea>
既定でこの要素にはこの文章が挿入されます
</textarea>
```

### `<button>` 要素

 フォームはほぼできあがりました。あとは、ユーザーがフォームに記入したらデータを「送信」するためのボタンを追加します。
 これは、`<button>` 要素を使用して簡単にできます。終了タグ `</ul>` の直前に次の行を追加してください。

```html
<li class="button">
  <button type="submit">メッセージを送信</button>
</li>
```

`<button>` 要素は `type` 属性を受け入れます。これは `submit`、`reset`、`button` の 3 種類の値のうち 1 つを受け入れます。

* `submit` ボタン（既定値）をクリックすると、フォームのデータを `<form>` 要素の `action` 属性で定義したウェブページへ送信します。
* `reset` ボタンをクリックすると、直ちにすべてのフォームウィジェットを既定値にリセットします。 UX の観点では、このボタンは悪い行為であると考えられており、必要な理由がない限りこのボタンは使用しないようにしてください。
* `button` ボタンをクリックすると*何もしません*! おかしなことのように見えますが、独自のボタンを作成するのに驚くほど役立ちます。 JavaScript でその機能を定義することができます。

**メモ:** `<input>` 要素を使用して、対応する `type` を指定してボタンを作成することもできます。例えば `<input type="submit">` のように。`<button>` 要素との大きな違いは、`<input>` 要素ではラベルとしてプレーンテキストしか許容しませんが、`<button>` 要素ではすべての HTML コンテンツを使用して、もっと複雑でクリエイティブなボタンの内容を作成することができます。

基本的なフォームの整形
-----------

フォームの HTML コードの記述ができました。このフォームを保存してブラウザーで見てみてください。今のところ、かなり不格好であることがわかると思います。

**メモ:** 作成した HTML コードが正しくないと思われる場合は、完成例と比較してみてください — first-form.html にあります (ライブ版も参照)。

フォームをきれいにスタイル付けするのは、なかなか難しいものです。フォームのスタイル付けを詳しく教えるのはこの記事の範囲外なので、とりあえず見た目が問題ないように CSS を追加してもらうだけにしておきましょう。

最初に、ページの HTML の head 内に `<style>` 要素を追加します。次のようになります。

```html
<style></style>
```

`style` タグの中に、以下の CSS を追加してください。

```css
form {
  /\* フォームをページの中央に配置 \*/
  margin: 0 auto;
  width: 400px;
  /\* フォームの輪郭 \*/
  padding: 1em;
  border: 1px solid #ccc;
  border-radius: 1em;
}

ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

form li + li {
  margin-top: 1em;
}

label {
  /\* 大きさと配置を統一 \*/
  display: inline-block;
  width: 90px;
  text-align: right;
}

input,
textarea {
  /\* すべてのテキストフィールドのフォント設定を一致させる
 既定で、 textarea には等幅フォントが設定されている \*/
  font: 1em sans-serif;

  /\* テキストフィールドの大きさを統一 \*/
  width: 300px;
  box-sizing: border-box;

  /\* フォームフィールド境界に合わせる \*/
  border: 1px solid #999;
}

input:focus,
textarea:focus {
  /\* フォーカスのある要素を強調する \*/
  border-color: #000;
}

textarea {
  /\* 複数行のテキストフィールドをラベルに揃える \*/
  vertical-align: top;

  /\* テキスト入力に十分な空間を与える \*/
  height: 5em;
}

.button {
  /\* ボタンを他のテキストフィールドと同じ場所に置く \*/
  padding-left: 90px; /\* label 要素と同じサイズ \*/
}

button {
  /\* このマージンは、ラベルとテキストフィールドの間のスペースと
 おおよそ同じスペースを表す \*/
  margin-left: 0.5em;
}
```

保存して再読み込みすると、フォームがよりきれいになりました。

**メモ:** Github の first-form-styled.html にあります(ライブ版も確認)。

ウェブサーバーへのデータの送信
---------------

 最後の、またもっともややこしいであろう部分が、サーバー側でのフォームデータの扱いです。
 `<form>` 要素は `action` 属性と `method` 属性により、どこへどのようにデータを送信するかを定義できます。

フォームコントロールには `name` をつけます。これらの名前はクライアント側とサーバー側の両側で重要です。ブラウザー側ではそれぞれのデータにどのような名前をつけるかを示すものであり、サーバー側では名前によってそれぞれのデータを扱うことができます。フォームデータは名前/値のペアとしてサーバーに送信されます。

データに名前をつけるために、各々のデータを集めるフォームウィジェットの `name` 属性を使用しなければなりません。ここでもフォームのコードで見てみましょう。

```html
<form action="/my-handling-form-page" method="post">
  <ul>
    <li>
      <label for="name">Name:</label>
      <input type="text" id="name" name="user\_name" />
    </li>
    <li>
      <label for="mail">E-mail:</label>
      <input type="email" id="mail" name="user\_email" />
    </li>
    <li>
      <label for="msg">Message:</label>
      <textarea id="msg" name="user\_message"></textarea>
    </li>

    …
  </ul>
</form>
```

 この例では、フォームから "`user_name`", "`user_email`", "`user_message`" という 3 つのデータが送信されます。
 このデータは、 HTTP の `POST` メソッドを用いて "`/my-handling-form-page`" という URL に送信されます。

 サーバー側では、 URL "`/my-handling-form-page`" にあるスクリプトが、 HTTP リクエストに含まれる 3 つのキー/値の項目のリストとしてデータを受け取ることになります。
 このスクリプトがどのようにデータを処理するかは、あなた次第です。
 各サーバーサイド言語 (PHP, Python, Ruby, Java, C# など) は、フォームデータを処理する独自のメカニズムを持っています。
 そのことについて深く掘り下げることはこのガイドの範囲外ですが、もっと知りたい場合は、この後の フォームデータの送信 の記事でいくつかの例を示しています。

まとめ
---

おめでとうございます。初めてのウェブフォームが完成しました。こちらが最終結果のデモです。
```

<form action="/my-handling-form-page" method="post">
  <div>
    <label for="name">Name:</label>
    <input type="text" id="name" name="user\_name" />
  </div>

  <div>
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user\_email" />
  </div>

  <div>
    <label for="msg">Message:</label>
    <textarea id="msg" name="user\_message"></textarea>
  </div>

  <div class="button">
    <button type="submit">Send your message</button>
  </div>
</form>
```

```
form {
  /\* Just to center the form on the page \*/
  margin: 0 auto;
  width: 400px;

  /\* To see the limits of the form \*/
  padding: 1em;
  border: 1px solid #ccc;
  border-radius: 1em;
}

div + div {
  margin-top: 1em;
}

label {
  /\* To make sure that all label have the same size and are properly align \*/
  display: inline-block;
  width: 90px;
  text-align: right;
}

input,
textarea {
  /\* To make sure that all text field have the same font settings
 By default, textarea are set with a monospace font \*/
  font: 1em sans-serif;

  /\* To give the same size to all text field \*/
  width: 300px;

  -moz-box-sizing: border-box;
  box-sizing: border-box;

  /\* To harmonize the look & feel of text field border \*/
  border: 1px solid #999;
}

input:focus,
textarea:focus {
  /\* To give a little highlight on active elements \*/
  border-color: #000;
}

textarea {
  /\* To properly align multiline text field with their label \*/
  vertical-align: top;

  /\* To give enough room to type some text \*/
  height: 5em;

  /\* To allow users to resize any textarea vertically
 It works only on Chrome, Firefox and Safari \*/
  resize: vertical;
}

.button {
  /\* To position the buttons to the same position of the text fields \*/
  padding-left: 90px; /\* same size as the label elements \*/
}

button {
  /\* This extra margin represent the same space as the space between
 the labels and their text fields \*/
  margin-left: 0.5em;
}
```

これはほんの開始点です、しかし — さて、より深く見ていくときが来ました。ウェブフォームはここで見てきたものよりさらに強力であり、ガイドの他の記事で残りの部分を習得できます。

* Overview: Forms
* 次のページ


古いブラウザーでの HTML フォーム - ウェブ開発を学ぶ

古いブラウザーでの HTML フォーム
===================

ウェブ開発者は誰でも、ウェブが自分たちにとって非常に厳しい場所であることを、すぐに (時には痛みを伴って) 学びます。最悪の災いは古いブラウザーです。「古いブラウザー」というと、 Safari や古いバージョンの Internet Explorer を思い浮かべますが、それだけではありません。モバイルの世界では、古い Android スマホや iPhone のように、ブラウザーも OS もアップデートできない場合、アップデートされない純正ブラウザーも古いブラウザーです。

この荒れた環境に対応するのも仕事のうちです。幸いなことに、知っておくと古いブラウザーによる問題のほとんどを解決することができる秘訣があります。また、 HTML の `<input>` 型は、対応していなくても失敗はしません。 `type=text` で代替されます。

問題について知る
--------

一般的なパターンを理解するには、ブラウザーのドキュメントを読むことが役立ちます。 MDN でこの記事を読んでいるのであれば、始めるのにふさわしい場所にいます。使用したい要素（または DOM インタフェース）の対応状況を確認するだけです。 MDN には、ウェブページで使用できるほとんどの要素、プロパティ、API の互換性一覧表が用意されています。他にも驚くほど役に立つリソースがあります。

HTML フォームでは複雑なやり取りが行われるため、シンプルに保つという経験則があり、「KISS の原則」とも呼ばれています。フォームを「よりかっこよく」あるいは「高機能に」したい場合はたくさんありますが、効率的なフォームの作成はデザインや技術の問題ではありません。むしろ、シンプルさ、直感性、そしてユーザーとの対話のしやすさが重要なのです。 forms usability on UX For The Masses のチュートリアルがこれをよく説明しています。

### グレイスフルデグラデーションはウェブ開発者の最大の味方

グレイスフルデグラデーションとプログレッシブエンハンスメントは、様々なブラウザーに同時に対応することにより、優れたものを作ることができる開発パターンです。新しいブラウザーで何かを構築した場合、古いブラウザーでも同じ方法または別な方法で動作するのであれば、グレイスフルデグラデーションが実施できていることになります。

HTML フォームに関する例をいくつか見ていきましょう。

#### HTML の入力型

HTML5 で追加された入力型は、劣化の仕方が高度に予測可能であるため、古いブラウザーでもすべて使用可能です。ブラウザーにとって未知の `type` 属性の値が `<input>` 要素にあった場合、その値が `text` であったかのように代替されます。

```html
<label for="myColor">
  Pick a color
  <input type="color" id="myColor" name="color" />
</label>
```

| 対応済み | 未対応 |
| --- | --- |
| Screen shot of the color input on Chrome for Mac OSX | Screen shot of the color input on Firefox for Mac OSX |

#### フォームのボタン

HTML フォームでボタンを定義する方法は 2 つあります。

* `<input>` 要素の `type` 属性に `button`、`submit`、`reset`、`image` のいずれかの値に設定したもの
* `<button>` 要素

##### `<input>`

`<input>` 要素は、要素セレクターを使用して CSS を適用したい場合に少し難しくなることがあります。

```html
<input type="button" value="click me" />
```

すべての input から境界線を削除する場合、ボタンについてのみ既定の外見に戻すことができるでしょうか？

```css
input {
  /\* この規則は、input 要素で定義するボタンを含む、境界線を持つ入力型の
 既定のレンダリングを無効にします \*/
  border: 1px solid #ccc;
}
input[type="button"] {
  /\* これでは既定のレンダリングを復元できません \*/
  border: none;
}
input[type="button"] {
  /\* これでも復元できません。実際、どのブラウザーでもできる標準の方法はありませ \*/
  border: auto;
  border: initial;
}
input[type="button"] {
  /\* 対応していれば、これが既定のレンダリングに戻す最も近い方法です。 \*/
  border: revert;
}
```

詳しくは、CSS のグローバル値である `revert` を参照してください。

##### `<button>`

`<button>` 要素は 2 つの問題に悩まされていましたが、すでに解決しました。

* 古いバージョンの Internet Explorer では、クリックされたときに、 `<button>` 要素の開始タグと終了タグの間にある HTML コンテンツが、 `value` 属性の内容の代わりに送信されるというバグがありました。これは、ユーザーがどのボタンをクリックしたかによってデータ処理が決まる場合など、その値を送信する必要がある場合にのみ問題となっていました。
* 一部のとても古いブラウザーは `submit` を `type` 属性の既定値として使用していませんでした。すべての現在のブラウザーでは解決していますが、 `type` 属性を常に `<button>` 要素に設定することを推奨します。

```html
<!-- ボタンをクリックすると "A" ではなく "<em>Do A</em>" を送信する場合があります -->
<button type="submit" name="IWantTo" value="A">
  <em>Do A</em>
</button>
```

プロジェクトの制約に基づいて、どちらの解決策を選択するかはあなた次第です。

### CSS を手放そう

HTML フォームの大きな問題の一つは、 CSS によるフォームウィジェットのスタイル付けです。フォームコントロールの外観は、ブラウザーや OS に依存します。例えば、 color 型の入力は、 Safari、Chrome、Firefox のそれぞれのブラウザーによって外見が異なりますが、カラーピッカーのウィジェットは、OS のネイティブカラーピッカーを開くため、端末上のどのブラウザーでも同じになります。

一般に、フォームコントロールの既定の外観は変更しない方が良いと考えられています。というのも、 1 つの CSS プロパティの値を変更すると、一部の入力型は変更されますが、他の入力型は変更されないからです。例えば、 `input { font-size: 2rem; }` と宣言した場合、 `number`、`date`、`text` には影響がありますが、 `color` や `range` には影響しません。プロパティを変更すると、予期せぬ形でウィジェットの外観に影響を与えることがあります。例えば、 `[value] { background-color: #ccc; }` は、 `value` 属性を持つすべての `<input>` を対象としていますが、 `<meter>` の背景色や境界線の角の丸めを変更すると、ブラウザーによって異なる予期せぬ結果になる可能性があります。 `appearance: none;` と宣言してブラウザーのスタイルを削除することもできますが、一般的には目的を達成できません。すべてのスタイルが失われ、訪問者が慣れ親しんだ既定のルック＆フィールが削除されるからです。

まとめるとすると、フォームコントロールのウィジェットに CSS でスタイル付けすることで、予測できない副作用が発生することがあります。だからやめましょう。 フォームコントロール向けの CSS プロパティの互換性一覧表の記事の複雑さからもわかるように、非常に難しいのです。テキスト要素に多少の調整 (サイズやフォントの色など) を行うことはまだ可能でも、必ず副作用が発生します。最良の方法は、 HTML フォームウィジェットにスタイルをまったく適用しないことです。しかし、周囲のアイテムになら、どれでも適用することはできます。また、どうしてもフォームウィジェットの既定のスタイルを変更しなければならない場合は、スタイルガイドを定義して、すべてのフォームコントロールの一貫性を確保し、ユーザーの使い勝手を損なわないようにしてください。また、 JavaScript でのウィジェットの再構築など、難しいテクニックを検討することもできます。しかし、その場合は、そのような愚かな要求をするクライアントに請求することをためらってはいけません。

機能検出とポリフィル
----------

CSS や JavaScript は素晴らしい技術ですが、古いブラウザーで壊れないようにすることが重要です。ターゲットとしているブラウザーで完全に対応していない機能を使用する前には、機能検出を行う必要があります。

### CSS の機能検出

置き換えられたフォームコントロールウィジェットをスタイル付けする前に、 `@supports` を使用してその機能にブラウザーが対応しているかどうかをチェックすることができます。

```css
@supports (appearance: none) {
 input[type="search"] {
   appearance: none;
   /\* restyle the search input \*/
 }
```

`appearance` プロパティは、要素をプラットフォームのネイティブのスタイルで表示したり、 `none` の値を指定することで、既定のプラットフォームのネイティブベースのスタイルを削除したりするために使用されます。

### 控えめな JavaScript

最大の問題のひとつは、API が利用できるかどうかです。そのため、「控えめな」 JavaScript によって取り組むことベストプラクティスであると考えられています。これは、2 つの要件によって定義される開発パターンです。

* 構造と動作を厳密に分割する。
* コードが動作しない場合でも、コンテンツや基本的な機能はアクセス可能かつ利用可能のままでなければならない。

The principles of unobtrusive JavaScript (原文は Peter-Paul Koch 氏によって Dev.Opera.com 向けに記述され、現在は Docs.WebPlatform.org に移動しました) で、これらのアイデアを明快に説明しています。

### Modernizr ライブラリー

欠けている API を提供することで、すばらしい "ポリフィル" が大きな助けになるケースが多数あります。ポリフィルは、古いブラウザーにおける機能性の "穴を埋める" 小さな JavaScript コードです。ポリフィルは任意の機能のサポート状況を改善するために使用できますが、JavaScript 向けに使用するのは CSS や HTML 向けより低リスクです。JavaScript が動作しない可能性は多数あります(ネットワークの問題、スクリプトの競合 など)。しかし JavaScript については、控えめな JavaScript を念頭に置いて取り組む場合はポリフィルが欠けたとしても、重大な問題にはなりません。

欠けている API に対してポリフィルを適用する最善の方法は、Modernizr ライブラリー、およびそこからスピンオフしたプロジェクトである YepNope を使用することです。Modernizr は、機能が利用できるかを確認して適宜対応を行えるようにするためのライブラリーです。YepNope は、条件付きで読み込みを行うライブラリーです。

例を示します。

```js
Modernizr.load({
  // ブラウザーがフォーム検証 API に対応しているかを確認します
  test: Modernizr.formvalidation,

  // ブラウザーが対応していない場合は、以下のポリフィルを読み込みます
  nope: form_validation_API_polyfill.js,

  // どの場合でも、API に依存するコアアプリのファイルを読み込みます
  both: app.js,

  // 両方のファイルを読み込んだら、アプリを初期化するためにこの関数を呼び出します
  complete: function () {
    app.init();
  },
});
```

Modernizr チームはすばらしいポリフィルのリストを管理しています。必要なポリフィルを選びましょう。

**メモ:** Modernizr は、控えめな JavaScript や グレイスフルでグラデーションのテクニックに取り組むことを支援するためのすばらしい機能を搭載しています。Modernizr のドキュメントをご覧ください。

### パフォーマンスに注意を払う

Modernizr のようなスクリプトはパフォーマンスを非常に意識していますが、200 キロバイトのポリフィルをロードすると、アプリケーションのパフォーマンスに影響を与えます。これは、古いブラウザーでは特に重要です。古いブラウザーの多くは JavaScript エンジンが非常に遅く、ポリフィルをすべて実行するとユーザーに負担がかかります。パフォーマンスはそれ自体が問題ですが、古いブラウザーはとても敏感です。基本的に古いブラウザーは遅く、ポリフィルが増えれば増えるほど、より多くの JavaScript を処理しなければなりません。つまり、新しいブラウザーに比べて二重に負担がかかるのです。古いブラウザーでコードをテストし、実際にどのように動作するかを確認してください。すべてのブラウザーでまったく同じ機能を使うよりも、一部の機能を削除したほうがユーザーの使い勝手が向上することもあります。最後になりましたが、常にエンドユーザーのことを考えてください。

おわりに
----

このように、ブラウザーや OS における既定のフォームコントロールの外観を考慮することは重要です。これらの問題に対処するためのテクニックは数多くありますが、そのすべてをマスターすることは、この記事の範囲を超えています。大前提として、既定の実装を変更することに価値があるかどうかを検討してから挑戦してください。

この HTML フォームガイドのすべての記事を読んでいれば、フォームの使用に慣れているはずです。新しいテクニックやヒントを見つけた場合は、ガイドの改善にご協力ください。

関連情報
----

### 学習経路

* 初めてのフォーム
* ウェブフォームの構築方法
* ネイティブのフォームウィジェット
* HTML5 の入力型
* 高度なフォームコントロール
* UI 擬似クラス
* ウェブフォームへのスタイル設定
* クライアントサイドのフォーム検証
* フォームデータの送信
### 高度なトピック

* JavaScript によるフォームの送信
* カスタムフォームウィジェットの作成方法
* 古いブラウザーでの HTML フォーム
* フォームへの高度なスタイル設定
* フォームコントロール向けの CSS プロパティの互換性一覧表


ユーザ入力とコントロール - ウェブ開発を学ぶ

ユーザ入力とコントロール
============

現代のウェブのユーザー入力は、単純なマウスやキーボードだけではありません。この記事では、ユーザー入力を管理し、オープンなウェブアプリに制御を実装するための推奨事項を、FAQ、実例、および基礎となる技術について、より詳細な情報を必要とする人のための詳細な情報へのリンクとともに提供します。関連する API とイベントには、タッチイベント、Pointer Lock API、Screen Orientation API、Fullscreen API、ドラッグ＆ドロップ API などがあります。

ユーザー入力とコントロールのワークフロー
--------------------

次の図式は、ユーザー入力の仕組みを実装するための典型的なワークフローを説明しています。

![](/ja/docs/Learn/Forms/User_input_methods/user-input-and-controls.png)

最初に、マウス、キーボード、指でのタッチなどから、アプリケーションで対象としたい入力の仕組みをどれにするかを決める必要があります。入力の仕組みを決めたのであれば、ウェブプラットフォームや JavaScript ライブラリーによって提供されているツールを使い、制御することができます。

推奨事項
----

利用できる入力の仕組みはアプリを動かしているデバイスの性能に依存します。

* デバイスの中にはタッチスクリーンディスプレイを提供するものがあります。そのウェブプラットフォームは、タッチを基にしたユーザーインターフェースで指の動きを解釈するためのタッチイベントを提供します。
* ポインターを操作する方法としてマウスやタッチパッドを提供しているデバイスの場合、Pointer Lock API が一人称視点の 3D ゲームの実装や、他のアプリがポイントを合わせているデバイスの全ての制御を要求するのに役立ちます。そして Fullscreen API は、あなたのアプリを全画面モードで表示するのに役立ちます。
* コンテンツが編集可能な要素（contentEditable など）のような機能を使うことで、速いリッチテキストエディターを実装することができ、そしてドラッグ＆ドロップ APIはユーザーがあなたのアプリ内に要素を移動することを可能にします。画面の向きがあなたのアプリで問題である時、Screen Orientation API を通して、画面の向きの状態を参照でき、またその他のアクションを実行できます。
* キーボードのアクセシビリティが適切か常に気に掛ける必要があります。多くのユーザーはキーボードのみを使いウェブサイトやアプリを操作します。ですので、あなたのシステムの機能性からそれを除外することは良くない考えです。

以下は推奨事項一式であり、オープンなウェブアプリでそのようなツールを利用するためのベストプラクティスです。

### 使用する入力の仕組みを決める

#### キーボード

キーボード入力はあなたのアプリによって制御できます。例えば、何らかのキーが押された時に制御を追加したい場合、ウィンドウオブジェクトにイベントリスナーを追加する必要があります。

```js
window.addEventListener("keydown", handleKeyDown, true);
window.addEventListener("keyup", handleKeyUp, true);
```

`handleKeyDown` と `handleKeyUp` は、`keydown` と `keyup` イベントについての制御を実装する関数です。

**メモ:** キーボードイベントについて、より知りたい人はイベントリファレンス と `KeyboardEvent` ガイドをご確認ください。

#### マウス

ユーザーがマウスのようなポインティングデバイスと関わっている時に発生するイベントは `MouseEvent` DOM インターフェースによって表されます。一般的なマウスイベントは、`click イベント`、`dblclick イベント`、`mouseup イベント`、そして `mousedown イベント`を含みます。マウスイベントインターフェースが使用している全てのイベントの一覧は、イベントリファレンスに記載されています。

入力デバイスがマウスの場合、ユーザー入力を Pointer Lock API やドラッグ＆ドロップ API の実装でも制御できます (下記を参照してください)。

#### 指でのタッチ

タッチスクリーンデバイスにインストールされることを目的としている ウェブアプリを開発している時、ディスプレイ解像度とユーザー入力に関して異なる性能を考慮することは良いプラクティスです。タッチイベントは、タッチスクリーンデバイス上のインタラクションな要素と一般的なインタラクションジェスチャーを実装するのに役立ちます。

タッチイベントを使いたいのであれば、イベントリスナーを追加して、イベントが発火された時に呼び出されるハンドラー関数を指定する必要があります。

```js
element.addEventListener("touchstart", handleStart, false);
element.addEventListener("touchcancel", handleCancel, false);
element.addEventListener("touchend", handleEnd, false);
element.addEventListener("touchmove", handleMove, false);
```

ここでの `element` は、あなたがタッチイベントを登録したい DOM 要素です。

**メモ:** タッチイベントでできることについての更なる情報は、タッチイベントガイドを読んでください。

#### ポインターイベント

マウス、指でのタッチ、ペン入力など複数の入力形式が内蔵されているデバイスを扱う時、これら全ての異なる制御の仕組みを機能させるソリューションを開発することは難しいかもしれません。Pointer Events は、デバイス毎の扱いを標準化することにより、開発者がデバイスを横断してイベントを管理することをより簡単にするのに役立ちます。マウスカーソル、ペン、タッチ（マルチタッチを含む）、またはその他のポインティング入力デバイスによって、ポインターはスクリーン上のあらゆる接点となることができます。汎用的なポインター入力を扱うためのイベントは、`pointerdown`、`pointermove`、`pointerup`、`pointerover`、`pointerout` などのマウス用のイベントとよく似ています。

**メモ:** Pointer Events はまだ広くサポートされていませんが、pointer.js polyfill は Mozilla Github で利用可能です。

### コントロールの実装

#### ポインターロック

典型的なゲーム開発では、ブラウザやスクリーンの境界を超えた時でさえもマウスイベントにアクセスすることが必要なケースがあるかもしれません。Pointer Lock API はポインティングデバイスの全ての制御を可能にします。

以下は `element` にポインターロックをリクエストしているコードです。

```js
element.requestPointerLock();
```

**メモ:** 全てのチュートリアルとリファレンスは、Pointer Lock API のページを読んでください。

#### 画面の向き

画面の向きがあなたのアプリケーションの問題である時、Screen Orientation API を通して画面の向きの状態を参照し、状態が変化した時に通知し、そして画面の向きを特定の状態（大抵はポートレートもしくはランドスケープ）に固定することができます。

画面の向きのデータは `screen.orientation` 属性、または `orientation` メディア特性を通して取得することができます。`screen.orientation` が変化した時、`screen.orientationchange` イベントがスクリーンオブジェクトで発火されます。`screen.lockOrientation` メソッドを呼ぶことで画面の向きを固定することができます。また、`screen.unlockOrientation` メソッドはそれまで設定されていた画面のロックを全て解除します。

**メモ:** Screen Orientation API についてのより多くの情報は画面の向きの管理で確認することができます。

#### 全画面

あなたのアプリケーションの要素を全画面モードで表示する必要があるかもしれません(例えば `<video>` のような)。その要素で `Element.requestFullscreen()` を呼び出すことによって全画面モードを実現することができます。多くのブラウザーが、これをまだベンダー接頭辞とともに実装していることを覚えておいてください。ですので、あなたのコードを以下のようにフォークする必要があるかもしれません:

```js
var elem = document.getElementById("myvideo");
if (elem.requestFullscreen) {
  elem.requestFullscreen();
} else if (elem.msRequestFullscreen) {
  elem.msRequestFullscreen();
} else if (elem.mozRequestFullScreen) {
  elem.mozRequestFullScreen();
} else if (elem.webkitRequestFullscreen) {
  elem.webkitRequestFullscreen();
}
```

**メモ:** 全画面の機能性をあなたのアプリケーションに追加することについてもっと知るには、私たちの全画面モードの使用についてのドキュメントを読んでください。

#### ドラッグ＆ドロップ

ドラッグ＆ドロップ API によりあなたのアプリケーションのユーザーは、クリックして要素を超えてマウスボタンを押し続け、他の場所にドラッグし、そしてその要素を移動先にドロップするためにマウスボタンを離すことができます。

以下は、コンテンツのセクションにドラッグできるようにする例です。

```html
<div
 draggable="true"
 ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
  This text <strong>may</strong> be dragged.
</div>
```

私たちが実装する点は以下です:

* ドラッグ可能にしたい要素の `draggable` 属性を true にセットします。
* `dragstart` イベントのためのリスナーを追加し、このリスナーの中にドラッグデータをセットします。

**メモ:** MDN のドラッグ＆ドロップドキュメントでもっと多くの情報を確認することができます。

#### コンテンツを編集可能にする

`contenteditable` 属性を使うことで、開いているウェブアプリのあらゆる DOM 要素を直接編集することができます。

```html
<div contenteditable="true">このテキストは閲覧者が編集することができます。</div>
```

**メモ:** 互換性や例、その他リソースに関する情報は コンテンツを編集可能にするガイドで確認することができます。

例
-

**複数のタッチポイントを同時に追跡する**

この例は一度に複数のタッチ箇所を追跡しており、ユーザーは ``<canvas>`` の中で一本以上の指で同時に描くことができます。タッチイベントをサポートしているブラウザーでのみ動きます。

**シンプルなポインターロックデモ**

シンプルなコントロールシステムをセットアップするためのポインターロックの使い方を紹介するために、シンプルなポインターロックデモを記載しています。このデモでは ``<canvas>`` 要素の中にボールを描くために JavaScript を使っています。canvas をクリックすると、ポインターロックはその後、マウスポインターの除去と直接マウスを使ってボールを移動させるために利用されます。

**コンテンツを編集可能にするデモ**

このデモは、編集可能なドキュメントセクションを作成することに利用できる contenteditable がどのように動くか表示しており、その状態はその後 ローカルストレージを使い保存されます。

チュートリアル
-------

* タッチイベントガイド
* 画面の向きの管理
* 全画面モードの使用
* 複数のアイテムのドラッグ＆ドロップ
* ドラッグ操作ガイド
関連情報
----

* `MouseEvent`
* `KeyboardEvent`
* タッチイベント
* Pointer Lock API
* Screen Orientation API
* Fullscreen API
* ドラッグ＆ドロップ API
* コンテンツを編集可能にする
* Keyboard events in Firefox OS TV
* Implementing TV remote control navigation


クライアント側のフォーム検証 - ウェブ開発を学ぶ

クライアント側のフォーム検証
==============

* 前のページ
* Overview: Forms
* 次のページ

 データをサーバーへ送信する前に、必須のフォームコントロールが記入され、すべてのフォームコントロールが正しい書式で記入されていることを保証することが重要です。
 この**クライアント側フォーム検証** (client-side form validation) は、送信されるデータが様々なフォームコントロールで指定されている要件を満たしていることを保証します。
 この記事では、クライアント側フォーム検証の基本概念と例を紹介します。

|  |  |
| --- | --- |
| 前提知識: |
 コンピューターリテラシー、適度な
 HTML、CSS、JavaScript の理解。
  |
| 目的: | フォーム検証とは何か、なぜ重要なのか、どのように実装するのかを理解すること。 |

 クライアント側の検証は最初のチェックであり、ユーザーの使い勝手を良くするために重要な機能ですクライアント側で不当なデータを捕捉することで、ユーザーはすぐに修正できます。
 もしも無効なデータがサーバーに送られてから拒否された場合、サーバーへの往復とクライアント側に戻ってユーザーにデータを修正するように指示することになり、かなり時間を浪費します。

 しかし、クライアント側の検証はセキュリティ対策*とは考えられません*。アプリは常に*サーバー側でも*クライアント側と**同様に**送信されたデータのセキュリティをチェックしてください。なぜならクライアント側の検証は容易に回避することができて、悪意のユーザーは簡単に、サーバーへ不正なデータを送信できます。
 何が起こり得るかは ウェブサイトセキュリティを見てください。サーバー側の検証はこのガイドの範囲を超えますが、覚えておいてください。

フォーム検証とは何か
----------

 有名なサイトの登録フォームに行き、データを求められている書式で入力しないと、フィードバックがあることに気づくでしょう。
 次のようなメッセージが表示されます。

* 「このフィールドは必須です」（このフィールドが空欄にできない場合）
* 「電話番号は XXX-XXXX の形式で入力してください」（あるデータフォーマットが必須の場合）
* 「有効なメールアドレスを入力してください」（入力データが適切なフォーマットではない場合）
* 「パスワードは 8 文字から 30 文字の間で、1 文字以上の大文字、記号、数字を含む必要があります。」（特に詳しいデータフォーマットが必要な場合）

 これは**フォーム検証**と呼ばれます。
 データを入力したとき、ブラウザー、またはウェブアプリケーションは、そのデータが正しい書式であり、アプリケーションに設定された制約に合っているかをチェックします。ブラウザーで行われる検証は**クライアント側**の検証と、サーバー側で行われるものは**サーバー側**の検証と呼ばれます。
 この章では、クライアント側の検証に集中します。

情報が正しく書式化されていれば、アプリケーションはデータをサーバーに送信し、（通常は）データベースに保存することができます。情報が正しく書式化されていない場合は、修正すべき点を説明するエラーメッセージを表示して、ユーザーに再試行を促します。

私たちはできるだけ簡単にフォームを埋めてもらいたいわけですが、なぜフォームを検証する必要があるのでしょうか？理由は主に 3 つあります。

* **正しいデータを正しい書式で入力してほしい。** ユーザーのデータが誤った形式で格納されたり、ユーザーが正しい情報を入力しなかったり、省略したりすると、アプリケーションが正しく動作しないからです。
* **ユーザーのデータを保護したい。** ユーザーに安全なパスワードを入力させることで、アカウント情報を保護しやすくなります。
* **自分たちを守りたい。** 悪意のあるユーザーが保護のないフォームを悪用して、そのフォームを一部に持つアプリケーションに危害を加える方法がたくさんあります。ウェブサイトセキュリティを参照してください。

**警告:** クライアントからサーバーに渡されたデータを信用しないでください。フォームが正しく検証を行い、クライアント側で悪意のある入力を防いでいるとしても、悪意のあるユーザーはネットワークリクエストを改ざんすることができます。
様々な種類のフォーム検証
------------

ウェブで見かけるクライアント側のフォーム検証には 2 つの種類があります。

* **組み込みフォーム検証** は、このモジュールを通して多くの場所で説明してきた、 HTML フォーム検証の機能を使用します。
 この検証は一般に、あまり JavaScript を必要としません。組み込みのフォーム検証は JavaScript よりもパフォーマンスがよいのですが、 JavaScript の検証ほどにはカスタマイズできません。
* **JavaScript** 検証は JavaScript を使ってコーディングされるものです。
 これは完全にカスタマイズ可能ですが、すべて作成する（かライブラリーを使う）必要があります。
組み込みフォーム検証の利用
-------------

最新のフォームコントロールの機能の一つに、 JavaScript に頼らない多くのユーザーデータの検証があります。
 これはフォーム要素の検証の属性を使って行います。
 これまで多くを見てきましたが、まとめ直すと次のようになります。

* `required`: フォームを送信する前に、フォームフィールドに入力する必要があるかどうかを指定します。
* `minlength` と `maxlength`: テキストデータ（文字列）の最小・最大長を指定します。
* `min` と `max`: 数値入力型の最小値、最大値を指定します。
* `type`: データを数字にするか、メールアドレスにするか、その他のプリセットされた特定の型にするかを指定します。
* `pattern`: データが指定された正規表現に一致するかどうかを指定します。

入力データをこの指定されたルールに基いて検証します。検証にパスすれば妥当で検証にパスしなければ妥当ではないと考えます。

要素が妥当な場合は、次のようになります。

* 要素が CSS の `:valid` 擬似クラスに一致します。これにより、妥当な要素に特定のスタイルを適用することができます。
* ユーザーがデータを送信しようとすると、ブラウザーは止めるもの（JavaScript など）が他になければ、フォームを送信します。

要素が不正なときは、次のようになります。

* 要素が CSS の `:invalid` 擬似クラスに一致し、エラーによっては他の UI 擬似クラス（`:out-of-range` など）に一致することもあります。これにより、不正な要素に特定のスタイルを適用することができます。
* ユーザーがデータを送信しようとすると、ブラウザーはフォームをブロックしてエラーメッセージを表示します。

**メモ:** サーバーへの送信を中断するエラーがいくつかあります。 `badInput`、`patternMismatch`、`rangeOverflow` または`rangeUnderflow`、`stepMismatch`、`tooLong` または`tooShort`、`typeMismatch`、`valueMissing`、または `customError` が含まれます。

入力要素の制約の検証
----------

この節では、これまで述べてきたいくつかの属性をテストします。

### 簡単な最初のファイル

簡単な例から始めましょう。― 好きな果物を banana （バナナ）か cherry （サクランボ）から選べる入力欄があるとします。単純なテキストの `<input>` とそれに合わせたラベル、送信の `<button>` から成ります。ソースコードは GitHub の fruit-start.html で、ライブサンプルは次の通りです。

```html
<form>
  <label for="choose">banana と cherry のどちらが好き?</label>
  <input id="choose" name="i-like" />
  <button>Submit</button>
</form>
```

```css
input:invalid {
  border: 2px dashed red;
}

input:valid {
  border: 2px solid black;
}
```

始めるにあたって、ハードディスク内の新しいディレクトリーに `fruit-start.html` のコピーを作成してください。

### required 属性

 最も単純な HTML の検証機能が `required` 属性です。
 入力欄を必須にしたい場合は、この属性を要素に追加してください。
 この属性が設定されていると、この要素が `:required` UI 擬似クラスに一致するようになり、入力欄が空であった場合にフォームが送信されずにエラーメッセージが表示されるようになります。
 空のままでは、この入力は不正とみなされ、`:invalid` UI 擬似クラスに一致します。

以下のように、 `required` 属性を入力欄に追加しましょう。

```html
<form>
  <label for="choose">banana と cherry のどちらが好き? (必須)</label>
  <input id="choose" name="i-like" required />
  <button>送信</button>
</form>
```

このサンプルファイルの中に含まれている CSS も書いておきましょう。

```css
input:invalid {
  border: 2px dashed red;
}

input:invalid:required {
  background-image: linear-gradient(to right, pink, lightgreen);
}

input:valid {
  border: 2px solid black;
}
```

 この CSS によって、入力が妥当でない場合には、入力を赤の破線で境界線を描きますが、入力が妥当な場合には、黒の直線で境界線を描きます。
 要求された値があり、値が妥当でないときは背景にグラデーションを追加します。つぎの例の動作を確認しましょう。

**メモ:** この例は GitHub の fruit-validation.html で見ることができます（ソースコードも見てください）。

値のないままフォームを送信してみましょう。妥当ではない入力がどのようにフォーカスされるか注意しましょう。デフォルトのエラーメッセージ（「このフィールドは入力必須です。」）が表示され、フォームの送信を抑止します。

`required` 属性に対応している要素にこの属性がある場合、その要素に値があるかないかによって、要素が `:required` 擬似クラスに一致するかどうかが決まります。もし `<input>` に値がなければ、`input` は`:invalid` 擬似クラスに一致します。

**メモ:** 使い勝手を良くするために、フォームのフィールドが必要なときにはユーザーに通知しましょう。
 これは使い勝手だけに良いというわけではなく、WCAG アクセシビリティ ガイドラインで求められています。
 また、本当に必要とする場合にのみ必須にしましょう。例えば誰かの性別や肩書などの情報は本当に必要でしょうか？

### 正規表現での検証

 もう一つとてもよく使われる機能は `pattern` 属性で、値として正規表現を取ります。
 正規表現 (regexp) はテキスト文字列の中の文字の組み合わせに一致させるために使うことができるため、フォームの検証には理想的であり、JavaScript と同様に様々な利用ができます。

 正規表現はかなり複雑です。このモジュールでは正規表現のすべてを説明する意図はありません。
 いくつかの例を挙げますのでどのように動作するか基本的な考えを把握してください。

* `a` — `a` の 1 文字に一致する (`b` や `aa` などではない)。
* `abc` — `a` と、その次の `b` と、その次の `c` の並びに一致する。
* `ab?c` — `a` と、その次にひとつだけ `b` があるかないかと、その次の `c` の並びに一致する ( `ac` または `abc`)
* `ab*c` — `a` と、その次に任意の数の `b` が続き、その次に `c` のある並びに一致する。( `ac`, `abc`, `abbbbbc`, 等)
* `a|b` — 一文字の `a` または `b` に一致する
* `abc|xyz` — `abc` の並びまたは `xyz` の並びに一致する。これは `abcxyz` や `a` や `y` などには一致しない。

正規表現には多くの組合せがあるので例はここまでとします。完全な一覧や多くの例は、正規表現のドキュメントを参照してください。

使用例を実装しましょう。HTML を更新して `pattern` 属性を追加しましょう。

```html
<form>
  <label for="choose">banana と cherry のどちらが好き?</label>
  <input id="choose" name="i-like" required pattern="[Bb]anana|[Cc]herry" />
  <button>Submit</button>
</form>
```

```
input:invalid {
  border: 2px dashed red;
}

input:valid {
  border: 2px solid black;
}
```

これは下記の更新があります。次のものを使ってみてください。

**メモ:** GitHub の fruit-pattern.html でライブ例を見ることができます（ソースコードも見てください）。

この例では、`<input>` 要素は "banana"、"Banana"、"cherry"、"Cherry" という 4 つの文字列値のうち 1 つを受け付けます。正規表現は大文字小文字を区別しますが、中括弧にはさまれた "Aa" のパターンを使って小文字と同様に先頭が大文字のバージョンをサポートします。

 この時点で、`pattern` 属性の中の値を以前に見たいくつかの例と同じ値に変更してみて、入力欄が有効になるように入力する値がどのように影響するかを確認してください。
 自分で考えた値も書いてみて、どのようになるか確認しましょう。
 果物に関する値を可能にすれば、例が分かりやすくなります。

もし `<input>` の空ではない値が正規表現パターンに一致しなかった場合、この `input` は `:invalid` 擬似クラスに一致します。

**メモ:** `<input>` 要素の型によっては、検証のために `pattern` 属性が必要ないことがあります。例えば `email` 型を指定すると、入力された文字列を、妥当な形式のメールアドレスまたは、 `multiple` 属性がある場合はカンマで区切られたメールアドレスのリストであることを確認する正規表現で検証します。

**メモ:** `<textarea>` 要素は `pattern` 属性に対応していません。

### 入力欄の長さの制約

`<input>` または `<textarea>` によって作成してすべてのテキストフィールドで文字数を制限したいときには `minlength` 属性と `maxlength` 属性が使用できます。
 フィールドが値をもっており、その文字数が `minlength` の値より少ないか、文字数が `maxlength` の値より大きい場合は、フィールドは不正です。

 ブラウザーはよくテキストフィールドに期待している以上に入力させないことがあります。単に `maxlength` を使うよりも良いユーザーエクスペリエンスは、入力文字数のフィードバックを提供してサイズ以下でコンテンツを編集できるようにもしておくことです。
 例えば、Twitter の文字入力の制限があります。これは JavaScript と `maxlength` を使った解決策の組み合わせ実現できます。

### 入力欄の値に制約を加える

 数値のフィールド (例えば `<input type="number">`) の場合、`min` 属性と `max` 属性によって入力に制限を加えられます。
 もしそのフィールドの値がこの範囲を超える場合、そのフィールドは妥当ではありません。

他の例を見てみましょう。fruit-start.html ファイルの新しいコピーを作成してください。

では、`<body>` 要素の中身を削除して、以下のように置き換えてください。

```html
<form>
  <div>
    <label for="choose">banana と cherry のどちらが好き?</label>
    <input
 type="text"
 id="choose"
 name="i-like"
 required
 minlength="6"
 maxlength="6" />
  </div>
  <div>
    <label for="number">どのくらい要りますか?</label>
    <input type="number" id="number" name="amount" value="1" min="1" max="10" />
  </div>
  <div>
    <button>Submit</button>
  </div>
</form>
```

* ここで、`text` フィールドには `minlength` 属性と `maxlength` 属性には 6 を指定しています。これは banana (バナナ) や cherry (さくらんぼ) の文字数と同じです。
* またここでは、`number` フィールドに `min` 属性で 1 を `max` 属性で 10 を指定しました。
 この範囲外の数字の入力は妥当ではないと表示されます。ユーザーは矢印を使ってこの範囲外の値に増減できませんが、ユーザーが数字を手入力した場合はデータは不正となります。
 この数字は必須ではないので、値を除去すると妥当になります。
```

input:invalid {
  border: 2px dashed red;
}

input:valid {
  border: 2px solid black;
}

div {
  margin-bottom: 10px;
}
```

例をライブで実行してみましょう。

**メモ:** GitHub の fruit-length.html でライブサンプルを見ることができます（ソースコードも見てください）

**メモ:** `<input type="number">` （および、 `range` や `date` のような他の型）は `step` 属性を取ることもでき、入力コントロール（数値の増加・減少ボタンなど）を使用するときに上げ下げすることができる値の刻みを設定することができます。上の例では `step` 属性を入れていませんので、既定値の `1` となります。つまり 3.2 のような浮動小数でも、不正になります。

### サンプル全体

HTML の内蔵検証機能の使い方を示す例の全体を示します。まずは HTML から:

```html
<form>
  <p>
    <fieldset>
      <legend>Do you have a driver's license?<span aria-label="required">*</span></legend>
      <!-- While only one radio button in a same-named group can be selected at a time,
 and therefore only one radio button in a same-named group having the "required"
 attribute suffices in making a selection a requirement -->
      <input type="radio" required name="driver" id="r1" value="yes"><label for="r1">Yes</label>
      <input type="radio" required name="driver" id="r2" value="no"><label for="r2">No</label>
    </fieldset>
  </p>
  <p>
    <label for="n1">How old are you?</label>
    <!-- pattern 属性は number 型の入力欄を実装していないものの、pattern
 属性には対応しているブラウザー向けの代替策として動作できます。
 なお、pattern 属性に対応しているブラウザーでは、number 型の入力欄
 で使用すると暗黙に失敗します。
 ここでは代替策としての使い方のみです。-->
    <input type="number" min="12" max="120" step="1" id="n1" name="age"
 pattern="\d+">
  </p>
  <p>
    <label for="t1">What's your favorite fruit?<span aria-label="required">*</span></label>
    <input type="text" id="t1" name="fruit" list="l1" required
 pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range">
    <datalist id="l1">
      <option>Banana</option>
      <option>Cherry</option>
      <option>Apple</option>
      <option>Strawberry</option>
      <option>Lemon</option>
      <option>Orange</option>
    </datalist>
  </p>
  <p>
    <label for="t2">What's your email address?</label>
    <input type="email" id="t2" name="email">
  </p>
  <p>
    <label for="t3">Leave a short message</label>
    <textarea id="t3" name="msg" maxlength="140" rows="5"></textarea>
  </p>
  <p>
    <button>Submit</button>
  </p>
</form>
```

この HTML をスタイル設定する CSS は:

```css
form {
  font: 1em sans-serif;
  max-width: 320px;
}

p > label {
  display: block;
}

input[type="text"],
input[type="email"],
input[type="number"],
textarea,
fieldset {
  width: 100%;
  border: 1px solid #333;
  box-sizing: border-box;
}

input:invalid {
  box-shadow: 0 0 5px 1px red;
}

input:focus:invalid {
  box-shadow: none;
}
```

これで次のようにレンダリングされます。

入力値と、それをサポートする入力型の制約に使える属性の完全なリストは、検証関連属性を見てください。

**メモ:** GitHub の fruit-length.html でライブサンプルを見ることができます(ソースコードも見てください)

JavaScript を使用したフォーム検証
----------------------

 内蔵のエラーメッセージの見かけを制御したい場合は、JavaScript を使用する必要があります。
 この節では、このようにするさまざまな方法を見ていきます。

### 制約検証 API

多くのブラウザーが制約検証 API に対応しています。以下のフォーム要素 DOM インターフェイスで利用できるメソッドとプロパティのセットで構成されています。

* `HTMLButtonElement` (`<button>` 要素を表現)
* `HTMLFieldSetElement` (`<fieldset>` 要素を表現)
* `HTMLInputElement` ( `<input>` 要素を表現)
* `HTMLOutputElement` (`<output>` 要素を表現)
* `HTMLSelectElement` (`<select>` 要素を表現)
* `HTMLTextAreaElement` (`<textarea>` 要素を表現)

制約検証 API には、上記の要素で利用できる、次のプロパティがあります。

* `validationMessage`: コントロールが満たさない検証制約を記述したローカライズされたメッセージを返します（存在する場合）。コントロールが制約検証の候補でない場合（`willValidate`が `false`）、または要素の値が制約を満たしている場合（有効である場合）には、空の文字列を返します。
* `validity`: 要素の検証状態を説明する `ValidityState` オブジェクトです。取りうる検証状態の詳細は `ValidityState`のリファレンスを参照してください。下記はよく使われるものを少し、一覧にしています。
    + `patternMismatch`: 値が指定した `pattern` に一致しない場合 `true` を、一致する場合 `false` を返す。true なら、要素は `:invalid` CSS 擬似クラスに一致する。
    + `tooLong`: `maxlength` 属性で指定した最大値より値が長い場合 `true` を、同じ長さ以下の場合 `false` を返す。true なら、要素は `:invalid` CSS 擬似クラスに一致する。
    + `tooShort`: `minlength` 属性で指定した最小値より値が短い場合 `true` を、同じ長さ以上の場合`false` を返す。true なら、要素は `:invalid` CSS 擬似クラスに一致する。
    + `rangeOverflow`: `max` 属性で指定し最大値より値が大きい場合`true` を、同じ大きさ以下の場合 `false` を返す。true なら、要素は `:invalid` と `:out-of-range`CSS 擬似クラスに一致する。
    + `rangeUnderflow`: `min` 属性で指定し最小値より値が小さい場合`true` を、同じ大きさ以上の場合 `false` を返す。true なら、要素は `:invalid` と `:out-of-range`CSS 擬似クラスに一致する。
    + `typeMismatch`: 値が要求する構文でない場合 `type` が `email` か `url` のとき)は `true` を、文法が正しい場合は `false` を返す。`true` なら、要素は `:invalid` CSS 擬似クラスに一致する。
    + `valid`: 要素が検証制約をすべて満たす、ゆえに妥当とみなされる場合`true` を、いずれかの制約を満たさない場合 `false` を返す。true なら、要素は `:valid` CSS 擬似クラスに一致する。そうでない場合は `:invalid` CSS 擬似クラスに一致する。
    + `valueMissing`: 要素に `required` 属性があって値がない場合は `true` を、そうでない場合 `false` を返す。true なら、要素は `:invalid` CSS 擬似クラスに一致する。
* `willValidate`: フォームが送信されるときに要素が検証される場合に `true` を返します。そうでない場合は `false` を返します。

また、制約検証 API では、上記の要素や `form` 要素に対して、以下のメソッドを利用することが可能です。

* `checkValidity()`: 要素の値で妥当性の問題がない場合に `true` を返します。そうでない場合は `false` を返します。要素が不正である場合、このメソッドは要素で `invalid` イベントを発生させます。
* `reportValidity()`: イベントを使用して、無効なフィールドを報告します。このメソッドは `onSubmit` イベントハンドラーでは `preventDefault()` と組み合わせて使用すると有益です。
* `setCustomValidity(message)`: 要素に独自のエラーメッセージを追加します。独自のエラーメッセージを設定すると、要素が不正であるとみなされる場合に指定したエラーが表示されます。これにより JavaScript で、標準の HTML 制約検証 API で提供されるもの以外の検証不合格状態を作り出すことができます。ユーザーに問題を報告する際に、メッセージが表示されます。

#### 独自のエラーメッセージを実装する

上記の HTML の検証制約の例で見てきたように、ユーザーが不正なフォームを送信しようとするたびにブラウザーはエラーメッセージを表示します。このメッセージを表示する方法は、ブラウザーにより異なります。

これらの自動のメッセージには、2 つの欠点があります。

* CSS でメッセージの表示方法を変更するための標準的な方法がありません。
* メッセージはブラウザーのロケールに依存しており、ある言語のページでエラーメッセージが別の言語で表示されることがあります。これは下記の Firefox スクリーンショットで見ることができます。

![Example of an error message with Firefox in French on an English page](/ja/docs/Learn/Forms/Form_validation/error-firefox-win7.png)

これらのメッセージの外見やテキストを変更するには、制約検証 API の最も一般的なユースケースです。この使用法を例で詳しく見てみましょう。

いくつかの簡単な HTML で開始します (空の HTML ファイルにこれを入力します; もしよければ、fruit-start.html を基礎としてもいいでしょう):

```html
<form>
  <label for="mail">メールアドレスを教えてください:</label>
  <input type="email" id="mail" name="mail" />
  <button>Submit</button>
</form>
```

このページに次の JavaScript を追加します。

```js
const email = document.getElementById("mail");

email.addEventListener("input", (event) => {
  if (email.validity.typeMismatch) {
    email.setCustomValidity("メールアドレスを入力してください。");
  } else {
    email.setCustomValidity("");
  }
});
```

ここでメールアドレス入力への参照を保管して、入力値が変更されるたびに制約コードが走るためのイベントリスナーを追加します。

このコードの中で、 email 入力欄の `validity.typeMismatch` プロパティが `true` を返しているかどうか、つまり、含まれる値が正規の email アドレスのパターンに一致しないことをチェックしています。その場合、`setCustomValidity()`メソッドをカスタムメッセージとともに呼び出します。これにより、入力が無効となるため、フォームを送信しようとすると、送信に失敗し、カスタムエラーメッセージが表示されます。

`validity.typeMismatch` が `false`の場合、空文字で `setCustomValidity()` メソッドを呼び出します。これは入力が妥当となり、フォームが送信されます。

次のもので試すことができます。

**メモ:** この例は GitHub の custom-error-message.html で見ることができます （ソースコードも見てください）。

#### より詳細な例

これまでほんとうに簡単な例を見てきましたので、少し複雑な独自の検証を作成するために API を使用する方法を見ていきましょう。

始めに、HTML です。また、次のものに沿ってみてください。

```html
<form novalidate>
  <p>
    <label for="mail">
      <span>メールアドレスを入力してください。</span>
      <input type="email" id="mail" name="mail" required minlength="8" />
      <span class="error" aria-live="polite"></span>
    </label>
  </p>
  <button>Submit</button>
</form>
```

この簡単なフォームでは、ブラウザーの自動検証を無効にするために `novalidate` 属性を使用しています。これで、検証を制御するためにスクリプトを使用できます。ただし、これは制約検証 API の対応や CSS の擬似クラス `:valid`, `:invalid`, `:in-range`, `:out-of-range` の適用を無効にするわけではありません。つまり、データを送信する前にブラウザーが自動的なフォームの妥当性確認を行わないとしても、あなた自身で確認を行って、フォームの状態に応じたスタイル設定ができます。

検証する入力は `<input type="email">`で、これは `required` (入力必須) で、8 文字の `minlength` があります。これをわれわれのコードで確認して、それぞれカスタムエラーメッセージを表示させてみましょう。

`<span>` 要素の中にエラーメッセージを表示させようとしています。 `<span>`にセットされた `aria-live` (en-US) 属性は、スクリーンリーダーのような支援技術を使用している人々を含む皆に、独自のエラーメッセージを提示するようにします。

**メモ:** ここでの要点は、フォームに `novalidate` 属性をつけると、フォームがエラーメッセージのバブルを表示するのを停止して、その代わり DOM 内にカスタムエラーメッセージを選択した方法で表示させられることです。

この CSS はフォームの見栄えを少し良くして、入力データが無効なときの見た目のフィードバックを提供します。

```css
body {
  font: 1em sans-serif;
  width: 200px;
  padding: 0;
  margin: 0 auto;
}

p \* {
  display: block;
}

input[type="email"] {
  appearance: none;

  width: 100%;
  border: 1px solid #333;
  margin: 0;

  font-family: inherit;
  font-size: 90%;

  box-sizing: border-box;
}

/\* これは不正なフィールド向けのスタイルです \*/
input:invalid {
  border-color: #900;
  background-color: #fdd;
}

input:focus:invalid {
  outline: none;
}

/\* これはエラーメッセージ向けのスタイルです \*/
.error {
  width: 100%;
  padding: 0;

  font-size: 80%;
  color: white;
  background-color: #900;
  border-radius: 0 0 5px 5px;

  box-sizing: border-box;
}

.error.active {
  padding: 0.3em;
}
```

以下の JavaScript コードは独自のエラー検証を制御します。

```js
// DOM ノードの選択法はたくさんあります。ここではフォーム自体、メールアドレス
// 入力ボックス、そしてエラーメッセージを配置する span 要素を取得しています。
const form = document.querySelector("form");
const email = document.getElementById("mail");
const emailError = document.querySelector("#mail + span.error");

email.addEventListener("input", (event) => {
  // ユーザーが何かを入力するたびに、メールアドレスのフィールドが妥当かを
  // 確認します。

  if (email.validity.valid) {
    // エラーメッセージを表示している場合に、フィールドが妥当になれば
    // エラーメッセージを取り除きます。
    emailError.textContent = ""; // メッセージの内容物をリセットします
    emailError.className = "error"; // メッセージの表示状態をリセットします
  } else {
    // それでもエラーが発生する場合は、正しいエラーを表示します。
    showError();
  }
});

form.addEventListener("submit", (event) => {
  // ユーザーがデータを送信しようとするたびに、メールアドレスの
  // フィールドが妥当かをチェックします。
  if (!email.validity.valid) {
    // フィールドが妥当ではない場合、独自のエラーメッセージを表示します。
    showError();
    // また、イベントをキャンセルしてフォームの送信を止めます。
    event.preventDefault();
  }
});

function showError() {
  if (email.validity.valueMissing) {
    // If the field is empty,
    // display the following error message.
    emailError.textContent = "You need to enter an email address.";
  } else if (email.validity.typeMismatch) {
    // If the field doesn't contain an email address,
    // display the following error message.
    emailError.textContent = "Entered value needs to be an email address.";
  } else if (email.validity.tooShort) {
    // If the data is too short,
    // display the following error message.
    emailError.textContent = `Email should be at least ${email.minLength} characters; you entered ${email.value.length}.`;
  }

  // Set the styling appropriately
  emailError.className = "error active";
}
```

コメントがよく説明していますが、簡単にいうと次の通りです。

* 入力値を変えるたびに、それが妥当なデータを含んでいるかをチェックします。
 その場合は表示されたエラーメッセージを削除します。
 データが不正の場合は、適当なエラーを表示する `showError()` を実行します。
* フォームの送信を試すごとに、またデータが妥当かチェックします。
 その場合はフォームの送信を許可します。そうでない場合、適当なエラーを表示する `showError()` を実行し、`preventDefault()`でフォーム送信を停止します。
* `showError()` 関数は、入力の `validity` オブジェクトのさまざまなプロパティを使ってエラーがどれかを決めて、適当なエラーメッセージを表示します。

こちらが実際の結果です。

**メモ:** GitHub の detailed-custom-validation.html に例があります（ソースコード見てください）。

制約検証 API はフォーム検証を制御するための強力なツールであり、HTML および CSS のみで検証を行うよりもはるかにユーザーインターフェイスをコントロールできます。

### 組み込み API を使用しないフォーム検証

古いブラウザーやカスタムコントロールにおいて、制約検証 API を使用できない （または使用したくない）ことがあるでしょう。このような場合でも、フォームを検証するために JavaScript が使用できます。フォームを検証には、実際のデータの検証よりもユーザーインターフェイスの疑問が多くなります。

フォームを検証するために、あなたはいくつかの疑問を考えなければなりません。

どのような検証を実施するべきか

どのようにデータを検証するかを決めなければなりません。文字列演算、型変換、正規表現など。これはあなた次第です。

フォームが妥当でない場合に何をするべきか

 これは明らかにユーザーインターフェイスの問題です。フォームがどのように動作するかを決めなければなりません。どのような場合でもフォームのデータを送信しますか？
 エラー状態の入力欄を強調しますか？
 エラーメッセージを表示しますか？

ユーザーが不正なデータを修正することをどのように支援できるか

 ユーザーの不満を軽減するためには、ユーザーに入力内容の修正を案内するために、できるだけ多くの役立つ情報を提供することがとても重要です。
 明確なエラーメッセージはもちろん、ユーザーが何を求められているか理解できるように前向きの提案をするべきです。
 フォーム検証のユーザーインターフェイスの要件について深く知りたいのであれば、ぜひ読むべきである有用な記事があります（英語）。

* Help users enter the right data in forms
* Validating input
* How to Report Errors in Forms: 10 Design Guidelines

#### 制約検証 API を使用しない例

これまでのことを説明するため、古いブラウザーでも動作するように前出のサンプルを作り直してみましょう。

ご覧の通り、 HTML はほとんど同じであり、HTML の検証機能を取り除いただけです。

```html
<form>
  <p>
    <label for="mail">
      <span>メールアドレスを入力してください。</span>
      <input type="text" id="mail" name="mail" />
      <span class="error" aria-live="polite"></span>
    </label>
  </p>
  <button>Submit</button>
</form>
```

同様に、 CSS も大きく変更する必要はありません。 `:invalid` 擬似クラスから実クラスへの変更と、属性セレクターの使用を避けただけです。

```css
body {
  font: 1em sans-serif;
  width: 200px;
  padding: 0;
  margin: 0 auto;
}

form {
  max-width: 200px;
}

p \* {
  display: block;
}

input.mail {
  appearance: none;
  width: 100%;
  border: 1px solid #333;
  margin: 0;

  font-family: inherit;
  font-size: 90%;

  box-sizing: border-box;
}

/\* これは不正なフィールド向けのスタイルです \*/
input.invalid {
  border-color: #900;
  background-color: #fdd;
}

input:focus.invalid {
  outline: none;
}

/\* これはエラーメッセージ向けのスタイルです \*/
.error {
  width: 100%;
  padding: 0;

  font-size: 80%;
  color: white;
  background-color: #900;
  border-radius: 0 0 5px 5px;
  box-sizing: border-box;
}

.error.active {
  padding: 0.3em;
}
```

JavaScript コードでは大きな変更があり、多くの面倒な作業が必要です。

```js
const form = document.querySelector("form");
const email = document.getElementById("mail");
const error = email.nextElementSibling;

// HTML5 仕様書より
const emailRegExp =
  /^[a-zA-Z0-9.!#$%&'\*+/=?^\_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)\*$/;

// ここから検証制約の再構築ができます。
// CSS の擬似クラスに頼ることはできないため、メールアドレスフィールドで
// valid/invalid クラスを明示的に設定しなければなりません。
window.addEventListener("load", () => {
  // ここで、フィールドが空かを確認しています (フィールドは必須入力ではありません)
  // 空でなければ、内容部が適切な電子メールアドレスかを確認します。
  const isValid = email.value.length === 0 || emailRegExp.test(email.value);
  email.className = isValid ? "valid" : "invalid";
});

// ユーザーがフィールドに入力したときに、何をするかを定義します。
email.addEventListener("input", () => {
  const isValid = email.value.length === 0 || emailRegExp.test(email.value);
  if (isValid) {
    email.className = "valid";
    error.textContent = "";
    error.className = "error";
  } else {
    email.className = "invalid";
  }
});

// ユーザーがデータを送信しようとしたときに何をするかを定義します。
form.addEventListener("submit", (event) => {
  event.preventDefault();

  const isValid = email.value.length === 0 || emailRegExp.test(email.value);
  if (!isValid) {
    email.className = "invalid";
    error.textContent = "I expect an email, darling!";
    error.className = "error active";
  } else {
    email.className = "valid";
    error.textContent = "";
    error.className = "error";
  }
});
```

結果は以下のようになります。

ご覧の通り、自分でで検証システムを構築するのは大変なことではありません。難しいのはクロスプラットフォームで、かつ作成するであろうあらゆるフォームで使用できる汎用的なものにすることです。フォーム検証を行うために利用できる、Validate.js のような多くのライブラリーがあります。

スキルテスト
------

この記事の最後に到着しましたが、最も大事な情報を覚えていますか？ 次に進む前に、この情報を保持しているか検証するテストがあります — スキルテスト: フォーム検証 (en-US) を見てください。

まとめ
---

クライアント側のフォーム検証は、カスタムスタイル設定やエラーメッセージには複雑な JavaScript を必要としませんが、ユーザーについては注意深く考えることが必要です。ユーザーが正しいデータを入力できるよう支援することを、常に忘れないでください。最後に、以下のことを必ず行ってください。

* 明確なエラーメッセージを表示してください。
* 入力形式については寛容になってください。
* どこでエラーが発生しているかを正確に示してください（特に大きなフォームで）。

フォームが正しく埋められたことをチェックしたら、送信することができます。次のデータ送信でカバーします。

* 前のページ
* Overview: Forms
* 次のページ
### 上級トピック

* カスタムフォームコントロールの作成方法
* JavaScript によるフォームの送信
* フォームコントロール向けの CSS プロパティの互換性一覧表


フォームデータの送信 - ウェブ開発を学ぶ

フォームデータの送信
==========

* 前のページ
* Overview: Forms

フォームがクライアント側での検証が終わったら、次はフォームの送信です。前の記事では検証を扱ったので、送信する準備はできています。この記事では、ユーザーがフォームを送信したときに何が起こるか、つまりデータがどこへ行くのか、そこに来たときにどう扱うのかを見ます。また、フォームデータの送信に関連するセキュリティの考慮事項のいくつかも見てみます。

|  |  |
| --- | --- |
| 前提知識: |
 基本的なコンピューターリテラシー、
 HTML の理解、基本的な
 HTTP および
 サーバーサイドプログラミングの知識。
  |
| 目標: | フォームデータが送信されたら何が起こるかを、データがサーバー上でどのように処理されるかの基本的な考えも含めて理解すること。 |

まずは、フォームが送信されたときにデータに何が起こるかを考えてみましょう。

クライアント/サーバー構成
-------------

ウェブはごく基本的なクライアント/サーバー構成に基づいており、簡単に言うと次のようになります。クライアント (通常はウェブブラウザー) は、サーバー (ほとんどの場合 Apache、Nginx、IIS、Tomcat などのウェブサーバー) に HTTP プロトコルを使用してリクエストを送ります。サーバーは同じプロトコルを使用して、リクエストに応答します。

![基本的なクライアント/サーバー構成](/ja/docs/Learn/Forms/Sending_and_retrieving_form_data/client-server.png)

クライアント側において、HTML フォームはサーバーへデータを送信する HTTP リクエストを組み立てるのための、便利でユーザーに使いやすい手段でしかありません。フォームによって、ユーザーが HTTP リクエストで渡す情報を提供することができるようになります。

**メモ:** どのようにクライアント/サーバー構成が動作するかについてもっと知りたい場合は、サーバーサイドウェブサイトプログラミング入門モジュールをお読みください。

クライアント側: データ送信方法の定義
-------------------

`<form>` 要素で、データを送信する方法を定義します。その属性すべてが、ユーザーが送信ボタンを押すと送信されるリクエストを調整できるように設計されています。もっとも重要な属性は `action` と `method` の 2 つです。

### action 属性

`action` 属性は、どこにデータを送信するかを定義します。値は妥当な相対/絶対 URL でなければなりません。この属性が与えられなかった場合は、フォームが含まれているページの URL にデータが送信されます。

この例では、データを絶対 URL の `http://example.com` に送信します。

```html
<form action="https://example.com"></form>
```

こちらは、相対 URL を使用しています。データは同一オリジン上の別の URL に送信されます。

```html
<form action="/somewhere\_else"></form>
```

以下のように属性を指定しない場合は、`<form>` 要素はフォームが表示されているページ自身に対してデータを送信します。

```html
<form></form>
```

**メモ:** HTTPS (secure HTTP) プロトコルを使用して URL を指定することができます。このようにすると、フォーム自体が HTTP でアクセスされる安全ではないページで提供される場合でも、データはリクエストの残りの部分とともに暗号化されます。一方、フォームが安全なページ提供されていても、`action` 属性で安全ではない HTTP の URL を指定すると、どのブラウザーでもデータを送信する際にユーザーに対してセキュリティの警告を表示します。これは、データが暗号化されないためです。

非ファイル型のフォームコントロールの名前/値は&記号で結合された `name=value` ペアでサーバーに送られます。`action` の値は、サーバー側の検証を含め入力データを扱うサーバーのファイルです。サーバーは応答して、一般的にはデータを処理して `action` 属性で定義された URL を読み込み、新しいページの読み込み (または `action` が同じページを指している場合は既存ページのリフレッシュ)を引き起こします。

データがどう送られるかは `method` 属性に依存します。

### method 属性

`method` 属性は、どのようにデータを送信するかを定義します。HTTP プロトコルはリクエストを実行するための方法をいくつか提供しています。HTML フォームのデータは複数の方法で送信することができます。もっとも一般的なものは `GET` メソッドと `POST` メソッドです。

これら 2 つのメソッドの違いを理解するために、一歩戻って HTTP の動作についてみていきましょう。ウェブ上のリソースにたどり着こうとするたびに、ブラウザーは URL へリクエストを送信します。HTTP リクエストは 2 つの部分で構成されます。ブラウザーの機能に関する包括的なメタデータのセットを持つヘッダーと、指定されたリクエストをサーバーが処理するために必要な情報を持つ本文です。

#### GET メソッド

`GET` メソッドは、サーバーに対して指定したリソースを返すよう求めるためにブラウザーが使用するメソッドです。"やあサーバー、このリソースをくれよ。" この場合、ブラウザーは空の本文を送信します。本文が空であるため、フォームをこのメソッドで送信する場合はデータを URL の後に付加します。

以下のフォームについて考えてみましょう。

```html
<form action="http://www.foo.com" method="GET">
  <div>
    <label for="say">What greeting do you want to say?</label>
    <input name="say" id="say" value="Hi" />
  </div>
  <div>
    <label for="to">Who do you want to say it to?</label>
    <input name="to" id="to" value="Mom" />
  </div>
  <div>
    <button>Send my greetings</button>
  </div>
</form>
```

`GET` メソッドが使用されているので、フォームを送信するときにブラウザーのアドレスバーに `www.foo.com/?say=Hi&to=Mom` という URL が見えるでしょう。

![変更された引数付き URL によって GET メソッドでフォームを送信した後の "server not found" のブラウザーエラーページです。](/ja/docs/Learn/Forms/Sending_and_retrieving_form_data/url-parameters.png)

URL に追加されたデータは名前/値の組の連続です。URL のウェブアドレスが終了した後、疑問符 (`?`) に続いて、名前/値の組が、それぞれアンパサンド (`&`) で区切られて入ります。この場合、2 つのデータの断片がサーバーに渡されます。

* `say` の値は `Hi`
* `to` の値は `Mom`

HTTP リクエストは次のようになります。

```http
GET /?say=Hi&to=Mom HTTP/2.0
Host: foo.com
```

**メモ:** この例は GitHub にあります。— get-method.html を参照してください （ライブはこちら）.

#### POST メソッド

`POST` メソッドは少し異なります。これは、HTTP リクエストの本文で提供したデータを考慮したレスポンスの要求を、ブラウザーがサーバーに送信するためのメソッドです。"やあサーバー、このデータを見て適切な結果を返してよ。" このメソッドを使用してフォームを送信する場合は、データが HTTP リクエストの本文の後に追加されます。

例を見てみましょう。— これは前述の `GET` の節で見たものと同じフォームですが、`method` 属性が `post` に設定されています。

```html
<form action="http://www.foo.com" method="POST">
  <div>
    <label for="say">What greeting do you want to say?</label>
    <input name="say" id="say" value="Hi" />
  </div>
  <div>
    <label for="to">Who do you want to say it to?</label>
    <input name="to" id="to" value="Mom" />
  </div>
  <div>
    <button>Send my greetings</button>
  </div>
</form>
```

フォームをが `POST` メソッドで送信されると、URL にはデータが追加されず、HTTP リクエストは次のように、リクエスト本文にデータが含まれた形になります。

```http
POST / HTTP/2.0
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13

say=Hi&to=Mom
```

`Content-Length` ヘッダーは本文の長さを、また `Content-Type` ヘッダーはサーバーに送信するリソースの種類を表します。これらのヘッダーについて少し説明しましょう。

**メモ:** この例は GitHub で見つけることができます。— post-method.html を参照してください (ライブ版も見てください)。

### HTTP リクエストの表示

当然ながら HTTP リクエストはユーザーには表示されません (見たいのであれば、Firefox ネットワークモニターや Chrome デベロッパー ツールなどのツールが必要です)。例のように、フォームのデータは Chrome の Network タブに以下のように表示されます。フォームの送信後に、以下のように操作してください。

1. 開発者ツールを開く
2. "Network" を選択
3. "All" を選択
4. "Name" タブから "foo.com" を選択
5. "Headers" を選択

これで下の画像にあるように、フォームデータを取得することができます。

![ブラウザー開発者ツールのネットワーク監視タブで HTTP リクエストとレスポンスデータを取得](/ja/docs/Learn/Forms/Sending_and_retrieving_form_data/network-monitor.png)

ユーザーに表示されるのは呼び出された URL のみです。前述のように、`GET` リクエストはユーザーが URL バーの中でデータを見ることができますが、`POST` リクエストではそうではありません。これは 2 つの理由でとても重要です。

1. パスワード (あるいは何らかの機密データ) を送信する必要がある場合は、`GET` メソッドを使用してはいけません。データが URL バーに表示されるリスクがあり、とても危険です。
2. 大量のデータを送信する必要があるなら、`POST` が好ましいメソッドです。これは、URL の長さ制限があるブラウザーが存在するためです。加えて、多くのサーバーは受け入れる URL の長さを制限しています。
サーバー側: データの取得
-------------

どちらの HTTP メソッドを選択しても、サーバーが受け取る文字列は、キー/値の組のリストとしてデータを取得するために解析されます。このリストにアクセスする方法は、使用する開発プラットフォームや、使用するであろう特定のフレームワークに依存します。

### 生の PHP の例

PHP は、データにアクセスするためのグローバルオブジェクトを提供します。`POST` メソッドを使用したと仮定すると、データを取得してユーザーに表示する例は以下のとおりです。もちろん、データに対して何をするかはあなた次第です。データを表示したり、データベースに保管したり、メールで送信したり、他の手段で処理したりするでしょう。

```php
<?php
 // $\_POST グローバル変数は、POST メソッドで送信されたデータへ名前でアクセスを可能にする
 // GET メソッドで送信されたデータにアクセスするには、$\_GET が使用できる
 $say = htmlspecialchars($\_POST['say']);
 $to = htmlspecialchars($\_POST['to']);

 echo $say, ' ', $to;
?>
```

この例では送信されたデータを含むページを表示します。これはサンプルの php-example.html ファイル、つまり以前 `method` が `POST` で `action` が `php-example.php` の時に見たサンプルフォームを含むファイルアクションの中で見ることができます。送信されると、フォームデータは上記のブロックの PHP コードを含む php-example.php へ送信されます。コードが実行されると、ブラウザーの出力は `Hi Mom` になります。

![それ以外の空白のウェブページに "hi mom" と表示された場合、 POST メソッドでフォームデータを PHP ファイルに送信した後のレスポンスとして受け取ったデータ](/ja/docs/Learn/Forms/Sending_and_retrieving_form_data/php-result.png)

**メモ:** この例はブラウザーにローカルに読み込んだ時には動作しません。— ブラウザーは PHP コードを解釈できないので、フォームがブラウザーに送信されると、PHP ファイルをダウンロードしようとするでしょう。動作させるためには、この例を何らかの PHP サーバー経由で実行する必要があります。ローカルの PHP のテストには、MAMP (Mac および Windows) や AMPPS (Mac, Windows, Linux) がいいでしょう。

なお、MAMP を使って MAMP Pro がない (または MAMP Pro デモトライアルの有効期限が切れた) 場合、動作させるのにトラブルが起こるかもしれません。再び動作させるには MAMP アプリを閉じて、*MAMP* > *Preferences* > *PHP*メニューから "Standard Version:" を "7.2.x" (x はあなたがどのバージョンをインストールしたかによります)にするといいことがわかっています。

### Python の例

この例は、同じこと (与えられたデータをウェブページに表示する) を Python で行います。これはテンプレートの表示やフォームデータの受付などのために Flask フレームワークを使用しています (python-example.py を参照してください)。

```python
from flask import Flask, render_template, request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def form():
    return render_template('form.html')

@app.route('/hello', methods=['GET', 'POST'])
def hello():
    return render_template('greeting.html', say=request.form['say'], to=request.form['to'])

if __name__ == "\_\_main\_\_":
    app.run()
```

次のように、上記のコードでは 2 つのテンプレートが参照されます。(自分の環境で実行する場合、これらは `templates` というサブディレクトリーにあり、`python-example.py`ファイルと同じディレクトリーにある必要があります)。

* form.html: 以前に POST メソッドの節で見たフォームと同じですが、`action` が `{{ url_for('hello') }}` に設定されています (これは Jinja テンプレートで、基本的に HTML ですが、波括弧の中にウェブサーバーで実行されている Python のコードの呼び出しを含めることができます。`url_for('hello')` は基本的に、「フォームが送信されたら `/hello` にリダイレクトしてください」と言っています。)
* greeting.html: このテンプレートは、表示時に渡された 2 つの小さいデータを表示する行だけを含みます。`/hello` の URL が呼び出されるときに実行される、前述の `hello()` 関数によって行われます。

**メモ:** 繰り返しますが、このコードはブラウザーに直接読み込もうとしても動作しません。Python は PHP とは若干異なる動作をします。— ローカルでこのコードを実行するには、Python/PIP をインストールする必要があり、それから `pip3 install flask` を使用して Flask をインストールしてください。この時点で `python3 python-example.py` を実行し、ブラウザーで `localhost:5000` に移動することで実行することができるでしょう。

### その他の言語やフレームワーク

フォームの操作に使用できるサーバー側の技術は、Perl、Java、.Net、Ruby などたくさんあります。もっとも好きなものを選びましょう。しかしそれらの技術を直接使用することは、扱いにくいため一般的ではないことが特筆に値します。以下のような、フォームをより簡単に扱えるようにする多くの高品質フレームワークのひとつを使用する方がより一般的です。

* Django (Python 向け、Flask より若干重いものですが、ツールとオプションがより豊富です。)
* Express (Node.js 向け)
* Laravel (PHP 向け)
* Ruby On Rails (Ruby 向け)
* Spring Boot (Java 向け)

言うまでもなく、これらのフレームワークを使用したとしても、フォームでの作業が必ずしも*簡単に*なるとは限りません。しかし、すべての機能を自分で 1 から書こうとするよりずっと簡単で、また多くの時間を節約できるでしょう。

**メモ:** サーバー側言語やフレームワークまで説明することはこの記事の範囲を超えます。上記のリンクが参考になりますので、学習してみてください。

特別な場合: ファイル送信
-------------

ファイルは HTML フォームで特別なケースです。他のデータがすべてテキストデータである中、ファイルはバイナリーデータ (あるいはそのように考えられるデータ) です。HTTP はテキストのプロトコルであるため、バイナリーデータを扱うための特別な要件があります。

### enctype 属性

この属性で `Content-Type` HTTP ヘッダーの値を指定できます。このヘッダーはサーバーに対して送信するデータの種類を伝えることから、とても重要です。既定値は `application/x-www-form-urlencoded` です。人間の言葉では、「これは URL 形式でエンコードされたフォームデータです。」という意味です。

しかしファイルを送信したい場合は、さらに 2 つのステップを踏む必要があります。

* ファイルの内容は URL 引数に収めることができないので、`method` 属性を `POST` に設定してください。
* データは複数の部分に分かれ、それぞれのファイルや文字列データがフォーム本体に含められているので、`enctype` の値を `multipart/form-data` に設定ください。
* ユーザーがアップロードするファイルを選択できるように、1 つ以上の `<input type="file">` コントロールを含めてください。

例:

```html
<form method="post" action="https://www.foo.com" enctype="multipart/form-data">
  <div>
    <label for="file">Choose a file</label>
    <input type="file" id="file" name="myFile" />
  </div>
  <div>
    <button>Send the file</button>
  </div>
</form>
```

**メモ:** 多くのサーバーは悪用を防ぐために、ファイルや HTTP リクエストの長さを制限しています。

一般的なセキュリティへの配慮
--------------

サーバーにデータを送信するたびに、セキュリティについて考える必要があります。HTML フォームはサーバーに対するもっともよくある攻撃の入口 (攻撃が行われる場所) になります。問題が HTML フォーム自身から発生することはありません — サーバーがどのようにデータを扱うかによります。

ウェブサイトセキュリティ の記事がサーバーサイドの学習トピックにあり、一般的な攻撃とその防御を詳細に扱っています。そちらへ行って記事を確認し、何が起こり得るかを理解してください。

### 疑い深くあれ: ユーザーを信用してはいけません

さて、これらの脅威に対してどう対抗するのでしょうか? これは本ガイドの内容を超える話題です。それでも、覚えておくとよいルールがいくつかあります。もっとも重要なルールは、自分自身も含めユーザーを決して信用してはならないことです。信頼されているユーザーでさえハイジャックされるかもしれません。

サーバーに来るすべてのデータを確認およびサニタイズしなければなりません。いつでもです。例外はありません。

* **潜在的に危険な文字をエスケープします。** 注意すべき具体的な文字は、データが使用される状況や使用するサーバー基盤に大きく依存しますが、どのサーバー側言語もそのための機能を持っています。注意しておくべきことは、 (JavaScript や SQL コマンドといった)実行可能なコードのようなキャラクターシーケンスです。
* **入力データの量を、必要なサイズまでしか受け入れないように制限します。**
* **アップロードされたファイルをサンドボックス化します。** ファイルを別のサーバーに保管して、別のサブドメインまたはよりよい方法としてまったく別のドメインを通してのみアクセスを許可します。

これら 3 つのルールに従うと、多くのあるいはほとんどの問題を避けられるでしょう。ただし、適格の第三者によるセキュリティレビューを受けることもよい考えです。発生し得る問題のすべてを見いだしたとは考えないようにしてください。

まとめ
---

ご覧いただいたように、フォームデータの送信は簡単ですが、アプリケーションを安全にするのは容易ではありません。フロントエンドの開発者はデータのセキュリティモデルを定義すべき者ではないことを忘れないようにしてください。今後見ていくようにクライアント側でのデータ検証も可能ですが、クライアント側で実際に何が起きているかを知ることはできませんので、サーバー側でその検証内容を信用することはできません。

このチュートリアルを順番に終えた場合、フォームのマークアップとスタイル設定の方法、クライアント側での検証の方法、フォーム送信の理解ができているでしょう。

関連情報
----

ウェブアプリケーションのセキュア化についてさらに学びたいのでしたら、次のリソースをよく読んでください。

* サーバーサイドウェブサイトプログラミング入門
* The Open Web Application Security Project (OWASP)
* Web Security by Mozilla
* 前のページ
* Overview: Forms
モジュール内の記事
---------

* 初めてのフォーム
* フォームの構築方法
* 基本的なネイティブフォームコントロール
* HTML5 の入力型
* その他のフォームコントロール
* フォームへのスタイル設定
* フォームへの高度なスタイル設定
* UI 擬似クラス
* クライアントサイドのフォーム検証
* フォームデータの送信
### 上級トピック

* カスタムフォームコントロールの作成方法
* JavaScript によるフォームの送信
* フォームコントロール向けの CSS プロパティの互換性一覧表


ウェブフォームへのスタイル設定 - ウェブ開発を学ぶ

ウェブフォームへのスタイル設定
===============

* 前のページ
* Overview: Forms
* 次のページ

これまでのいくつかの記事では、ウェブフォームを作成し、構成するために必要なすべての HTML について見てきました。この記事では、CSS を使用してフォームコントロールのスタイルを設定する方法について移動します。これは過去には難しいことでした。フォームコントロールは CSS でカスタマイズしやすいかどうかで大きく異なりますが、古いブラウザーが引退し、現代のブラウザーがより多くの機能を使用するようになるにつれて、簡単になってきています。

|  |  |
| --- | --- |
| 前提条件: |
 基本的なコンピューターリテラシーと、
 HTML および
 CSS に対する基本的な理解。
  |
| 目的: | フォームのスタイル設定の問題を理解し、役立つスタイル付けのテクニックを学ぶこと。 |

なぜフォームウィジェットへのスタイル設定は難しいのか
--------------------------

1995 年頃に HTML 2 仕様書へフォームコントロールが追加されました。 CSS は 1996 年までリリースされず、その後も数年は部hラウザーの対応が充分ではありませんでした。ブラウザーは、フォームコントロールの管理とレンダリングを、オペレーティングシステムに頼っていました。

CSS が HTML のスタイル設定できるようになってからも、ユーザーは各プラットフォームの視覚的な外見に慣れていましたので、ブラウザーベンダーはフォームコントロールをスタイル付け可能にすることに乗り気ではありませんでした。しかしこれは変わりました。ウェブサイトのオーナーはこれまでよりも、サイト全体に適するスタイルを欲しており、ウェブプラットフォームはこれを実現可能にしました。

一部のフォームウィジェットは、コントロールをスタイル設定できるように作成し直すのは難しいのですが、ユーザビリティを破綻させないよう気をつける必要はあるものの、 CSS を使って多くのフォーム機能をスタイル設定できます。

### CSS を使用する場合、すべてのウィジェットが同じように作成されるわけではない

いまだに、フォームで CSS を使用する際に困ることが存在します。この問題は、3 つのカテゴリーに分けられます。

#### 良好

いくつかの要素はプラットフォーム間の問題があるとしても、ほとんど問題なくスタイルを設定できます。これらは以下の構造的な要素が含まれます。

1. `<form>`
2. `<fieldset>` と `<legend>`
3. 単一行のテキストの `<input>` （例えば text, url, email 型） `<input type="search">` 以外
4. 複数行の `<textarea>`
5. ボタン（`<input>` と `<button>`の両方）
6. `<label>`
7. `<output>`

#### 不良

一部の要素はほとんどスタイル設定ができず、時に CSS の高度な知識やトリックが必要になるかもしれません。

1. チェックボックスとラジオボタン
2. `<input type="search">`

これら特殊なケースをどのように扱うかについては、フォームへの高度なスタイル設定の記事で見ていきます。

#### 劣悪

一部の要素は、CSS でスタイルを設定できません。たとえば次のものです。

* `<input type="color">`
* `<input type="datetime-local">`のような日時関連コントロール
* `<input type="range">`
* `<input type="file">`
* ドロップダウンウィジェットの作成に含まれる要素、 `<select>`, `<option>`, `<optgroup>`, `<datalist>` を含む。
* `<progress>` と `<meter>`

これらの要素をスタイル設定するのに関して何ができるかについては、フォームへの高度なスタイル設定の記事で見ていきます。

これらすべてのウィジェットの主な問題は、ウィジェットの構造がとても複雑であるという事実と、（コントロールの width や margin の変更といった）基本的なスタイル設定を超えると、現在の CSS では（例えばカレンダー日付ピッカーや、選択肢のリストを表示する <select> のボタンのような）ウィジェットの細かい部分すべてにスタイルを設定できるほどの表現力がないことによります。

これらのウィジェットを完全にカスタマイズしたい場合は、 HTML, CSS, JavaScript を使って独自のものを作成する必要があります。それはこのコアフォームの記事の範囲を超えますが、高度な記事のカスタムウィジェットの作成方法の記事で説明します。

**メモ:** フォームコントロールの内部コンポーネントにスタイル設定するプロプライエタリな CSS 擬似要素、例えば `::-moz-range-track`がありますが、これはブラウザー同士で整合していないので、これに頼るべきではありません。これについては後程でも触れます。

良好
--

CSS でスタイルを設定するのが簡単なフォームコントロールは、他の HTML 要素とほとんど同じように動作するため、困難はあまりないはずです。最初のフォームで、いくつかの簡単なフォームのスタイルを既に見ましたし、 CSS の構成要素モジュールにもいくつかの役立つフォームのスタイル設定の基本が含まれています。

CSS でのスタイル設定が容易な要素は、振る舞いが他の HTML 要素とほとんど同じであるため、問題に直面することはないでしょう。ただし、ブラウザー間でユーザーエージェントのスタイルシートが若干矛盾するかもしれませんので、より簡単にスタイルを設定できるようにするためのトリックがあります。

この記事の最後で基本的なフォームコントロールのスタイル設定と配置について理解できる実例を詳しく見ていきます。しかしその前に、知っておくと良いフォームスタイル設定の特定の面をいくつか述べておきます。

### フォントとテキスト

CSS のフォントやテキストの機能は、任意のウィジェットで容易に使用できます（また、フォームウィジェットで `@font-face` も使用できます）。ただし、ブラウザーの動作にしばしば矛盾があります。デフォルトで、一部のブラウザーは親から `font-family` や `font-size` を継承しません。代わりに多くのブラウザーでは、システムのデフォルトの体裁を使用します。フォームの体裁を他のコンテンツと一致させるには、以下のルールをスタイルシートに追加するとよいでしょう。

```css
button,
input,
select,
textarea {
  font-family: inherit;
  font-size: 100%;
}
```

`inherit` のプロパティ値で、プロパティ値は計算された親要素のプロパティ値に一致するようになります。つまり親の値を継承します。

以下のスクリーンショットで違いを示します。左側は Mac OS X の Chrome における `<input type="text">`, `<input type="date">`, `<select>`, `<textarea>`, `<input type="submit">`, `<button>` 要素の既定のレンダリングで、プラットフォームのキテイノフォントスタイルを使用しています。右側は同じ要素ですが、フォントを調和させるスタイルルールを適用したものです。

![既定値および継承されたフォントファミリーを持つフォームコントロール。既定値では、ある型はセリフで、ある型はサンセリフである。継承すると、すべてのフォントが親のフォントファミリ（この場合は段落）に変更されるはずです。奇妙なことに、 submit 型の入力は親の段落から継承されません。](/ja/docs/Learn/Forms/Styling_web_forms/forms_fontfamily.png)

既定はいろいろと変わります。継承により、フォントは親のフォントファミリーに変更されます — ここでは親コンテナーの既定の serif フォントです。ほぼすべてそうですが、例外として Chrome では`<input type="submit">` は親段落を継承しません。むしろ、`font-family: system-ui`を使います。これは同等な入力タイプの中で `<button>` 要素を使う理由です。

フォームはシステムの既定のスタイルを使用するか、コンテンツに合うよう設計されたカスタムスタイルを使用するかについては多くの議論があります。これを決めるのは、設計者としてサイトやウェブアプリケーションを作成するあなた次第です。

### ボックスモデル

すべてのテキストフィールドは、CSS のボックスモデルに関する全プロパティ (`width`、`height`、`padding`、`margin`、および `border`) を完全にサポートしています。ただし前述のとおり、ブラウザーがウィジェットを表示する際はシステムのデフォルトスタイルに依存します。コンテンツに対してそれらをどのように混ぜ合わせるかを決めるのは、あなた次第です。ウィジェットでネイティブのルックアンドフィールを維持したいのでしたら、ウィジェットのサイズを調和させたい場合に若干の問題に直面するでしょう。

\*\*これは各ウィジェットが境界、パディング、マージンについて独自のルールを持っているためです。\*\*このためさまざまなウィジェットを同じサイズにしたい場合に、 `box-sizing` プロパティを使用しなければなりません。

```css
input,
textarea,
select,
button {
  width: 150px;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
```

下のスクリーンショットで、左の列は <input type="radio">, <input type="checkbox">, <input type="range">, <input type="text">, <input type="date"> input, `<select>`, `<textarea>`,<input type="submit">, `<button>` の既定の描画、右の列は同じ要素に上のルールを使用して作成したものです。各種のウィジェットのプラットフォームのデフォルトルールと比較して、すべての要素が同じ領域を占めるようにすることが可能な点に注目してください。

![box model properties effect most input types.](/ja/docs/Learn/Forms/Styling_web_forms/boxmodel_formcontrols1.png)

スクリーンショットではわからないかもしれませんが、ラジオやチェックボックスの操作はそのままで、 `width` プロパティで提供される 150px の水平空間に中央配置されています。他のブラウザーでは、ウィジェットが中央に配置されないことがありますが、割り当てられた空間は守られます。

### legend の配置

`<legend>` 要素はスタイル設定では問題ありませんが、その配置を操作するのは少し厄介かもしれません。既定では、それは常に親である `<fieldset>` の上境界の上、左上隅の近くに配置されます。他の場所、例えばfieldsetの内部や左下隅の近くに配置するには、位置指定に頼る必要があります。

下記の例を見てください。

この方法で legend を配置するには、次の CSS を使います（単純化するため、他の宣言は削除しています）。

```css
fieldset {
  position: relative;
}

legend {
  position: absolute;
  bottom: 0;
  right: 0;
}
```

`<fieldset>` も位置指定する必要があり、 `<legend>` がそこから相対的に位置指定されます（そうでなければ `<legend>` は `<body>`に合わせて位置決めされます）。

`<legend>` 要素はアクセシビリティにとってとても重要です。フィールドセット内の各フォーム要素のラベルの一部として支援技術によって読み上げられます。しかし、上記のようなテクニックを使用しても問題ありません。 legend の内容はこれまでと同じように読み上げられます。見た目の位置が変更されただけです。

**メモ:** `transform` プロパティを使用して `<legend>` の位置指定に役立てることもできます。しかし、例えば `transform: translateY();` を使って配置すると、移動はするものの `<fieldset>` の枠に醜い隙間ができて、簡単には除去できません。

具体的なスタイル設定の例
------------

HTML フォームにスタイルを設定する方法の具体例を見ていきましょう。以下のような「はがき」風の連絡フォームを作成します。完成バージョンはこちら。

この例をやってみるのであれば、 postcard-start.html ファイルをコピーして、次のやり方に従ってください。

### HTML

HTML は、ガイドの最初の記事で使用したものより少しだけ複雑です。いくつか ID やタイトルを追加しています。

```html
<form>
  <h1>to: Mozilla</h1>

  <div id="from">
    <label for="name">from:</label>
    <input type="text" id="name" name="user\_name" />
  </div>

  <div id="reply">
    <label for="mail">reply:</label>
    <input type="email" id="mail" name="user\_email" />
  </div>

  <div id="message">
    <label for="msg">Your message:</label>
    <textarea id="msg" name="user\_message"></textarea>
  </div>

  <div class="button">
    <button type="submit">Send your message</button>
  </div>
</form>
```

上記のコードを HTML の body に追加します。

### 資産を揃える

ここからがおもしろいところです! コードを書き始める前に、ここでは 3 つの追加要素が必要です。

1. はがきの背景 — この画像をダウンロードして作業している HTML ファイルと同じディレクトリーに保存します。
2. タイプライター風フォント: fontsquirrel.com の "Secret Typewriter" — TTF ファイルを上記と同じディレクトリーにダウンロードします。
3. 手書き風フォント: fontsquirrel.com の "Journal" — TTF ファイルを上記と同じディレクトリーにダウンロードします。

始める前にフォントの処理が必要です。

1. fontsquirrel の Webfont Generator に移動します。
2. フォームを使って、両方のフォントファイルをアップロードして webfont キットを生成します。キットをコンピューターにダウンロードします。
3. zip ファイルを展開します。
4. 展開した中身には 2 つの `.woff` ファイルと 2 つの `.woff2` ファイルがあります。このファイルを、前と同じ fonts というディレクトリーにコピーします。各フォントの 2 つのファイルはブラウザー互換性を最大化するのに使います; より詳しい情報は Web fonts の記事を見てください。
### CSS

ここから例の CSS を見ていきましょう。`<style>` 要素の中にすべてのコードブロックを一つ一つ追加します。

#### 全体レイアウト

まず、 `@font-face` ルールと、すべての `<body>` と `<form>` 要素に設定するスタイルを定義して準備します。 fontsquirrel 出力が上記で述べたものと異なる場合、 `stylesheet.css` ファイル内にダウンロード済みの webfont キットの中から正しい `@font-face` ブロックを見つけることができます（下記の `@font-face` ブロックをそれで置換し、パスをフォントファイルのものに更新する必要があります）。

```css
@font-face {
  font-family: "handwriting";
  src:
    url("fonts/journal-webfont.woff2") format("woff2"),
    url("fonts/journal-webfont.woff") format("woff");
  font-weight: normal;
  font-style: normal;
}

@font-face {
  font-family: "typewriter";
  src:
    url("fonts/veteran\_typewriter-webfont.woff2") format("woff2"),
    url("fonts/veteran\_typewriter-webfont.woff") format("woff");
  font-weight: normal;
  font-style: normal;
}

body {
  font: 1.3rem sans-serif;
  padding: 0.5em;
  margin: 0;
  background: #222;
}

form {
  position: relative;
  width: 740px;
  height: 498px;
  margin: 0 auto;
  padding: 1em;
  box-sizing: border-box;
  background: #fff url(background.jpg);

  /\* we create our grid \*/
  display: grid;
  grid-gap: 20px;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: 10em 1em 1em 1em;
}
```

注意として、フォームのレイアウトに CSS グリッドとフレックスボックス を使っています。これで、タイトルやフォーム要素といった各要素を配置できます。

```css
h1 {
  font:
    1em "typewriter",
    monospace;
  align-self: end;
}

#message {
  grid-row: 1 / 5;
}

#from,
#reply {
  display: flex;
}
```

#### ラベルとコントロール

そして、フォーム要素自体に対するスタイル設定を始めます。まずは、 `<label>` に適切なフォントを割り当てましょう。

```css
label {
  font:
    0.8em "typewriter",
    sans-serif;
}
```

テキストフィールドには、共通のルールがいくつか必要です。 `border` や `background` の削除と `padding` や `margin` の再定義を行います。

```css
input,
textarea {
  font:
    1.4em/1.5em "handwriting",
    cursive,
    sans-serif;
  border: none;
  padding: 0 10px;
  margin: 0;
  width: 80%;
  background: none;
}
```

これらのフィールドのいずれかがフォーカスされると、ライトグレーの透明な背景でハイライトされます（ユーザビリティとキーボードアクセシビリティのために、フォーカススタイルを保有することは常に重要です）。

```css
input:focus,
textarea:focus {
  background: rgba(0, 0, 0, 0.1);
  border-radius: 5px;
}
```

これでテキストフィールドのスタイル設定が完了しましたが、次は単一行および複数行のテキストフィールドの表示が同じになるよう調整しなければなりません。一般に、これらの既定の表示が同じでないためです。

#### テキストエリアの微調整

`<textarea>` 要素は既定でブロック要素としてレンダリングされるようにします。ここで重要なことは、 `resize` プロパティと `overflow` プロパティの 2 つです。ここでは固定サイズでデザインしているため、ユーザーが複数行のテキストフィールドをリサイズできないように `resize` プロパティを使用します。 `overflow` プロパティは、ブラウザー間でのフィールドの一貫性を向上させるために使用します。これの既定値が `auto` であるブラウザーと `scroll` であるブラウザーが存在します。この例では、すべてのブラウザーが `auto` になるようにするのがよいでしょう。

```css
textarea {
  display: block;

  padding: 10px;
  margin: 10px 0 0 -10px;
  width: 100%;
  height: 90%;

  border-right: 1px solid;

  /\* resize : none; \*/
  overflow: auto;
}
```

#### 送信ボタンにスタイル設定する

`<button>` 要素は、 CSS によってより便利になります。擬似要素を含めて、行いたいことが何でもできます。

```css
button {
  padding: 5px;
  font: bold 0.6em sans-serif;
  border: 2px solid #333;
  border-radius: 5px;
  background: none;
  cursor: pointer;
  transform: rotate(-1.5deg);
}

button:after {
  content: " >>>";
}

button:hover,
button:focus {
  outline: none;
  background: #000;
  color: #fff;
}
```

### 最終結果

これでよし! フォームは次のようになるでしょう。

![上記のようにスタイル設定と微調整を行った後の、フォームの最終的な外観とレイアウト](/ja/docs/Learn/Forms/Styling_web_forms/updated-form-screenshot.jpg)

**メモ:** 例が期待どおり動かず、私たちのバージョンを確認したい場合は、 GitHub を参照してください。ライブ版を見てください (ソースコードも見てください)。

スキルを試しましょう！
-----------

この記事の終わりまで到達しました。しかし、肝要な点を思い起こせるでしょうか？次に進む前に、テストによって知識の定着を試すことができます——スキルテスト：スタイル設定の基本 (en-US)をご覧ください。

まとめ
---

ご覧いただいたとおり、テキストフィールドとボタンだけでフォームを作成する限りでは、CSS を使用したスタイル設定は容易です。次の記事では、「不良」や「劣悪」に分類されているウィジェットの扱い方を見ていきます。

* 前のページ
* Overview: Forms
* 次のページ