Stripped personal data from development repository
Samo Penic
2019-02-20 83c3f647c35477564b77cbc5b36d37d793d5442a
commit | author | age
83c3f6 1 ---
SP 2 layout: docs
3 title: Forms
4 description: Examples and usage guidelines for form control styles, layout options, and custom components for creating a wide variety of forms.
5 group: components
6 toc: true
7 ---
8
9 ## Overview
10
11 Bootstrap's form controls expand on [our Rebooted form styles]({{ site.baseurl }}/docs/{{ site.docs_version }}/content/reboot/#forms) with classes. Use these classes to opt into their customized displays for a more consistent rendering across browsers and devices.
12
13 Be sure to use an appropriate `type` attribute on all inputs (e.g., `email` for email address or `number` for numerical information) to take advantage of newer input controls like email verification, number selection, and more.
14
15 Here's a quick example to demonstrate Bootstrap's form styles. Keep reading for documentation on required classes, form layout, and more.
16
17 {% capture example %}
18 <form>
19   <div class="form-group">
20     <label for="exampleInputEmail1">Email address</label>
21     <input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter email">
22     <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small>
23   </div>
24   <div class="form-group">
25     <label for="exampleInputPassword1">Password</label>
26     <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
27   </div>
28   <div class="form-group form-check">
29     <input type="checkbox" class="form-check-input" id="exampleCheck1">
30     <label class="form-check-label" for="exampleCheck1">Check me out</label>
31   </div>
32   <button type="submit" class="btn btn-primary">Submit</button>
33 </form>
34 {% endcapture %}
35 {% include example.html content=example %}
36
37 ## Form controls
38
39 Textual form controls—like `<input>`s, `<select>`s, and `<textarea>`s—are styled with the `.form-control` class. Included are styles for general appearance, focus state, sizing, and more.
40
41 Be sure to explore our [custom forms](#custom-forms) to further style `<select>`s.
42
43 {% capture example %}
44 <form>
45   <div class="form-group">
46     <label for="exampleFormControlInput1">Email address</label>
47     <input type="email" class="form-control" id="exampleFormControlInput1" placeholder="name@example.com">
48   </div>
49   <div class="form-group">
50     <label for="exampleFormControlSelect1">Example select</label>
51     <select class="form-control" id="exampleFormControlSelect1">
52       <option>1</option>
53       <option>2</option>
54       <option>3</option>
55       <option>4</option>
56       <option>5</option>
57     </select>
58   </div>
59   <div class="form-group">
60     <label for="exampleFormControlSelect2">Example multiple select</label>
61     <select multiple class="form-control" id="exampleFormControlSelect2">
62       <option>1</option>
63       <option>2</option>
64       <option>3</option>
65       <option>4</option>
66       <option>5</option>
67     </select>
68   </div>
69   <div class="form-group">
70     <label for="exampleFormControlTextarea1">Example textarea</label>
71     <textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
72   </div>
73 </form>
74 {% endcapture %}
75 {% include example.html content=example %}
76
77 For file inputs, swap the `.form-control` for `.form-control-file`.
78
79 {% capture example %}
80 <form>
81   <div class="form-group">
82     <label for="exampleFormControlFile1">Example file input</label>
83     <input type="file" class="form-control-file" id="exampleFormControlFile1">
84   </div>
85 </form>
86 {% endcapture %}
87 {% include example.html content=example %}
88
89 ### Sizing
90
91 Set heights using classes like `.form-control-lg` and `.form-control-sm`.
92
93 {% capture example %}
94 <input class="form-control form-control-lg" type="text" placeholder=".form-control-lg">
95 <input class="form-control" type="text" placeholder="Default input">
96 <input class="form-control form-control-sm" type="text" placeholder=".form-control-sm">
97 {% endcapture %}
98 {% include example.html content=example %}
99
100 {% capture example %}
101 <select class="form-control form-control-lg">
102   <option>Large select</option>
103 </select>
104 <select class="form-control">
105   <option>Default select</option>
106 </select>
107 <select class="form-control form-control-sm">
108   <option>Small select</option>
109 </select>
110 {% endcapture %}
111 {% include example.html content=example %}
112
113 ### Readonly
114
115 Add the `readonly` boolean attribute on an input to prevent modification of the input's value. Read-only inputs appear lighter (just like disabled inputs), but retain the standard cursor.
116
117 {% capture example %}
118 <input class="form-control" type="text" placeholder="Readonly input here…" readonly>
119 {% endcapture %}
120 {% include example.html content=example %}
121
122 ### Readonly plain text
123
124 If you want to have `<input readonly>` elements in your form styled as plain text, use the `.form-control-plaintext` class to remove the default form field styling and preserve the correct margin and padding.
125
126 {% capture example %}
127 <form>
128   <div class="form-group row">
129     <label for="staticEmail" class="col-sm-2 col-form-label">Email</label>
130     <div class="col-sm-10">
131       <input type="text" readonly class="form-control-plaintext" id="staticEmail" value="email@example.com">
132     </div>
133   </div>
134   <div class="form-group row">
135     <label for="inputPassword" class="col-sm-2 col-form-label">Password</label>
136     <div class="col-sm-10">
137       <input type="password" class="form-control" id="inputPassword" placeholder="Password">
138     </div>
139   </div>
140 </form>
141 {% endcapture %}
142 {% include example.html content=example %}
143
144 {% capture example %}
145 <form class="form-inline">
146   <div class="form-group mb-2">
147     <label for="staticEmail2" class="sr-only">Email</label>
148     <input type="text" readonly class="form-control-plaintext" id="staticEmail2" value="email@example.com">
149   </div>
150   <div class="form-group mx-sm-3 mb-2">
151     <label for="inputPassword2" class="sr-only">Password</label>
152     <input type="password" class="form-control" id="inputPassword2" placeholder="Password">
153   </div>
154   <button type="submit" class="btn btn-primary mb-2">Confirm identity</button>
155 </form>
156 {% endcapture %}
157 {% include example.html content=example %}
158
159 ## Range Inputs
160
161 Set horizontally scrollable range inputs using `.form-control-range`.
162
163 {% capture example %}
164 <form>
165   <div class="form-group">
166     <label for="formControlRange">Example Range input</label>
167     <input type="range" class="form-control-range" id="formControlRange">
168   </div>
169 </form>
170 {% endcapture %}
171 {% include example.html content=example %}
172
173 ## Checkboxes and radios
174
175 Default checkboxes and radios are improved upon with the help of `.form-check`, **a single class for both input types that improves the layout and behavior of their HTML elements**. Checkboxes are for selecting one or several options in a list, while radios are for selecting one option from many.
176
177 Disabled checkboxes and radios are supported, but to provide a `not-allowed` cursor on hover of the parent `<label>`, you'll need to add the `disabled` attribute to the `.form-check-input`. The disabled attribute will apply a lighter color to help indicate the input's state.
178
179 Checkboxes and radios use are built to support HTML-based form validation and provide concise, accessible labels. As such, our `<input>`s and `<label>`s are sibling elements as opposed to an `<input>` within a `<label>`. This is slightly more verbose as you must specify `id` and `for` attributes to relate the `<input>` and `<label>`.
180
181 ### Default (stacked)
182
183 By default, any number of checkboxes and radios that are immediate sibling will be vertically stacked and appropriately spaced with `.form-check`.
184
185 {% capture example %}
186 <div class="form-check">
187   <input class="form-check-input" type="checkbox" value="" id="defaultCheck1">
188   <label class="form-check-label" for="defaultCheck1">
189     Default checkbox
190   </label>
191 </div>
192 <div class="form-check">
193   <input class="form-check-input" type="checkbox" value="" id="defaultCheck2" disabled>
194   <label class="form-check-label" for="defaultCheck2">
195     Disabled checkbox
196   </label>
197 </div>
198 {% endcapture %}
199 {% include example.html content=example %}
200
201 {% capture example %}
202 <div class="form-check">
203   <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios1" value="option1" checked>
204   <label class="form-check-label" for="exampleRadios1">
205     Default radio
206   </label>
207 </div>
208 <div class="form-check">
209   <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios2" value="option2">
210   <label class="form-check-label" for="exampleRadios2">
211     Second default radio
212   </label>
213 </div>
214 <div class="form-check">
215   <input class="form-check-input" type="radio" name="exampleRadios" id="exampleRadios3" value="option3" disabled>
216   <label class="form-check-label" for="exampleRadios3">
217     Disabled radio
218   </label>
219 </div>
220 {% endcapture %}
221 {% include example.html content=example %}
222
223 ### Inline
224
225 Group checkboxes or radios on the same horizontal row by adding `.form-check-inline` to any `.form-check`.
226
227 {% capture example %}
228 <div class="form-check form-check-inline">
229   <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
230   <label class="form-check-label" for="inlineCheckbox1">1</label>
231 </div>
232 <div class="form-check form-check-inline">
233   <input class="form-check-input" type="checkbox" id="inlineCheckbox2" value="option2">
234   <label class="form-check-label" for="inlineCheckbox2">2</label>
235 </div>
236 <div class="form-check form-check-inline">
237   <input class="form-check-input" type="checkbox" id="inlineCheckbox3" value="option3" disabled>
238   <label class="form-check-label" for="inlineCheckbox3">3 (disabled)</label>
239 </div>
240 {% endcapture %}
241 {% include example.html content=example %}
242
243 {% capture example %}
244 <div class="form-check form-check-inline">
245   <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio1" value="option1">
246   <label class="form-check-label" for="inlineRadio1">1</label>
247 </div>
248 <div class="form-check form-check-inline">
249   <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio2" value="option2">
250   <label class="form-check-label" for="inlineRadio2">2</label>
251 </div>
252 <div class="form-check form-check-inline">
253   <input class="form-check-input" type="radio" name="inlineRadioOptions" id="inlineRadio3" value="option3" disabled>
254   <label class="form-check-label" for="inlineRadio3">3 (disabled)</label>
255 </div>
256 {% endcapture %}
257 {% include example.html content=example %}
258
259 ### Without labels
260
261 Add `.position-static` to inputs within `.form-check` that don't have any label text. Remember to still provide some form of label for assistive technologies (for instance, using `aria-label`).
262
263 {% capture example %}
264 <div class="form-check">
265   <input class="form-check-input position-static" type="checkbox" id="blankCheckbox" value="option1" aria-label="...">
266 </div>
267 <div class="form-check">
268   <input class="form-check-input position-static" type="radio" name="blankRadio" id="blankRadio1" value="option1" aria-label="...">
269 </div>
270 {% endcapture %}
271 {% include example.html content=example %}
272
273 ## Layout
274
275 Since Bootstrap applies `display: block` and `width: 100%` to almost all our form controls, forms will by default stack vertically. Additional classes can be used to vary this layout on a per-form basis.
276
277 ### Form groups
278
279 The `.form-group` class is the easiest way to add some structure to forms. It provides a flexible class that encourages proper grouping of labels, controls, optional help text, and form validation messaging. By default it only applies `margin-bottom`, but it picks up additional styles in `.form-inline` as needed. Use it with `<fieldset>`s, `<div>`s, or nearly any other element.
280
281 {% capture example %}
282 <form>
283   <div class="form-group">
284     <label for="formGroupExampleInput">Example label</label>
285     <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Example input">
286   </div>
287   <div class="form-group">
288     <label for="formGroupExampleInput2">Another label</label>
289     <input type="text" class="form-control" id="formGroupExampleInput2" placeholder="Another input">
290   </div>
291 </form>
292 {% endcapture %}
293 {% include example.html content=example %}
294
295 ### Form grid
296
297 More complex forms can be built using our grid classes. Use these for form layouts that require multiple columns, varied widths, and additional alignment options.
298
299 {% capture example %}
300 <form>
301   <div class="row">
302     <div class="col">
303       <input type="text" class="form-control" placeholder="First name">
304     </div>
305     <div class="col">
306       <input type="text" class="form-control" placeholder="Last name">
307     </div>
308   </div>
309 </form>
310 {% endcapture %}
311 {% include example.html content=example %}
312
313 #### Form row
314
315 You may also swap `.row` for `.form-row`, a variation of our standard grid row that overrides the default column gutters for tighter and more compact layouts.
316
317 {% capture example %}
318 <form>
319   <div class="form-row">
320     <div class="col">
321       <input type="text" class="form-control" placeholder="First name">
322     </div>
323     <div class="col">
324       <input type="text" class="form-control" placeholder="Last name">
325     </div>
326   </div>
327 </form>
328 {% endcapture %}
329 {% include example.html content=example %}
330
331 More complex layouts can also be created with the grid system.
332
333 {% capture example %}
334 <form>
335   <div class="form-row">
336     <div class="form-group col-md-6">
337       <label for="inputEmail4">Email</label>
338       <input type="email" class="form-control" id="inputEmail4" placeholder="Email">
339     </div>
340     <div class="form-group col-md-6">
341       <label for="inputPassword4">Password</label>
342       <input type="password" class="form-control" id="inputPassword4" placeholder="Password">
343     </div>
344   </div>
345   <div class="form-group">
346     <label for="inputAddress">Address</label>
347     <input type="text" class="form-control" id="inputAddress" placeholder="1234 Main St">
348   </div>
349   <div class="form-group">
350     <label for="inputAddress2">Address 2</label>
351     <input type="text" class="form-control" id="inputAddress2" placeholder="Apartment, studio, or floor">
352   </div>
353   <div class="form-row">
354     <div class="form-group col-md-6">
355       <label for="inputCity">City</label>
356       <input type="text" class="form-control" id="inputCity">
357     </div>
358     <div class="form-group col-md-4">
359       <label for="inputState">State</label>
360       <select id="inputState" class="form-control">
361         <option selected>Choose...</option>
362         <option>...</option>
363       </select>
364     </div>
365     <div class="form-group col-md-2">
366       <label for="inputZip">Zip</label>
367       <input type="text" class="form-control" id="inputZip">
368     </div>
369   </div>
370   <div class="form-group">
371     <div class="form-check">
372       <input class="form-check-input" type="checkbox" id="gridCheck">
373       <label class="form-check-label" for="gridCheck">
374         Check me out
375       </label>
376     </div>
377   </div>
378   <button type="submit" class="btn btn-primary">Sign in</button>
379 </form>
380 {% endcapture %}
381 {% include example.html content=example %}
382
383 #### Horizontal form
384
385 Create horizontal forms with the grid by adding the `.row` class to form groups and using the `.col-*-*` classes to specify the width of your labels and controls. Be sure to add `.col-form-label` to your `<label>`s as well so they're vertically centered with their associated form controls.
386
387 At times, you maybe need to use margin or padding utilities to create that perfect alignment you need. For example, we've removed the `padding-top` on our stacked radio inputs label to better align the text baseline.
388
389 {% capture example %}
390 <form>
391   <div class="form-group row">
392     <label for="inputEmail3" class="col-sm-2 col-form-label">Email</label>
393     <div class="col-sm-10">
394       <input type="email" class="form-control" id="inputEmail3" placeholder="Email">
395     </div>
396   </div>
397   <div class="form-group row">
398     <label for="inputPassword3" class="col-sm-2 col-form-label">Password</label>
399     <div class="col-sm-10">
400       <input type="password" class="form-control" id="inputPassword3" placeholder="Password">
401     </div>
402   </div>
403   <fieldset class="form-group">
404     <div class="row">
405       <legend class="col-form-label col-sm-2 pt-0">Radios</legend>
406       <div class="col-sm-10">
407         <div class="form-check">
408           <input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
409           <label class="form-check-label" for="gridRadios1">
410             First radio
411           </label>
412         </div>
413         <div class="form-check">
414           <input class="form-check-input" type="radio" name="gridRadios" id="gridRadios2" value="option2">
415           <label class="form-check-label" for="gridRadios2">
416             Second radio
417           </label>
418         </div>
419         <div class="form-check disabled">
420           <input class="form-check-input" type="radio" name="gridRadios" id="gridRadios3" value="option3" disabled>
421           <label class="form-check-label" for="gridRadios3">
422             Third disabled radio
423           </label>
424         </div>
425       </div>
426     </div>
427   </fieldset>
428   <div class="form-group row">
429     <div class="col-sm-2">Checkbox</div>
430     <div class="col-sm-10">
431       <div class="form-check">
432         <input class="form-check-input" type="checkbox" id="gridCheck1">
433         <label class="form-check-label" for="gridCheck1">
434           Example checkbox
435         </label>
436       </div>
437     </div>
438   </div>
439   <div class="form-group row">
440     <div class="col-sm-10">
441       <button type="submit" class="btn btn-primary">Sign in</button>
442     </div>
443   </div>
444 </form>
445 {% endcapture %}
446 {% include example.html content=example %}
447
448 ##### Horizontal form label sizing
449
450 Be sure to use `.col-form-label-sm` or `.col-form-label-lg` to your `<label>`s or `<legend>`s to correctly follow the size of `.form-control-lg` and `.form-control-sm`.
451
452 {% capture example %}
453 <form>
454   <div class="form-group row">
455     <label for="colFormLabelSm" class="col-sm-2 col-form-label col-form-label-sm">Email</label>
456     <div class="col-sm-10">
457       <input type="email" class="form-control form-control-sm" id="colFormLabelSm" placeholder="col-form-label-sm">
458     </div>
459   </div>
460   <div class="form-group row">
461     <label for="colFormLabel" class="col-sm-2 col-form-label">Email</label>
462     <div class="col-sm-10">
463       <input type="email" class="form-control" id="colFormLabel" placeholder="col-form-label">
464     </div>
465   </div>
466   <div class="form-group row">
467     <label for="colFormLabelLg" class="col-sm-2 col-form-label col-form-label-lg">Email</label>
468     <div class="col-sm-10">
469       <input type="email" class="form-control form-control-lg" id="colFormLabelLg" placeholder="col-form-label-lg">
470     </div>
471   </div>
472 </form>
473 {% endcapture %}
474 {% include example.html content=example %}
475
476 #### Column sizing
477
478 As shown in the previous examples, our grid system allows you to place any number of `.col`s within a `.row` or `.form-row`. They'll split the available width equally between them. You may also pick a subset of your columns to take up more or less space, while the remaining `.col`s equally split the rest, with specific column classes like `.col-7`.
479
480 {% capture example %}
481 <form>
482   <div class="form-row">
483     <div class="col-7">
484       <input type="text" class="form-control" placeholder="City">
485     </div>
486     <div class="col">
487       <input type="text" class="form-control" placeholder="State">
488     </div>
489     <div class="col">
490       <input type="text" class="form-control" placeholder="Zip">
491     </div>
492   </div>
493 </form>
494 {% endcapture %}
495 {% include example.html content=example %}
496
497 #### Auto-sizing
498
499 The example below uses a flexbox utility to vertically center the contents and changes `.col` to `.col-auto` so that your columns only take up as much space as needed. Put another way, the column sizes itself based on the contents.
500
501 {% capture example %}
502 <form>
503   <div class="form-row align-items-center">
504     <div class="col-auto">
505       <label class="sr-only" for="inlineFormInput">Name</label>
506       <input type="text" class="form-control mb-2" id="inlineFormInput" placeholder="Jane Doe">
507     </div>
508     <div class="col-auto">
509       <label class="sr-only" for="inlineFormInputGroup">Username</label>
510       <div class="input-group mb-2">
511         <div class="input-group-prepend">
512           <div class="input-group-text">@</div>
513         </div>
514         <input type="text" class="form-control" id="inlineFormInputGroup" placeholder="Username">
515       </div>
516     </div>
517     <div class="col-auto">
518       <div class="form-check mb-2">
519         <input class="form-check-input" type="checkbox" id="autoSizingCheck">
520         <label class="form-check-label" for="autoSizingCheck">
521           Remember me
522         </label>
523       </div>
524     </div>
525     <div class="col-auto">
526       <button type="submit" class="btn btn-primary mb-2">Submit</button>
527     </div>
528   </div>
529 </form>
530 {% endcapture %}
531 {% include example.html content=example %}
532
533 You can then remix that once again with size-specific column classes.
534
535 {% capture example %}
536 <form>
537   <div class="form-row align-items-center">
538     <div class="col-sm-3 my-1">
539       <label class="sr-only" for="inlineFormInputName">Name</label>
540       <input type="text" class="form-control" id="inlineFormInputName" placeholder="Jane Doe">
541     </div>
542     <div class="col-sm-3 my-1">
543       <label class="sr-only" for="inlineFormInputGroupUsername">Username</label>
544       <div class="input-group">
545         <div class="input-group-prepend">
546           <div class="input-group-text">@</div>
547         </div>
548         <input type="text" class="form-control" id="inlineFormInputGroupUsername" placeholder="Username">
549       </div>
550     </div>
551     <div class="col-auto my-1">
552       <div class="form-check">
553         <input class="form-check-input" type="checkbox" id="autoSizingCheck2">
554         <label class="form-check-label" for="autoSizingCheck2">
555           Remember me
556         </label>
557       </div>
558     </div>
559     <div class="col-auto my-1">
560       <button type="submit" class="btn btn-primary">Submit</button>
561     </div>
562   </div>
563 </form>
564 {% endcapture %}
565 {% include example.html content=example %}
566
567 And of course [custom form controls](#custom-forms) are supported.
568
569 {% capture example %}
570 <form>
571   <div class="form-row align-items-center">
572     <div class="col-auto my-1">
573       <label class="mr-sm-2 sr-only" for="inlineFormCustomSelect">Preference</label>
574       <select class="custom-select mr-sm-2" id="inlineFormCustomSelect">
575         <option selected>Choose...</option>
576         <option value="1">One</option>
577         <option value="2">Two</option>
578         <option value="3">Three</option>
579       </select>
580     </div>
581     <div class="col-auto my-1">
582       <div class="custom-control custom-checkbox mr-sm-2">
583         <input type="checkbox" class="custom-control-input" id="customControlAutosizing">
584         <label class="custom-control-label" for="customControlAutosizing">Remember my preference</label>
585       </div>
586     </div>
587     <div class="col-auto my-1">
588       <button type="submit" class="btn btn-primary">Submit</button>
589     </div>
590   </div>
591 </form>
592 {% endcapture %}
593 {% include example.html content=example %}
594
595 ### Inline forms
596
597 Use the `.form-inline` class to display a series of labels, form controls, and buttons on a single horizontal row. Form controls within inline forms vary slightly from their default states.
598
599 - Controls are `display: flex`, collapsing any HTML white space and allowing you to provide alignment control with [spacing]({{ site.baseurl }}/docs/{{ site.docs_version }}/utilities/spacing/) and [flexbox]({{ site.baseurl }}/docs/{{ site.docs_version }}/utilities/flex/) utilities.
600 - Controls and input groups receive `width: auto` to override the Bootstrap default `width: 100%`.
601 - Controls **only appear inline in viewports that are at least 576px wide** to account for narrow viewports on mobile devices.
602
603 You may need to manually address the width and alignment of individual form controls with [spacing utilities]({{ site.baseurl }}/docs/{{ site.docs_version }}/utilities/spacing/) (as shown below). Lastly, be sure to always include a `<label>` with each form control, even if you need to hide it from non-screenreader visitors with `.sr-only`.
604
605 {% capture example %}
606 <form class="form-inline">
607   <label class="sr-only" for="inlineFormInputName2">Name</label>
608   <input type="text" class="form-control mb-2 mr-sm-2" id="inlineFormInputName2" placeholder="Jane Doe">
609
610   <label class="sr-only" for="inlineFormInputGroupUsername2">Username</label>
611   <div class="input-group mb-2 mr-sm-2">
612     <div class="input-group-prepend">
613       <div class="input-group-text">@</div>
614     </div>
615     <input type="text" class="form-control" id="inlineFormInputGroupUsername2" placeholder="Username">
616   </div>
617
618   <div class="form-check mb-2 mr-sm-2">
619     <input class="form-check-input" type="checkbox" id="inlineFormCheck">
620     <label class="form-check-label" for="inlineFormCheck">
621       Remember me
622     </label>
623   </div>
624
625   <button type="submit" class="btn btn-primary mb-2">Submit</button>
626 </form>
627 {% endcapture %}
628 {% include example.html content=example %}
629
630 Custom form controls and selects are also supported.
631
632 {% capture example %}
633 <form class="form-inline">
634   <label class="my-1 mr-2" for="inlineFormCustomSelectPref">Preference</label>
635   <select class="custom-select my-1 mr-sm-2" id="inlineFormCustomSelectPref">
636     <option selected>Choose...</option>
637     <option value="1">One</option>
638     <option value="2">Two</option>
639     <option value="3">Three</option>
640   </select>
641
642   <div class="custom-control custom-checkbox my-1 mr-sm-2">
643     <input type="checkbox" class="custom-control-input" id="customControlInline">
644     <label class="custom-control-label" for="customControlInline">Remember my preference</label>
645   </div>
646
647   <button type="submit" class="btn btn-primary my-1">Submit</button>
648 </form>
649 {% endcapture %}
650 {% include example.html content=example %}
651
652 {% capture callout %}
653 ##### Alternatives to hidden labels
654 Assistive technologies such as screen readers will have trouble with your forms if you don't include a label for every input. For these inline forms, you can hide the labels using the `.sr-only` class. There are further alternative methods of providing a label for assistive technologies, such as the `aria-label`, `aria-labelledby` or `title` attribute. If none of these are present, assistive technologies may resort to using the `placeholder` attribute, if present, but note that use of `placeholder` as a replacement for other labelling methods is not advised.
655 {% endcapture %}
656 {% include callout.html content=callout type="warning" %}
657
658 ## Help text
659
660 Block-level help text in forms can be created using `.form-text` (previously known as `.help-block` in v3). Inline help text can be flexibly implemented using any inline HTML element and utility classes like `.text-muted`.
661
662 {% capture callout %}
663 ##### Associating help text with form controls
664
665 Help text should be explicitly associated with the form control it relates to using the `aria-describedby` attribute. This will ensure that assistive technologies—such as screen readers—will announce this help text when the user focuses or enters the control.
666 {% endcapture %}
667 {% include callout.html content=callout type="warning" %}
668
669 Help text below inputs can be styled with `.form-text`. This class includes `display: block` and adds some top margin for easy spacing from the inputs above.
670
671 {% capture example %}
672 <label for="inputPassword5">Password</label>
673 <input type="password" id="inputPassword5" class="form-control" aria-describedby="passwordHelpBlock">
674 <small id="passwordHelpBlock" class="form-text text-muted">
675   Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji.
676 </small>
677 {% endcapture %}
678 {% include example.html content=example %}
679
680 Inline text can use any typical inline HTML element (be it a `<small>`, `<span>`, or something else) with nothing more than a utility class.
681
682 {% capture example %}
683 <form class="form-inline">
684   <div class="form-group">
685     <label for="inputPassword6">Password</label>
686     <input type="password" id="inputPassword6" class="form-control mx-sm-3" aria-describedby="passwordHelpInline">
687     <small id="passwordHelpInline" class="text-muted">
688       Must be 8-20 characters long.
689     </small>
690   </div>
691 </form>
692 {% endcapture %}
693 {% include example.html content=example %}
694
695 ## Disabled forms
696
697 Add the `disabled` boolean attribute on an input to prevent user interactions and make it appear lighter.
698
699 {% highlight html %}
700 <input class="form-control" id="disabledInput" type="text" placeholder="Disabled input here..." disabled>
701 {% endhighlight %}
702
703 Add the `disabled` attribute to a `<fieldset>` to disable all the controls within.
704
705 {% capture example %}
706 <form>
707   <fieldset disabled>
708     <div class="form-group">
709       <label for="disabledTextInput">Disabled input</label>
710       <input type="text" id="disabledTextInput" class="form-control" placeholder="Disabled input">
711     </div>
712     <div class="form-group">
713       <label for="disabledSelect">Disabled select menu</label>
714       <select id="disabledSelect" class="form-control">
715         <option>Disabled select</option>
716       </select>
717     </div>
718     <div class="form-group">
719       <div class="form-check">
720         <input class="form-check-input" type="checkbox" id="disabledFieldsetCheck" disabled>
721         <label class="form-check-label" for="disabledFieldsetCheck">
722           Can't check this
723         </label>
724       </div>
725     </div>
726     <button type="submit" class="btn btn-primary">Submit</button>
727   </fieldset>
728 </form>
729 {% endcapture %}
730 {% include example.html content=example %}
731
732 {% capture callout %}
733 ##### Caveat with anchors
734
735 By default, browsers will treat all native form controls (`<input>`, `<select>` and `<button>` elements) inside a `<fieldset disabled>` as disabled, preventing both keyboard and mouse interactions on them. However, if your form also includes `<a ... class="btn btn-*">` elements, these will only be given a style of `pointer-events: none`. As noted in the section about [disabled state for buttons]({{ site.baseurl }}/docs/{{ site.docs_version }}/components/buttons/#disabled-state) (and specifically in the sub-section for anchor elements), this CSS property is not yet standardized and isn't fully supported in Internet Explorer 10, and won't prevent keyboard users from being able to focus or activate these links. So to be safe, use custom JavaScript to disable such links.
736 {% endcapture %}
737 {% include callout.html content=callout type="warning" %}
738
739 {% capture callout %}
740 #### Cross-browser compatibility
741
742 While Bootstrap will apply these styles in all browsers, Internet Explorer 11 and below don't fully support the `disabled` attribute on a `<fieldset>`. Use custom JavaScript to disable the fieldset in these browsers.
743 {% endcapture %}
744 {% include callout.html content=callout type="danger" %}
745
746 ## Validation
747
748 Provide valuable, actionable feedback to your users with HTML5 form validation–[available in all our supported browsers](https://caniuse.com/#feat=form-validation). Choose from the browser default validation feedback, or implement custom messages with our built-in classes and starter JavaScript.
749
750 {% capture callout %}
751 We currently recommend using custom validation styles, as native browser default validation messages are not consistently exposed to assistive technologies in all browsers (most notably, Chrome on desktop and mobile).
752 {% endcapture %}
753 {% include callout.html content=callout type="warning" %}
754
755 ### How it works
756
757 Here's how form validation works with Bootstrap:
758
759 - HTML form validation is applied via CSS's two pseudo-classes, `:invalid` and `:valid`. It applies to `<input>`, `<select>`, and `<textarea>` elements.
760 - Bootstrap scopes the `:invalid` and `:valid` styles to parent `.was-validated` class, usually applied to the `<form>`. Otherwise, any required field without a value shows up as invalid on page load. This way, you may choose when to activate them (typically after form submission is attempted).
761 - To reset the appearance of the form (for instance, in the case of dynamic form submissions using AJAX), remove the `.was-validated` class from the `<form>` again after submission.
762 - As a fallback, `.is-invalid` and `.is-valid` classes may be used instead of the pseudo-classes for [server side validation](#server-side). They do not require a `.was-validated` parent class.
763 - Due to constraints in how CSS works, we cannot (at present) apply styles to a `<label>` that comes before a form control in the DOM without the help of custom JavaScript.
764 - All modern browsers support the [constraint validation API](https://www.w3.org/TR/html5/sec-forms.html#the-constraint-validation-api), a series of JavaScript methods for validating form controls.
765 - Feedback messages may utilize the [browser defaults](#browser-defaults) (different for each browser, and unstylable via CSS) or our custom feedback styles with additional HTML and CSS.
766 - You may provide custom validity messages with `setCustomValidity` in JavaScript.
767
768 With that in mind, consider the following demos for our custom form validation styles, optional server side classes, and browser defaults.
769
770 ### Custom styles
771
772 For custom Bootstrap form validation messages, you'll need to add the `novalidate` boolean attribute to your `<form>`. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript. Try to submit the form below; our JavaScript will intercept the submit button and relay feedback to you. When attempting to submit, you'll see the `:invalid` and `:valid` styles applied to your form controls.
773
774 Custom feedback styles apply custom colors, borders, focus styles, and background icons to better communicate feedback. Background icons for `<select>`s are only available with `.custom-select`, and not `.form-control`.
775
776 {% capture example %}
777 <form class="needs-validation" novalidate>
778   <div class="form-row">
779     <div class="col-md-4 mb-3">
780       <label for="validationCustom01">First name</label>
781       <input type="text" class="form-control" id="validationCustom01" placeholder="First name" value="Mark" required>
782       <div class="valid-feedback">
783         Looks good!
784       </div>
785     </div>
786     <div class="col-md-4 mb-3">
787       <label for="validationCustom02">Last name</label>
788       <input type="text" class="form-control" id="validationCustom02" placeholder="Last name" value="Otto" required>
789       <div class="valid-feedback">
790         Looks good!
791       </div>
792     </div>
793     <div class="col-md-4 mb-3">
794       <label for="validationCustomUsername">Username</label>
795       <div class="input-group">
796         <div class="input-group-prepend">
797           <span class="input-group-text" id="inputGroupPrepend">@</span>
798         </div>
799         <input type="text" class="form-control" id="validationCustomUsername" placeholder="Username" aria-describedby="inputGroupPrepend" required>
800         <div class="invalid-feedback">
801           Please choose a username.
802         </div>
803       </div>
804     </div>
805   </div>
806   <div class="form-row">
807     <div class="col-md-6 mb-3">
808       <label for="validationCustom03">City</label>
809       <input type="text" class="form-control" id="validationCustom03" placeholder="City" required>
810       <div class="invalid-feedback">
811         Please provide a valid city.
812       </div>
813     </div>
814     <div class="col-md-3 mb-3">
815       <label for="validationCustom04">State</label>
816       <input type="text" class="form-control" id="validationCustom04" placeholder="State" required>
817       <div class="invalid-feedback">
818         Please provide a valid state.
819       </div>
820     </div>
821     <div class="col-md-3 mb-3">
822       <label for="validationCustom05">Zip</label>
823       <input type="text" class="form-control" id="validationCustom05" placeholder="Zip" required>
824       <div class="invalid-feedback">
825         Please provide a valid zip.
826       </div>
827     </div>
828   </div>
829   <div class="form-group">
830     <div class="form-check">
831       <input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
832       <label class="form-check-label" for="invalidCheck">
833         Agree to terms and conditions
834       </label>
835       <div class="invalid-feedback">
836         You must agree before submitting.
837       </div>
838     </div>
839   </div>
840   <button class="btn btn-primary" type="submit">Submit form</button>
841 </form>
842
843 <script>
844 // Example starter JavaScript for disabling form submissions if there are invalid fields
845 (function() {
846   'use strict';
847   window.addEventListener('load', function() {
848     // Fetch all the forms we want to apply custom Bootstrap validation styles to
849     var forms = document.getElementsByClassName('needs-validation');
850     // Loop over them and prevent submission
851     var validation = Array.prototype.filter.call(forms, function(form) {
852       form.addEventListener('submit', function(event) {
853         if (form.checkValidity() === false) {
854           event.preventDefault();
855           event.stopPropagation();
856         }
857         form.classList.add('was-validated');
858       }, false);
859     });
860   }, false);
861 })();
862 </script>
863 {% endcapture %}
864 {% include example.html content=example %}
865
866 ### Browser defaults
867
868 Not interested in custom validation feedback messages or writing JavaScript to change form behaviors? All good, you can use the browser defaults. Try submitting the form below. Depending on your browser and OS, you'll see a slightly different style of feedback.
869
870 While these feedback styles cannot be styled with CSS, you can still customize the feedback text through JavaScript.
871
872 {% capture example %}
873 <form>
874   <div class="form-row">
875     <div class="col-md-4 mb-3">
876       <label for="validationDefault01">First name</label>
877       <input type="text" class="form-control" id="validationDefault01" placeholder="First name" value="Mark" required>
878     </div>
879     <div class="col-md-4 mb-3">
880       <label for="validationDefault02">Last name</label>
881       <input type="text" class="form-control" id="validationDefault02" placeholder="Last name" value="Otto" required>
882     </div>
883     <div class="col-md-4 mb-3">
884       <label for="validationDefaultUsername">Username</label>
885       <div class="input-group">
886         <div class="input-group-prepend">
887           <span class="input-group-text" id="inputGroupPrepend2">@</span>
888         </div>
889         <input type="text" class="form-control" id="validationDefaultUsername" placeholder="Username" aria-describedby="inputGroupPrepend2" required>
890       </div>
891     </div>
892   </div>
893   <div class="form-row">
894     <div class="col-md-6 mb-3">
895       <label for="validationDefault03">City</label>
896       <input type="text" class="form-control" id="validationDefault03" placeholder="City" required>
897     </div>
898     <div class="col-md-3 mb-3">
899       <label for="validationDefault04">State</label>
900       <input type="text" class="form-control" id="validationDefault04" placeholder="State" required>
901     </div>
902     <div class="col-md-3 mb-3">
903       <label for="validationDefault05">Zip</label>
904       <input type="text" class="form-control" id="validationDefault05" placeholder="Zip" required>
905     </div>
906   </div>
907   <div class="form-group">
908     <div class="form-check">
909       <input class="form-check-input" type="checkbox" value="" id="invalidCheck2" required>
910       <label class="form-check-label" for="invalidCheck2">
911         Agree to terms and conditions
912       </label>
913     </div>
914   </div>
915   <button class="btn btn-primary" type="submit">Submit form</button>
916 </form>
917 {% endcapture %}
918 {% include example.html content=example %}
919
920 ### Server side
921
922 We recommend using client-side validation, but in case you require server-side validation, you can indicate invalid and valid form fields with `.is-invalid` and `.is-valid`. Note that `.invalid-feedback` is also supported with these classes.
923
924 {% capture example %}
925 <form>
926   <div class="form-row">
927     <div class="col-md-4 mb-3">
928       <label for="validationServer01">First name</label>
929       <input type="text" class="form-control is-valid" id="validationServer01" placeholder="First name" value="Mark" required>
930       <div class="valid-feedback">
931         Looks good!
932       </div>
933     </div>
934     <div class="col-md-4 mb-3">
935       <label for="validationServer02">Last name</label>
936       <input type="text" class="form-control is-valid" id="validationServer02" placeholder="Last name" value="Otto" required>
937       <div class="valid-feedback">
938         Looks good!
939       </div>
940     </div>
941     <div class="col-md-4 mb-3">
942       <label for="validationServerUsername">Username</label>
943       <div class="input-group">
944         <div class="input-group-prepend">
945           <span class="input-group-text" id="inputGroupPrepend3">@</span>
946         </div>
947         <input type="text" class="form-control is-invalid" id="validationServerUsername" placeholder="Username" aria-describedby="inputGroupPrepend3" required>
948         <div class="invalid-feedback">
949           Please choose a username.
950         </div>
951       </div>
952     </div>
953   </div>
954   <div class="form-row">
955     <div class="col-md-6 mb-3">
956       <label for="validationServer03">City</label>
957       <input type="text" class="form-control is-invalid" id="validationServer03" placeholder="City" required>
958       <div class="invalid-feedback">
959         Please provide a valid city.
960       </div>
961     </div>
962     <div class="col-md-3 mb-3">
963       <label for="validationServer04">State</label>
964       <input type="text" class="form-control is-invalid" id="validationServer04" placeholder="State" required>
965       <div class="invalid-feedback">
966         Please provide a valid state.
967       </div>
968     </div>
969     <div class="col-md-3 mb-3">
970       <label for="validationServer05">Zip</label>
971       <input type="text" class="form-control is-invalid" id="validationServer05" placeholder="Zip" required>
972       <div class="invalid-feedback">
973         Please provide a valid zip.
974       </div>
975     </div>
976   </div>
977   <div class="form-group">
978     <div class="form-check">
979       <input class="form-check-input is-invalid" type="checkbox" value="" id="invalidCheck3" required>
980       <label class="form-check-label" for="invalidCheck3">
981         Agree to terms and conditions
982       </label>
983       <div class="invalid-feedback">
984         You must agree before submitting.
985       </div>
986     </div>
987   </div>
988   <button class="btn btn-primary" type="submit">Submit form</button>
989 </form>
990 {% endcapture %}
991 {% include example.html content=example %}
992
993 ### Supported elements
994
995 Our example forms show native textual `<input>`s above, but form validation styles are also available for `<textarea>`s and custom form controls.
996
997 {% capture example %}
998 <form class="was-validated">
999   <div class="mb-3">
1000     <label for="validationTextarea">Textarea</label>
1001     <textarea class="form-control is-invalid" id="validationTextarea" placeholder="Required example textarea" required></textarea>
1002     <div class="invalid-feedback">
1003       Please enter a message in the textarea.
1004     </div>
1005   </div>
1006
1007   <div class="custom-control custom-checkbox mb-3">
1008     <input type="checkbox" class="custom-control-input" id="customControlValidation1" required>
1009     <label class="custom-control-label" for="customControlValidation1">Check this custom checkbox</label>
1010     <div class="invalid-feedback">Example invalid feedback text</div>
1011   </div>
1012
1013   <div class="custom-control custom-radio">
1014     <input type="radio" class="custom-control-input" id="customControlValidation2" name="radio-stacked" required>
1015     <label class="custom-control-label" for="customControlValidation2">Toggle this custom radio</label>
1016   </div>
1017   <div class="custom-control custom-radio mb-3">
1018     <input type="radio" class="custom-control-input" id="customControlValidation3" name="radio-stacked" required>
1019     <label class="custom-control-label" for="customControlValidation3">Or toggle this other custom radio</label>
1020     <div class="invalid-feedback">More example invalid feedback text</div>
1021   </div>
1022
1023   <div class="form-group">
1024     <select class="custom-select" required>
1025       <option value="">Open this select menu</option>
1026       <option value="1">One</option>
1027       <option value="2">Two</option>
1028       <option value="3">Three</option>
1029     </select>
1030     <div class="invalid-feedback">Example invalid custom select feedback</div>
1031   </div>
1032
1033   <div class="custom-file">
1034     <input type="file" class="custom-file-input" id="validatedCustomFile" required>
1035     <label class="custom-file-label" for="validatedCustomFile">Choose file...</label>
1036     <div class="invalid-feedback">Example invalid custom file feedback</div>
1037   </div>
1038 </form>
1039 {% endcapture %}
1040 {% include example.html content=example %}
1041
1042 ### Tooltips
1043
1044 If your form layout allows it, you can swap the `.{valid|invalid}-feedback` classes for `.{valid|invalid}-tooltip` classes to display validation feedback in a styled tooltip. Be sure to have a parent with `position: relative` on it for tooltip positioning. In the example below, our column classes have this already, but your project may require an alternative setup.
1045
1046 {% capture example %}
1047 <form class="needs-validation" novalidate>
1048   <div class="form-row">
1049     <div class="col-md-4 mb-3">
1050       <label for="validationTooltip01">First name</label>
1051       <input type="text" class="form-control" id="validationTooltip01" placeholder="First name" value="Mark" required>
1052       <div class="valid-tooltip">
1053         Looks good!
1054       </div>
1055     </div>
1056     <div class="col-md-4 mb-3">
1057       <label for="validationTooltip02">Last name</label>
1058       <input type="text" class="form-control" id="validationTooltip02" placeholder="Last name" value="Otto" required>
1059       <div class="valid-tooltip">
1060         Looks good!
1061       </div>
1062     </div>
1063     <div class="col-md-4 mb-3">
1064       <label for="validationTooltipUsername">Username</label>
1065       <div class="input-group">
1066         <div class="input-group-prepend">
1067           <span class="input-group-text" id="validationTooltipUsernamePrepend">@</span>
1068         </div>
1069         <input type="text" class="form-control" id="validationTooltipUsername" placeholder="Username" aria-describedby="validationTooltipUsernamePrepend" required>
1070         <div class="invalid-tooltip">
1071           Please choose a unique and valid username.
1072         </div>
1073       </div>
1074     </div>
1075   </div>
1076   <div class="form-row">
1077     <div class="col-md-6 mb-3">
1078       <label for="validationTooltip03">City</label>
1079       <input type="text" class="form-control" id="validationTooltip03" placeholder="City" required>
1080       <div class="invalid-tooltip">
1081         Please provide a valid city.
1082       </div>
1083     </div>
1084     <div class="col-md-3 mb-3">
1085       <label for="validationTooltip04">State</label>
1086       <input type="text" class="form-control" id="validationTooltip04" placeholder="State" required>
1087       <div class="invalid-tooltip">
1088         Please provide a valid state.
1089       </div>
1090     </div>
1091     <div class="col-md-3 mb-3">
1092       <label for="validationTooltip05">Zip</label>
1093       <input type="text" class="form-control" id="validationTooltip05" placeholder="Zip" required>
1094       <div class="invalid-tooltip">
1095         Please provide a valid zip.
1096       </div>
1097     </div>
1098   </div>
1099   <button class="btn btn-primary" type="submit">Submit form</button>
1100 </form>
1101 {% endcapture %}
1102 {% include example.html content=example %}
1103
1104 ## Custom forms
1105
1106 For even more customization and cross browser consistency, use our completely custom form elements to replace the browser defaults. They're built on top of semantic and accessible markup, so they're solid replacements for any default form control.
1107
1108 ### Checkboxes and radios
1109
1110 Each checkbox and radio `<input>` and `<label>` pairing is wrapped in a `<div>` to create our custom control. Structurally, this is the same approach as our default `.form-check`.
1111
1112 We use the sibling selector (`~`) for all our `<input>` states—like `:checked`—to properly style our custom form indicator. When combined with the `.custom-control-label` class, we can also style the text for each item based on the `<input>`'s state.
1113
1114 We hide the default `<input>` with `opacity` and use the `.custom-control-label` to build a new custom form indicator in its place with `::before` and `::after`. Unfortunately we can't build a custom one from just the `<input>` because CSS's `content` doesn't work on that element.
1115
1116 In the checked states, we use **base64 embedded SVG icons** from [Open Iconic](https://github.com/iconic/open-iconic). This provides us the best control for styling and positioning across browsers and devices.
1117
1118 #### Checkboxes
1119
1120 {% capture example %}
1121 <div class="custom-control custom-checkbox">
1122   <input type="checkbox" class="custom-control-input" id="customCheck1">
1123   <label class="custom-control-label" for="customCheck1">Check this custom checkbox</label>
1124 </div>
1125 {% endcapture %}
1126 {% include example.html content=example %}
1127
1128 Custom checkboxes can also utilize the `:indeterminate` pseudo class when manually set via JavaScript (there is no available HTML attribute for specifying it).
1129
1130 <div class="bd-example bd-example-indeterminate">
1131   <div class="custom-control custom-checkbox">
1132     <input type="checkbox" class="custom-control-input" id="customCheck2">
1133     <label class="custom-control-label" for="customCheck2">Check this custom checkbox</label>
1134   </div>
1135 </div>
1136
1137 If you're using jQuery, something like this should suffice:
1138
1139 {% highlight js %}
1140 $('.your-checkbox').prop('indeterminate', true)
1141 {% endhighlight %}
1142
1143 #### Radios
1144
1145 {% capture example %}
1146 <div class="custom-control custom-radio">
1147   <input type="radio" id="customRadio1" name="customRadio" class="custom-control-input">
1148   <label class="custom-control-label" for="customRadio1">Toggle this custom radio</label>
1149 </div>
1150 <div class="custom-control custom-radio">
1151   <input type="radio" id="customRadio2" name="customRadio" class="custom-control-input">
1152   <label class="custom-control-label" for="customRadio2">Or toggle this other custom radio</label>
1153 </div>
1154 {% endcapture %}
1155 {% include example.html content=example %}
1156
1157 #### Inline
1158
1159 {% capture example %}
1160 <div class="custom-control custom-radio custom-control-inline">
1161   <input type="radio" id="customRadioInline1" name="customRadioInline1" class="custom-control-input">
1162   <label class="custom-control-label" for="customRadioInline1">Toggle this custom radio</label>
1163 </div>
1164 <div class="custom-control custom-radio custom-control-inline">
1165   <input type="radio" id="customRadioInline2" name="customRadioInline1" class="custom-control-input">
1166   <label class="custom-control-label" for="customRadioInline2">Or toggle this other custom radio</label>
1167 </div>
1168 {% endcapture %}
1169 {% include example.html content=example %}
1170
1171 #### Disabled
1172
1173 Custom checkboxes and radios can also be disabled. Add the `disabled` boolean attribute to the `<input>` and the custom indicator and label description will be automatically styled.
1174
1175 {% capture example %}
1176 <div class="custom-control custom-checkbox">
1177   <input type="checkbox" class="custom-control-input" id="customCheckDisabled1" disabled>
1178   <label class="custom-control-label" for="customCheckDisabled1">Check this custom checkbox</label>
1179 </div>
1180
1181 <div class="custom-control custom-radio">
1182   <input type="radio" name="radioDisabled" id="customRadioDisabled2" class="custom-control-input" disabled>
1183   <label class="custom-control-label" for="customRadioDisabled2">Toggle this custom radio</label>
1184 </div>
1185 {% endcapture %}
1186 {% include example.html content=example %}
1187
1188 ### Switches
1189
1190 A switch has the markup of a custom checkbox but uses the `.custom-switch` class to render a toggle switch. Switches also support the `disabled` attribute.
1191
1192 {% capture example %}
1193 <div class="custom-control custom-switch">
1194   <input type="checkbox" class="custom-control-input" id="customSwitch1">
1195   <label class="custom-control-label" for="customSwitch1">Toggle this switch element</label>
1196 </div>
1197 <div class="custom-control custom-switch">
1198   <input type="checkbox" class="custom-control-input" disabled id="customSwitch2">
1199   <label class="custom-control-label" for="customSwitch2">Disabled switch element</label>
1200 </div>
1201 {% endcapture %}
1202 {% include example.html content=example %}
1203
1204 ### Select menu
1205
1206 Custom `<select>` menus need only a custom class, `.custom-select` to trigger the custom styles. Custom styles are limited to the `<select>`'s initial appearance and cannot modify the `<option>`s due to browser limitations.
1207
1208 {% capture example %}
1209 <select class="custom-select">
1210   <option selected>Open this select menu</option>
1211   <option value="1">One</option>
1212   <option value="2">Two</option>
1213   <option value="3">Three</option>
1214 </select>
1215 {% endcapture %}
1216 {% include example.html content=example %}
1217
1218 You may also choose from small and large custom selects to match our similarly sized text inputs.
1219
1220 {% capture example %}
1221 <select class="custom-select custom-select-lg mb-3">
1222   <option selected>Open this select menu</option>
1223   <option value="1">One</option>
1224   <option value="2">Two</option>
1225   <option value="3">Three</option>
1226 </select>
1227
1228 <select class="custom-select custom-select-sm">
1229   <option selected>Open this select menu</option>
1230   <option value="1">One</option>
1231   <option value="2">Two</option>
1232   <option value="3">Three</option>
1233 </select>
1234 {% endcapture %}
1235 {% include example.html content=example %}
1236
1237 The `multiple` attribute is also supported:
1238
1239 {% capture example %}
1240 <select class="custom-select" multiple>
1241   <option selected>Open this select menu</option>
1242   <option value="1">One</option>
1243   <option value="2">Two</option>
1244   <option value="3">Three</option>
1245 </select>
1246 {% endcapture %}
1247 {% include example.html content=example %}
1248
1249 As is the `size` attribute:
1250
1251 {% capture example %}
1252 <select class="custom-select" size="3">
1253   <option selected>Open this select menu</option>
1254   <option value="1">One</option>
1255   <option value="2">Two</option>
1256   <option value="3">Three</option>
1257 </select>
1258 {% endcapture %}
1259 {% include example.html content=example %}
1260
1261 ### Range
1262
1263 Create custom `<input type="range">` controls with `.custom-range`. The track (the background) and thumb (the value) are both styled to appear the same across browsers. As only IE and Firefox support "filling" their track from the left or right of the thumb as a means to visually indicate progress, we do not currently support it.
1264
1265 {% capture example %}
1266 <label for="customRange1">Example range</label>
1267 <input type="range" class="custom-range" id="customRange1">
1268 {% endcapture %}
1269 {% include example.html content=example %}
1270
1271 Range inputs have implicit values for `min` and `max`—`0` and `100`, respectively. You may specify new values for those using the `min` and `max` attributes.
1272
1273 {% capture example %}
1274 <label for="customRange2">Example range</label>
1275 <input type="range" class="custom-range" min="0" max="5" id="customRange2">
1276 {% endcapture %}
1277 {% include example.html content=example %}
1278
1279 By default, range inputs "snap" to integer values. To change this, you can specify a `step` value. In the example below, we double the number of steps by using `step="0.5"`.
1280
1281 {% capture example %}
1282 <label for="customRange3">Example range</label>
1283 <input type="range" class="custom-range" min="0" max="5" step="0.5" id="customRange3">
1284 {% endcapture %}
1285 {% include example.html content=example %}
1286
1287 ### File browser
1288
1289 {% capture callout %}
1290 The recommended plugin to animate custom file input: [bs-custom-file-input](https://www.npmjs.com/package/bs-custom-file-input), that's what we are using currently here in our docs.
1291 {% endcapture %}
1292 {% include callout.html content=callout type="info" %}
1293
1294 The file input is the most gnarly of the bunch and requires additional JavaScript if you'd like to hook them up with functional *Choose file...* and selected file name text.
1295
1296 {% capture example %}
1297 <div class="custom-file">
1298   <input type="file" class="custom-file-input" id="customFile">
1299   <label class="custom-file-label" for="customFile">Choose file</label>
1300 </div>
1301 {% endcapture %}
1302 {% include example.html content=example %}
1303
1304 We hide the default file `<input>` via `opacity` and instead style the `<label>`. The button is generated and positioned with `::after`. Lastly, we declare a `width` and `height` on the `<input>` for proper spacing for surrounding content.
1305
1306 #### Translating or customizing the strings with SCSS
1307
1308 The [`:lang()` pseudo-class](https://developer.mozilla.org/en-US/docs/Web/CSS/:lang) is used to allow for translation of the "Browse" text into other languages. Override or add entries to the `$custom-file-text` Sass variable with the relevant [language tag](https://en.wikipedia.org/wiki/IETF_language_tag) and localized strings. The English strings can be customized the same way. For example, here's how one might add a Spanish translation (Spanish's language code is `es`):
1309
1310 {% highlight scss %}
1311 $custom-file-text: (
1312   en: "Browse",
1313   es: "Elegir"
1314 );
1315 {% endhighlight %}
1316
1317 Here's `lang(es)` in action on the custom file input for a Spanish translation:
1318
1319 {% capture example %}
1320 <div class="custom-file">
1321   <input type="file" class="custom-file-input" id="customFileLang" lang="es">
1322   <label class="custom-file-label" for="customFileLang">Seleccionar Archivo</label>
1323 </div>
1324 {% endcapture %}
1325 {% include example.html content=example %}
1326
1327 You'll need to set the language of your document (or subtree thereof) correctly in order for the correct text to be shown. This can be done using [the `lang` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang) on the `<html>` element or the [`Content-Language` HTTP header](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.12), among other methods.
1328
1329 #### Translating or customizing the strings with HTML
1330
1331 Bootstrap also provides a way to translate the "Browse" text in HTML with the `data-browse` attribute which can be added to the custom input label (example in Dutch):
1332
1333 {% capture example %}
1334 <div class="custom-file">
1335   <input type="file" class="custom-file-input" id="customFileLangHTML">
1336   <label class="custom-file-label" for="customFileLangHTML" data-browse="Bestand kiezen">Voeg je document toe</label>
1337 </div>
1338 {% endcapture %}
1339 {% include example.html content=example %}