コンポーネント(5): フォーム
form
div.form-group
label 属性
for="exampleInputEmail1"Email addressinput.form-control 属性
id="exampleInputEmail1"type="email"placeholder="Enter email"aria-describedby="emailHelp"small.form-text.text-muted 属性
id="emailHelp"We'll never share your email with anyone else.div.form-group
label 属性
for="exampleInputPassword1"Passwordinput.form-control 属性
id="exampleInputPassword1"type="password"placeholder="Password"div.form-check
button.btn.btn-primary.mt-2 属性
type="submit"Submitテキスト用コントロール( input, select, textarea )には .form-control を設定する(横幅100%で角丸ボーダー表示)。
input +属性 type="(text|email|password|number|...)" の場合ブラウザデフォルトの input +属性 type="email"
input.form-control +属性 type="email"
select の場合ブラウザデフォルトの select
select.form-control
ブラウザデフォルトの select +属性 multiple
select.form-control +属性 multiple
textarea の場合ブラウザデフォルトの textarea
textarea.form-control
input +属性 type="file" の場合ファイル選択コントロール( input +属性 type="file" )には.form-control-file を設定する。
ブラウザデフォルトの input +属性 type="file"
input.form-control-file +属性 type="file" (⇒ 注1)
.form-control に .form-control-(sm|lg) を追加する。
input の場合input.form-control.form-control-sm
input.form-control
input.form-control.form-control-lg
select の場合select.form-control.form-control-sm
select.form-control
select.form-control.form-control-lg
ブラウザデフォルトの input +属性 type="range"
input.form-control-range +attribute type="range" (親要素幅にフィット)
readonly 属性
コントロールに属性 readonly を設定すると値を変更できなくなる(選択はできるためコピーは可能)。
input.form-control +属性 type="text" value="Read-only value" readonlyコントロールに .form-control-plaintext を設定すると枠を除去し通常テキストと同じように表示する。
input.form-control-plaintext +属性 type="text" value="Read-only value" readonlyform
form.form-inline
input.form-control-plaintext
div.form-check の内部に配置 属性
div.form-check (×3)
div.form-check (×3)
div.form-check に .form-check-inline を追加
インライン配置のチェックボックス
インライン配置のラジオボタン
div.form-check.form-check-inline (×3) 違いはここだけ
ラベルなしの場合は input に .position-static を追加
div.form-check
input.form-check-input.position-static 属性
id="blankCheckbox"type="checkbox"value="..."aria-label="Checkbox without label"div.form-check (×3)
input.form-check-input.position-static 属性
id="blankRadio(1|2|3)"type="radio"value="..."aria-label="Radio button without label"checkedコントロール要素( input , select , textarea , etc.)とそれに対応するラベル label は div.form-group の中に配置する。
form に灰色, div.form-group にオレンジのボーダー追加form
グリッド を利用してより高度でレスポンシブなフォームレイアウトを作成できる。次の例は単純に div.colで左右2分割した場合(間が空く)。
form
div.row
div.col (以下×2)
input.form-controlグリッドの行を div.form-row に変更するとフォーム用の短めの間隔に設定する。
form
div.form-row
div.col (以下 ×2)
input.form-control公式ドキュメントより(構造表示のため .form-group にオレンジのボーダーを追加)。
form
div.form-row
div.form-group.col-md-6 : md以上で(左側)6/12, 未満で上下配置
label Email と input Emaildiv.form-group.col-md-6 : md以上で(右側)6/12, 未満で上下配置
label Password と input Passworddiv.form-row
div.form-group.col-md-6 : md以上で(左側)6/12, 未満で上下配置
label City と inputdiv.form-group.col-md-4 : md以上で(中央右)4/12, 未満で上下配置
label State と select Choose...div.form-group.col-md-2 : md以上で(右)2/12, 未満で上下配置
label Zip と inputラベルとコントロールを水平配置するレイアウト。
まとめdiv.form-group に .row を追加 ⇒ div.form-group.rowlabel に .col-form-label を追加 ⇒ label.col-form-label.col-{breakpoint}-{width} を用いるform
div.form-group.row
label.col-form-label 属性
.col-sm-2for="inputEmail3"Emaildiv.col-sm-10
input.form-control : 属性は今までと同様(略)fieldset.form-group
div.row
legend.col-form-label 属性
.col-sm-2.pt-0Radiosdiv.col-sm-10
div.form-group.row
div.col-sm-2
Checkboxdiv.col-sm-10
左が (label|legend).col-form-label 、右が フォームコントロール .form-control の場合
(label|legend).col-form-control に .col-form-label-(sm|lg) を追加.form-control-(sm|lg) を追加(⇒ サイズ設定 )左 label.col-form-label.col-form-label-sm , 右 input.form-control.form-control-sm
左 label.col-form-label , 右 input.form-control
左 label.col-form-label.col-form-label-lg , 右 input.form-control.form-control-lg
グリッド を用いた列幅の設定例
構造form
div.form-row
div.col-7 (7/12), 内部はフォームコントロール (以下同様)div.col (残り5/12を2等分 ⇒ 5/24)div.col (残り5/12を2等分 ⇒ 5/24)列を .col から .col(-sm|-md|-lg|-xl)?-auto に変更すると幅をブラウザデフォルト値(内部コンテンツに対して可変)に設定する(⇒ グリッド - 幅の自動設定)。これを利用してフォーム要素を横(インライン)に並べて配置できる。
form
div.form-row.align-items-center
div.col-auto 属性
div.col-auto 属性
.my-1label.sr-only 属性
for="inlineFormInputGroup"Usernamediv.input-group
div.col-auto 属性
div.col-auto 属性
.my-1button.btn.btn-primary 属性
type="submit"Submit次節のインラインフォーム - 基本例とほぼ同じだが幅smブレークポイント未満(<576px)の場合が異なる。インラインフォームは auto を解除して横幅100%の縦配置に組み替えるが、こちらは常に auto が有効で幅に応じて適宜要素を折り返す。
placeholder 属性を使いデフォルト値を表示してラベル代わりにする。その場合可視ユーザにラベルは不要になるが、スクリーンリーダ利用者のために labelを設定する。これは可視ユーザには不要なので.sr-only (⇒ スクリーンリーダ)を設定して見えないようにする。レスポンシブ動作の設定例(公式ドキュメントの例を少し改良)。
構造form
div.form-row.align-items-center
div.col-sm-6.col-md-4.col-lg-3.my-1 +内部(隠れラベルとコントロール)div.col-sm-6.col-md-4.col-lg-3.my-1 +内部(インプットグループ)div.col-auto +内部(チェックボックス)div.col-auto +内部(ボタン)例1と構成は同じだが、幅変更に対して入力コントロールの幅が常に一定範囲を確保するようにレスポンシブ動作を個別調整している(インラインフォームはsmブレークポイントでの切り替えしかできないので、自分で細かく設定したい場合はこの方法を用いるとよい)。
div.col-sm-3(.my-1) だが、実際に動作確認するとsmとmdの場合に幅不足でレイアウトが乱れる。そこで各ブレークポイント毎に細かく調整してできたもの。カスタムフォームコントロール を用いた例。
構造form
div.form-row.align-items-center
div.col-auto 属性
my-1label 属性
.mr-sm-2for="inlineFormCustomSelect"Preferencediv.col-auto 属性
my-1select.custom-select 属性
.mr-sm-2id="inlineFormCustomSelect"style="width: auto;" (⇒ 注3 )option ...div.col-auto 属性
my-1div.custom-control.custom-checkbox 属性
div.col-auto 属性
my-1button.btn.btn-primary 属性
type="submit"Submitwidth: 100%; になり横一列にならない。そこで本ページではカスタムスタイルを追加して横配置になるよう修正している。(form).form-inline は構成要素を横に並べるレイアウト設定で、内部要素の設定を次のように変更する。
display: block; から) display: flex; に変更width: 100%; から) width: auto; に変更form.form-inline
label.sr-only 属性
for="inlineFormInputName2"Nameinput.form-control 属性
.my-1.mr-sm-2id="inlineFormInputName2"type="text"placeholder="Jane Doe" (ラベル代わりに用いる)label.sr-only 属性
for="inlineFormInputGroupUsername2"Usernamediv.input-group 属性
.my-1.mr-sm-2div.form-check 属性
button.btn.btn-primary 属性
.my-1type="submit"Submitform.form-inline
label 属性
.my-1.mr-2for="inlineFormCustomSelectPref"Preferenceselect.custom-select 属性
.my-1.mr-sm-2id="inlineFormCustomSelectPref"option ...div.custom-control.custom-checkbox 属性
button.btn.btn-primary 属性
.my-1type="submit"Submitsmall.form-text(.text-muted) を用い、アクセシビリティ用IDを付ける。
label 属性
for="inputPassword5"Passwordinput.form-control 属性
id="inputPassword5"type="password"aria-describedby="passwordHelpBlock"small.form-text.text-muted 属性
id="passwordHelpBlock"Your password must be 8-20 characters long, ...インラインレイアウトの場合は .form-text を付けない。
form.form-inline
disabled 属性
コントロールに属性 disabled を設定してdisabled状態にできる。またグループの親要素として fieldset を使いそこに disabled を設定するとグループ全体をdisabled状態にできる(⇒ 注4)。
form
fieldset 属性
disabled (ここに設定)disabled になるHTMLのバリデーション機能はバージョン5.0で導入された(詳しくはMDN - フォームデータの検証を参照)。今ではBootstrap 4の対応ブラウザ全てで使用できる(対応状況は Can I Use を参照)。しかし動作に環境依存がありどのブラウザでも同じ振る舞いにならない。またバリデーションメッセージはスクリーンリーダに対応していない(現状では認識困難)。
そこでBootstrap 4ではブラウザ依存を低減しスクリーンリーダがメッセージを判別できる独自方式を開発している。以下(公式ドキュメントと順番を入れ替えて)まずブラウザ標準の方法を示し、次にBootstrap方式を説明する。
required を利用した簡単なバリデーションの例。レイアウトの説明は省略し、バリデーションに関するポイントのみ示す。ただし送信時の応答にブラウザ依存性があり、表示されるメッセージやその表現方法も異なることに注意(本例を用いて色々なブラウザで実行すれば確認できる)。
input に属性 required を追加pattern 属性を利用できる(正規表現で設定)
pattern="[0-9]{5}"Bootstrap 4のバリデーション方式で作ったフォーム例。
HTMLはバリデーションに関するポイントのみ説明する。
HTMLまとめform に次の2つを設定
novalidate (ブラウザデフォルトのバリデーション動作を抑制).needs-validation を用いる.form-controlrequired 属性)(div).valid-feedback(div).invalid-feedback次にBootstrap 4 (CSS)のバリデーション機能についてまとめる。
CSSまとめform )に対し .was-validated の有無で表示を制御
.form-control を設定
.was-validated +自分に :valid が設定されると緑ボーダー表示.was-validated +自分に :invalid が設定されると赤ボーダー表示.valid-feedback : 次の条件で表示される
.was-validated が設定.form-control に疑似クラス :valid が設定.invalid-feedback : 次の条件で表示される
.was-validated が設定.form-control に疑似クラス :invalid が設定div.col* や div.col-auto などでもよい処理にはJavaScriptが必要。
JavaScriptまとめform (今回は .needs-validation )の submit イベントハンドラを設定{form}.checkValidity()
:valid 疑似クラスが設定される:invalid 疑似クラスが設定されるevent.preventDefault()event.stopPropagation().was-validated を追加// DOM版(公式ドキュメントより)
(function() {
'use strict';
window.addEventListener('load', function() {
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
// jQuery版
$('.needs-validation').on('submit', function(event) {
if (!this.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
$(this).addClass('was-validated');
});
送信してサーバ側でバリデーションを行い、サーバ側から結果を反映したフォームを送り返す場合は疑似クラスは使えない。そこで代替手段として .is-valid と .is-invalid を用いて上記バリデーションと同じ表示効果を得ることができる。
form に .was-validated は不要.is-valid.is-invalid.valid-feedback.invalid-feedback次はその設定例。ブラウザから送信後にサーバでバリデーションを行い、First nameとLast nameは正しく後は不正という結果を送り返した状態を表したもの。
設定form にはクラスや属性の追加なし.is-valid を追加
.valid-feedback は成功メッセージとして緑色表示.is-invalid を追加
.invalid-feedback は失敗メッセージとして赤色表示Bootstrapバリデーションはカスタムフォームコントロールに対応しており、通常のフォームコントロールと同じように使うことができる。次はその設定サンプルでデモ用に最初からバリデーション状態にしてある(送信もなし)。どれも入力すると表示が赤から緑に変化する。
設定.was-validated を設定(説明用に最初からバリデーション状態にする)required を追加
バリデーションの応答メッセージとして背景が半透明のツールチップをポップアップ表示できる。この方法を用いればレイアウト位置を変えずにバリデーション表示を行うことができる。
設定div.valid-feedback ⇒ div.valid-tooltip に変更div.invalid-feedback ⇒ div.invalid-tooltip に変更Bootstrap 4で導入された表示カスタマイズ、ブラウザ依存改善、アクセシビリティ向上のためのフォーム用部品。ブラウザデフォルトのコントロールを置き換えて利用できる。
div.custom-control.custom-checkbox (×4)
3番目のチェックボックスは初期状態を - にしてある。これは :indeterminate 疑似クラスを用いたもので、次のコードで設定している(要JavaScript)。
document.getElementById('custom-check-3').indeterminate = true;
jQueryを利用する場合は次でもよい。
$('#custom-check-3').prop('indeterminate', true);
div.custom-control.custom-radio (×4)
div.custom-control.custom-radio.custom-control-inline (×4)
div.custom-control.custom-switch (×2)
select.custom-select.custom-select-sm
select.custom-select
select.custom-select.custom-select-lg
属性 multiple を設定した場合の表示
属性 size="3" を設定した場合の表示
デフォルトの範囲は 0..100 、値は 50 、ステップは 1 に設定される。
label 属性
for="customRange1"Example rangeinput.custom-range 属性
id="customRange1"type="range"範囲は min と max 、値は value で設定する。
label 属性
for="customRange2"Example rangeinput.custom-range 属性
id="customRange2"type="range"min="0"max="5"value="1"ステップは step で設定する。
label 属性
for="customRange3"Example rangeinput.custom-range 属性
id="customRange3"type="range"min="0"step="0.5"max="5"value="3.5"div.custom-file
カスタムファイルブラウザの表示 Browse は任意の文字に変更できる。
(4.2以降) label.custom-file-label に data-browse="{表示する文字列}" を追加することにより設定できる。以下は英語(en)、日本語(ja)、スペイン語(es)の設定例。
data-browse の設定よりも優先度が高くなり、この設定は効かなくなる。より本格的にbootstrap.cssをソースコードからカスタマイズすることにより、label.custom-file-label の言語属性(lang="{言語コード}")に対して表示を変更するように設定できる。ただしSass(.scss)とnode.js開発環境の知識が必要。詳しくは本節の公式ドキュメント本文参照。
Sassの知識がなくてもBootstrap CSSの後に自分用のカスタムCSSを追加すれば同じように設定できる。単純にすべて日本語に変更する場合はHTMLの head ブロックの最後に次のCSS設定を追加すればよい。
<style>.custom-file-label::after { content: "ファイル選択"; }</style>
label 要素の lang 属性に応じて自動判別する場合は次のCSSコード例を参照。この場合はSass(Cscc)ソースレベルからのカスタマイズと全く同じ効果が得られる。
/* en(英語,デフォルト)はbootstrap.cssに設定済み(略) */
/* ja(日本語) */
.custom-file-input:lang(ja) ~ .custom-file-label::after {
content: "ファイル選択";
}
/* es(スペイン語) */
.custom-file-input:lang(es) ~ .custom-file-label::after {
content: "Elegir";
}
設定例は次の通り(en/ja/es)。
カスタムファイルブラウザは要素のデフォルト表示を( style="opacity: 0;" で)消去しその上にカスタム表示を行っている。そのためファイル名表示のための別要素が必要で、その更新にJavaScriptコードを用いる。例を示す(jQuery版を本サイト全体に設定済)。
// DOM版
(function() {
window.addEventListener('load', function() {
var input = document.getElementById('custom-file');
input.addEventListener('change', function(event) {
var label = document.querySelector('[for="custom-file"]');
label.textContent = event.target.files[0].name;
}, false);
}, false);
})();
// jQuery版
$('#custom-file').on('change', function(event) {
$('[for="custom-file"]').text($(this).prop('files')[0].name);
});