--- title: slug: Web/HTML/Element/input/month tags: - Date picker - Element - Form input - Forms - HTML - HTML forms - HTML input - Input - Input Element - Input Type - Number - Reference - month translation_of: Web/HTML/Element/input/month ---
{{HTMLElement("input")}} 要素の month
型は、ユーザーが年と月を入力できるようにする入力フィールドを作成し、年と月を簡単に入力できるようにします。値は "YYYY-MM
" の形式の文字列で、 YYYY
は4桁の年、 MM
は月の番号です。
コントロールのユーザーインターフェイスは、一般にブラウザーによって異なります。現時点では対応が不安定であり、デスクトップ版の Chrome/Opera と Edge — および最新のバージョンのモバイルブラウザー — のみに利用可能な実装があります。 month
入力欄に対応していないブラウザーでは、コントロールは単純な <input type="text">
に格下げされますが、入力されたテキストが期待されている形式であることを保証するための自動検証が行われることもあります。
month
に対応していないブラウザーを使用している場合のために、このスクリーンショットで Chrome と Opera でどのように見えるかを示します。右端にある下向き矢印をクリックすると、年と月を選択できる日付選択が表示されます。
Microsoft Edge では、 month
コントロールはこのように表示されます。
{{anch("Value", "値")}} | 年と月を表す {{domxref("DOMString")}}、または空欄 |
イベント | {{domxref("HTMLElement/change_event", "change")}} および {{domxref("HTMLElement/input_event", "input")}} |
対応している共通属性 | {{htmlattrxref("autocomplete", "input")}}, {{htmlattrxref("list", "input")}}, {{htmlattrxref("readonly", "input")}}, {{htmlattrxref("step", "input")}} |
IDL 属性 | value |
メソッド | {{domxref("HTMLInputElement.select", "select()")}}, {{domxref("HTMLInputElement.stepDown", "stepDown()")}}, {{domxref("HTMLInputElement.stepUp", "stepUp()")}} |
{{domxref("DOMString")}} で、入力欄に入力された年と月の値を YYYY-MM (4桁以上の年に続いてハイフン ("-
")、続いて2桁の月) の形式で表します。この入力型で使用される時刻の値の形式について詳しくは、 HTML で使われる日付や時刻の形式の月の文字列をご覧ください。
入力コントロールの既定値は、次のように {{htmlattrxref("value", "input")}} 属性に年と月を入れることで設定することができます。
When the above value is submitted to the server, for example, it will look like bday-month=1978-06
.
すべての {{HTMLElement("input")}} 型で共通する属性に加え、 month
型の入力欄は次の属性にも対応しています。
{{page("/ja/docs/Web/HTML/Element/input/text", "list", 0, 1, 2)}}
最新の年月で、上記の{{anch("Value", "値")}}で説明した文字列の書式です。要素に入力された {{htmlattrxref("value", "input")}} がこの日付よりも後の場合、要素は制約検証に失敗します。 max
属性の値が "yyyy-MM
" の書式に従う妥当な文字列でない場合、要素は最大値を持ちません。
この値は min
属性で指定されたものより後か、同じ年月を指定する必要があります。
受け付ける最古の年月で、前述と同じ yyyy-MM
の書式です。要素の {{htmlattrxref("value", "input")}} がこれより前の場合、要素は制約検証に失敗します。 min
属性の値が "yyyy-MM-dd
" の書式に従う妥当な文字列でない場合、要素は最小値を持ちません。
この値は max
属性で指定されたものより前か、同じ年月を指定する必要があります。
論理属性で、存在すれば、ユーザーが編集することができないことを表します。しかし、 value
は、 JavaScript コードから直接 {{domxref("HTMLInputElement.value")}} プロパティを設定することで変更することができます。
注: 読み取り専用フィールドは値を持てないため、 required
は readonly
属性も指定されている入力欄には効果がありません。
{{page("/ja/docs/Web/HTML/Element/input/number", "step-include")}}
date
入力欄では、 step
の値は月数で指定され、倍率は1です (数値も月単位であるため)。 step
の既定値は 1 です。
日付に関する入力欄は (month
を含め) 一見すると便利に見えます。日付の選択に簡単なユーザーインターフェイスを提供し、サーバーに送信するデータの書式をユーザーのロケールに関係なく正規化してくれます。しかし、現時点ではブラウザーの対応が限定されているため、 <input type="month">
には問題があります。
<input type="month">
の基本的な使い方と少し複雑な使い方を見てみてから、その後でブラウザーの互換性の問題を緩和するアドバイスを提供しましょう ({{anch("Handling browser support", "ブラウザーの互換性の扱い")}} を参照してください)。
もっとも単純な <input type="month">
の使用方法は、次のように基本的な {{HTMLElement("input")}} と {{htmlelement("label")}} 要素の組み合わせです。
<form> <label for="bday-month">生まれた月を入力してください。</label> <input id="bday-month" type="month" name="bday-month"> </form>
{{EmbedLiveSample('Basic_uses_of_month', 600, 40)}}
{{htmlattrxref("min", "input")}} および {{htmlattrxref("max", "input")}} 属性を使用して、ユーザーが選択できる日付の範囲を制限することができます。次の例では、日付の最小値を 1900-01
に、日付の最大値を 1999-12
に指定しています。
<form> <label for="bday-month">生まれた月を入力してください。</label> <input id="bday-month" type="month" name="bday-month" min="1900-01" max="1999-12"> </form>
{{EmbedLiveSample('Setting_maximum_and_minimum_dates', 600, 40)}}
次のような結果になります。
<input type="month">
は {{htmlattrxref("size", "input")}} のような寸法に関する属性には対応していません。寸法を変更する必要がある場合は、 CSS を使用する必要があります。
既定で、 <input type="month">
は入力された値の検証を行いません。ユーザーインターフェイスの実装は一般的に、日付でないものの入力をさせないからです。これは便利です。しかし、それでも month
入力欄を空のまま、または無効な日付 (例えば4月32日など) を入力してフォームを送信することが可能です。
これを防ぐために、 {{htmlattrxref("min", "input")}} と {{htmlattrxref("max", "input")}} を用いて利用可能な日を制限することができ ({{anch("Setting maximum and minimum dates", "日付の最大値と最小値の設定")}} を参照)、加えて {{htmlattrxref("required", "input")}} 属性を用いて、日付を入力することを必須にすることができます。結果として、対応しているブラウザーは、範囲外の日付や空の日付フィールドを送信しようとするとエラーを表示します。
例を見てみましょう。ここで日付の最小値と最大値を設定し、入力欄を必須にしました。
<form> <div> <label for="month">何月にいらっしゃいますか? (夏期間のみ、 yyyy-mm)</label> <input id="month" type="month" name="month" min="2017-06" max="2017-09" required> <span class="validity"></span> </div> <div> <input type="submit" value="フォームを送信"> </div> </form>
年と月を指定せずに (または設定した範囲を外れた日付を) 送信しようとすると、ブラウザーはエラーを表示します。例を実行してみましょう。
{{EmbedLiveSample('Validation', 600, 120)}}
対応しているブラウザーで入力しなかった場合のスクリーンショットです。
上記の例の CSS です。 CSS の {{cssxref(":valid")}} および {{cssxref(":invalid")}} プロパティを使用して、現在の値が有効かどうかに基づいてスタイルを設定しています。アイコンは入力欄そのものではなく、入力欄の隣の {{htmlelement("span")}} に置くようにしないと、 Chrome ではコントロールの内側にコンテンツを生成するので、正しく整形したり表示したりすることができません。
div { margin-bottom: 10px; position: relative; } input[type="number"] { width: 100px; } input + span { padding-right: 30px; } input:invalid+span:after { position: absolute; content: '✖'; padding-left: 5px; } input:valid+span:after { position: absolute; content: '✓'; padding-left: 5px; }
重要: HTML のフォーム検証は、入力されたデータが正しい形式であることを保証するスクリプトの代用にはなりません。 HTML を調整して検証をくぐり抜けたり、完全に削除したりすることはとても簡単にできます。 HTML を完全にバイパスし、サーバーに直接データを送信することも可能です。サーバー側のコードが受信したデータの検証に失敗した場合、不適切な形式のデータ (または大きすぎるデータ、誤った種類のデータなど) が送信された場合に障害が発生するおそれがあります。
前述のように、現時点で日付入力を書く上で一番の問題は、多くの主要なブラウザーがまだすべてを実装している訳ではないということです。デスクトップでは Chrome/Opera と Edge のみが対応しており、モバイルでは多くの最新のブラウザーが対応しています。例えば、 month
の選択画面は Android 版 Chrome ではこのように表示されます。
対応していないブラウザーでは、文字列入力欄に安全に格下げされますが、これはユーザーインターフェイスの一貫性 (表示されるコントロールが異なること) とデータの扱いの両方で問題を生みます。
2番目の問題はより深刻です。すでに述べたように、 month
入力欄では、実際の値が常に yyyy-mm
の書式で正規化されます。一方、既定の設定では、 text
入力欄ではどの書式で入力されるかの認識がなく、以下のように人間が日付を書く様々な方法で入力される可能性があります。
yyyy/mm
(2018/07)yyyymm
(201807)mm-yyyy
(07-2018)yyyy-mm
(2018-07)Month yyyy
(July 2018)これを回避する方法の一つは、 month
入力欄に {{htmlattrxref("pattern", "input")}} 属性を付けることです。 month
入力欄はこれを使用しないので、 text
入力欄などとして扱うようフォールバックされたときに、このパターンを使用します。例えば、次の例を month
入力欄に未対応のブラウザーで見てみてください。
<form> <div> <label for="month">何月にいらっしゃいますか? (夏期間のみ、 yyyy-mm)</label> <input id="month" type="month" name="month" min="2017-06" max="2017-09" required pattern="[0-9]{4}-[0-9]{2}"> <span class="validity"></span> </div> <div> <input type="submit" value="フォームを送信"> </div> </form>
{{ EmbedLiveSample('Handling_browser_support', 600, 100) }}
nnnn-nn
のパターン (n
は数字の0から9) に一致しない文字列を入力して送信しようとすると、エラーメッセージが表示される (そして入力欄が無効として強調表示される) のが分かるでしょう。もちろん、これでユーザーが無効な日付を入力したり (0000-42
など)、パターンに合わない誤った書式の日付が入力されたりすることを止めることはできません。
また、ユーザーが数ある日付形式の中で期待されるものがどれであるかを知らない可能性もあります。後はその分の作業が残っています。
div { margin-bottom: 10px; position: relative; } input[type="number"] { width: 100px; } input + span { padding-right: 30px; } input:invalid+span:after { position: absolute; content: '✖'; padding-left: 5px; } input:valid+span:after { position: absolute; content: '✓'; padding-left: 5px; }
(すべての主要なブラウザーが対応するまでの間) ブラウザーに依存しない方法によってフォームで日付を扱う最善の方法は、ユーザーが年と月を別々なコントロール ({{htmlelement("select")}} 要素が一般的です。以下の実装を見てください) に入力するようにするか、 jQuery date picker のような JavaScript ライブラリを使用することです。
この例では、ユーザーが都市と月を選択できるよう設計されたユーザーインターフェイスの要素を2組作成します。一つ目はネイティブの month
入力欄であり、もう一つは年と月を個別に選択することができる一組の {{HTMLElement("select")}} 要素で、まだ <input type="month">
に対応していないブラウザーのためのものです。
{{EmbedLiveSample('Examples', 600, 140)}}
年と月を入力するフォームはこのようになります。
<form> <div class="nativeDatePicker"> <label for="month-visit">何月にいらっしゃいますか?</label> <input type="month" id="month-visit" name="month-visit"> <span class="validity"></span> </div> <p class="fallbackLabel">何月にいらっしゃいますか?</p> <div class="fallbackDatePicker"> <div> <span> <select id="year" name="year"> </select> <label for="year">年</label> </span> <span> <select id="month" name="month"> <option selected>1</option> <option>2</option> <option>3</option> <option>4</option> <option>5</option> <option>6</option> <option>7</option> <option>8</option> <option>9</option> <option>10</option> <option>11</option> <option>12</option> </select> <label for="month">月</label> </span> </div> </div> </form>
nativeDatePicker
の ID がついた {{HTMLElement("div")}} は、年と月をリクエストするために month
入力欄を用いるのに対し、 fallbackDatePicker
の ID がついた <div>
は代わりに一組の <select>
要素を使用します。一つ目は年を、二つ目は月を入力します。
月を選択する <select>
は、変化しないので月をハードコーディングしています (ローカライズの問題が残っていますが)。年に利用できる値は、現在の年に応じて動的に生成されます (どのように動作するかについての詳細な説明は、以下のコードのコメントを参照してください)。
div { margin-bottom: 10px; position: relative; } input[type="number"] { width: 100px; } input + span { padding-right: 30px; } input:invalid+span:after { position: absolute; content: '✖'; padding-left: 5px; } input:valid+span:after { position: absolute; content: '✓'; padding-left: 5px; }
どちらの方法を使用するかを選択し、非ネイティブの年の <select>
に年の一覧を設定する JavaScript コードは以下の通りです。
この例の面白いもう一つの部分は、機能の検出コードです。ブラウザーが <input type="month">
に対応しているかどうかを検出するために、新たな {{htmlelement("input")}} 要素を生成し、その type
を month
に設定して、すぐに type に何が設定されたかをチェックします。対応していないブラウザーでは、 month
が フォールバックされて text
が返されます。 <input type="month">
に対応していない場合は、ネイティブの日付選択を非表示にしてフォールバック用の選択ユーザーインターフェイスを表示します。
// define variables var nativePicker = document.querySelector('.nativeDatePicker'); var fallbackPicker = document.querySelector('.fallbackDatePicker'); var fallbackLabel = document.querySelector('.fallbackLabel'); var yearSelect = document.querySelector('#year'); var monthSelect = document.querySelector('#month'); // hide fallback initially fallbackPicker.style.display = 'none'; fallbackLabel.style.display = 'none'; // test whether a new date input falls back to a text input or not var test = document.createElement('input'); try { test.type = 'month'; } catch (e) { console.log(e.description); } // if it does, run the code inside the if() {} block if(test.type === 'text') { // hide the native picker and show the fallback nativePicker.style.display = 'none'; fallbackPicker.style.display = 'block'; fallbackLabel.style.display = 'block'; // populate the years dynamically // (the months are always the same, therefore hardcoded) populateYears(); } function populateYears() { // get the current year as a number var date = new Date(); var year = date.getFullYear(); // Make this year, and the 100 years before it available in the year <select> for(var i = 0; i <= 100; i++) { var option = document.createElement('option'); option.textContent = year-i; yearSelect.appendChild(option); } }
注: 53週ある年もあることを忘れないでください(年あたりの週数を参照)。商品のアプリを開発するときはこれを念頭に置いておく必要があります。
仕様書 | 状態 | 備考 |
---|---|---|
{{SpecName('HTML WHATWG', 'forms.html#month-state-(type=month)', '<input type="month">')}} | {{Spec2('HTML WHATWG')}} |
{{Compat("html.elements.input.input-month")}}
<input type="datetime-local">
, <input type="date">
, <input type="time">
, <input type="week">