input-group.md 14.9 KB
Newer Older
Mark Otto's avatar
Mark Otto committed
1
---
Mark Otto's avatar
Mark Otto committed
2
layout: docs
Mark Otto's avatar
Mark Otto committed
3
title: Input group
Mark Otto's avatar
clarify    
Mark Otto committed
4
description: Easily extend form controls by adding text, buttons, or button groups on either side of textual inputs, custom selects, and custom file inputs.
5
group: components
Mark Otto's avatar
Mark Otto committed
6
toc: true
Mark Otto's avatar
Mark Otto committed
7
8
---

Mark Otto's avatar
Mark Otto committed
9
## Basic example
Mark Otto's avatar
Mark Otto committed
10

11
Place one add-on or button on either side of an input. You may also place one on both sides of an input. Remember to place `<label>`s outside the input group.
Mark Otto's avatar
Mark Otto committed
12

m5o's avatar
m5o committed
13
{% capture example %}
14
15
16
17
<div class="input-group mb-3">
  <div class="input-group-prepend">
    <span class="input-group-text" id="basic-addon1">@</span>
  </div>
18
  <input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="basic-addon1">
Mark Otto's avatar
Mark Otto committed
19
</div>
20
21

<div class="input-group mb-3">
22
  <input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="basic-addon2">
23
24
25
  <div class="input-group-append">
    <span class="input-group-text" id="basic-addon2">@example.com</span>
  </div>
Mark Otto's avatar
Mark Otto committed
26
</div>
27

Mark Otto's avatar
Mark Otto committed
28
<label for="basic-url">Your vanity URL</label>
29
30
31
32
<div class="input-group mb-3">
  <div class="input-group-prepend">
    <span class="input-group-text" id="basic-addon3">https://example.com/users/</span>
  </div>
Mark Otto's avatar
Mark Otto committed
33
34
  <input type="text" class="form-control" id="basic-url" aria-describedby="basic-addon3">
</div>
35
36
37
38
39

<div class="input-group mb-3">
  <div class="input-group-prepend">
    <span class="input-group-text">$</span>
  </div>
40
  <input type="text" class="form-control" aria-label="Amount (to the nearest dollar)">
41
42
43
  <div class="input-group-append">
    <span class="input-group-text">.00</span>
  </div>
44
</div>
Mark Otto's avatar
Mark Otto committed
45
46
47
48
49
50
51

<div class="input-group">
  <div class="input-group-prepend">
    <span class="input-group-text">With textarea</span>
  </div>
  <textarea class="form-control" aria-label="With textarea"></textarea>
</div>
m5o's avatar
m5o committed
52
53
{% endcapture %}
{% include example.html content=example %}
Mark Otto's avatar
Mark Otto committed
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
## Wrapping

Input groups wrap by default via `flex-wrap: wrap` in order to accommodate custom form field validation within an input group. You may disable this with `.flex-nowrap`.

{% capture example %}
<div class="input-group flex-nowrap">
  <div class="input-group-prepend">
    <span class="input-group-text" id="addon-wrapping">@</span>
  </div>
  <input type="text" class="form-control" placeholder="Username" aria-label="Username" aria-describedby="addon-wrapping">
</div>
{% endcapture %}
{% include example.html content=example %}

Mark Otto's avatar
Mark Otto committed
69
70
71
72
## Sizing

Add the relative form sizing classes to the `.input-group` itself and contents within will automatically resize—no need for repeating the form control size classes on each element.

73
74
**Sizing on the individual input group elements isn't supported.**

m5o's avatar
m5o committed
75
{% capture example %}
76
77
78
79
<div class="input-group input-group-sm mb-3">
  <div class="input-group-prepend">
    <span class="input-group-text" id="inputGroup-sizing-sm">Small</span>
  </div>
80
  <input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm">
81
82
83
84
85
86
</div>

<div class="input-group mb-3">
  <div class="input-group-prepend">
    <span class="input-group-text" id="inputGroup-sizing-default">Default</span>
  </div>
87
  <input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-default">
Mark Otto's avatar
Mark Otto committed
88
</div>
89
90
91
92
93

<div class="input-group input-group-lg">
  <div class="input-group-prepend">
    <span class="input-group-text" id="inputGroup-sizing-lg">Large</span>
  </div>
94
  <input type="text" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-lg">
Mark Otto's avatar
Mark Otto committed
95
</div>
m5o's avatar
m5o committed
96
97
{% endcapture %}
{% include example.html content=example %}
Mark Otto's avatar
Mark Otto committed
98

99
## Checkboxes and radios
Mark Otto's avatar
Mark Otto committed
100

Mark Otto's avatar
Mark Otto committed
101
Place any checkbox or radio option within an input group's addon instead of text.
Mark Otto's avatar
Mark Otto committed
102

m5o's avatar
m5o committed
103
{% capture example %}
104
105
106
107
<div class="input-group mb-3">
  <div class="input-group-prepend">
    <div class="input-group-text">
      <input type="checkbox" aria-label="Checkbox for following text input">
Mark Otto's avatar
Mark Otto committed
108
109
    </div>
  </div>
110
111
112
113
114
115
  <input type="text" class="form-control" aria-label="Text input with checkbox">
</div>

<div class="input-group">
  <div class="input-group-prepend">
    <div class="input-group-text">
116
      <input type="radio" aria-label="Radio button for following text input">
Mark Otto's avatar
Mark Otto committed
117
118
    </div>
  </div>
119
120
  <input type="text" class="form-control" aria-label="Text input with radio button">
</div>
m5o's avatar
m5o committed
121
122
{% endcapture %}
{% include example.html content=example %}
123
124
125
126
127

## Multiple inputs

While multiple `<input>`s are supported visually, validation styles are only available for input groups with a single `<input>`.

m5o's avatar
m5o committed
128
{% capture example %}
129
130
<div class="input-group">
  <div class="input-group-prepend">
131
    <span class="input-group-text">First and last name</span>
132
  </div>
133
134
  <input type="text" aria-label="First name" class="form-control">
  <input type="text" aria-label="Last name" class="form-control">
Mark Otto's avatar
Mark Otto committed
135
</div>
m5o's avatar
m5o committed
136
137
{% endcapture %}
{% include example.html content=example %}
Mark Otto's avatar
Mark Otto committed
138

139
140
141
142
## Multiple addons

Multiple add-ons are supported and can be mixed with checkbox and radio input versions.

m5o's avatar
m5o committed
143
{% capture example %}
144
145
146
147
<div class="input-group mb-3">
  <div class="input-group-prepend">
    <span class="input-group-text">$</span>
    <span class="input-group-text">0.00</span>
148
  </div>
149
  <input type="text" class="form-control" aria-label="Dollar amount (with dot and two decimal places)">
150
151
152
</div>

<div class="input-group">
153
  <input type="text" class="form-control" aria-label="Dollar amount (with dot and two decimal places)">
154
155
156
  <div class="input-group-append">
    <span class="input-group-text">$</span>
    <span class="input-group-text">0.00</span>
157
158
  </div>
</div>
m5o's avatar
m5o committed
159
160
{% endcapture %}
{% include example.html content=example %}
161

Mark Otto's avatar
Mark Otto committed
162
## Button addons
Mark Otto's avatar
Mark Otto committed
163

m5o's avatar
m5o committed
164
{% capture example %}
165
166
<div class="input-group mb-3">
  <div class="input-group-prepend">
167
    <button class="btn btn-outline-secondary" type="button" id="button-addon1">Button</button>
Mark Otto's avatar
Mark Otto committed
168
  </div>
169
  <input type="text" class="form-control" placeholder="" aria-label="Example text with button addon" aria-describedby="button-addon1">
170
171
172
</div>

<div class="input-group mb-3">
173
  <input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username" aria-describedby="button-addon2">
174
  <div class="input-group-append">
175
    <button class="btn btn-outline-secondary" type="button" id="button-addon2">Button</button>
Mark Otto's avatar
Mark Otto committed
176
177
  </div>
</div>
178
179

<div class="input-group mb-3">
180
  <div class="input-group-prepend" id="button-addon3">
181
182
183
    <button class="btn btn-outline-secondary" type="button">Button</button>
    <button class="btn btn-outline-secondary" type="button">Button</button>
  </div>
184
  <input type="text" class="form-control" placeholder="" aria-label="Example text with two button addons" aria-describedby="button-addon3">
185
186
187
</div>

<div class="input-group">
188
189
  <input type="text" class="form-control" placeholder="Recipient's username" aria-label="Recipient's username with two button addons" aria-describedby="button-addon4">
  <div class="input-group-append" id="button-addon4">
190
191
    <button class="btn btn-outline-secondary" type="button">Button</button>
    <button class="btn btn-outline-secondary" type="button">Button</button>
192
193
  </div>
</div>
m5o's avatar
m5o committed
194
195
{% endcapture %}
{% include example.html content=example %}
Mark Otto's avatar
Mark Otto committed
196

Mark Otto's avatar
Mark Otto committed
197
198
## Buttons with dropdowns

m5o's avatar
m5o committed
199
{% capture example %}
200
201
202
203
204
205
206
207
208
<div class="input-group mb-3">
  <div class="input-group-prepend">
    <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</button>
    <div class="dropdown-menu">
      <a class="dropdown-item" href="#">Action</a>
      <a class="dropdown-item" href="#">Another action</a>
      <a class="dropdown-item" href="#">Something else here</a>
      <div role="separator" class="dropdown-divider"></div>
      <a class="dropdown-item" href="#">Separated link</a>
Mark Otto's avatar
Mark Otto committed
209
210
    </div>
  </div>
211
212
213
214
215
216
217
218
219
220
221
222
223
  <input type="text" class="form-control" aria-label="Text input with dropdown button">
</div>

<div class="input-group">
  <input type="text" class="form-control" aria-label="Text input with dropdown button">
  <div class="input-group-append">
    <button class="btn btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown</button>
    <div class="dropdown-menu">
      <a class="dropdown-item" href="#">Action</a>
      <a class="dropdown-item" href="#">Another action</a>
      <a class="dropdown-item" href="#">Something else here</a>
      <div role="separator" class="dropdown-divider"></div>
      <a class="dropdown-item" href="#">Separated link</a>
Mark Otto's avatar
Mark Otto committed
224
    </div>
Mark Otto's avatar
Mark Otto committed
225
226
  </div>
</div>
m5o's avatar
m5o committed
227
228
{% endcapture %}
{% include example.html content=example %}
Mark Otto's avatar
Mark Otto committed
229

Mark Otto's avatar
Mark Otto committed
230
231
## Segmented buttons

m5o's avatar
m5o committed
232
{% capture example %}
233
234
235
236
237
238
239
240
241
242
243
244
<div class="input-group mb-3">
  <div class="input-group-prepend">
    <button type="button" class="btn btn-outline-secondary">Action</button>
    <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      <span class="sr-only">Toggle Dropdown</span>
    </button>
    <div class="dropdown-menu">
      <a class="dropdown-item" href="#">Action</a>
      <a class="dropdown-item" href="#">Another action</a>
      <a class="dropdown-item" href="#">Something else here</a>
      <div role="separator" class="dropdown-divider"></div>
      <a class="dropdown-item" href="#">Separated link</a>
Mark Otto's avatar
Mark Otto committed
245
246
    </div>
  </div>
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
  <input type="text" class="form-control" aria-label="Text input with segmented dropdown button">
</div>

<div class="input-group">
  <input type="text" class="form-control" aria-label="Text input with segmented dropdown button">
  <div class="input-group-append">
    <button type="button" class="btn btn-outline-secondary">Action</button>
    <button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      <span class="sr-only">Toggle Dropdown</span>
    </button>
    <div class="dropdown-menu">
      <a class="dropdown-item" href="#">Action</a>
      <a class="dropdown-item" href="#">Another action</a>
      <a class="dropdown-item" href="#">Something else here</a>
      <div role="separator" class="dropdown-divider"></div>
      <a class="dropdown-item" href="#">Separated link</a>
Mark Otto's avatar
Mark Otto committed
263
    </div>
Mark Otto's avatar
Mark Otto committed
264
265
  </div>
</div>
m5o's avatar
m5o committed
266
267
{% endcapture %}
{% include example.html content=example %}
268

269
270
271
272
273
274
## Custom forms

Input groups include support for custom selects and custom file inputs. Browser default versions of these are not supported.

### Custom select

m5o's avatar
m5o committed
275
{% capture example %}
276
<div class="input-group mb-3">
277
278
279
  <div class="input-group-prepend">
    <label class="input-group-text" for="inputGroupSelect01">Options</label>
  </div>
280
  <select class="custom-select" id="inputGroupSelect01">
281
282
283
284
285
286
287
288
    <option selected>Choose...</option>
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
</div>

<div class="input-group mb-3">
289
  <select class="custom-select" id="inputGroupSelect02">
290
291
292
293
294
    <option selected>Choose...</option>
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
295
296
297
  <div class="input-group-append">
    <label class="input-group-text" for="inputGroupSelect02">Options</label>
  </div>
298
299
300
</div>

<div class="input-group mb-3">
301
302
303
  <div class="input-group-prepend">
    <button class="btn btn-outline-secondary" type="button">Button</button>
  </div>
304
  <select class="custom-select" id="inputGroupSelect03" aria-label="Example select with button addon">
305
306
307
308
309
310
311
312
    <option selected>Choose...</option>
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
</div>

<div class="input-group">
313
  <select class="custom-select" id="inputGroupSelect04" aria-label="Example select with button addon">
314
315
316
317
318
    <option selected>Choose...</option>
    <option value="1">One</option>
    <option value="2">Two</option>
    <option value="3">Three</option>
  </select>
319
320
321
  <div class="input-group-append">
    <button class="btn btn-outline-secondary" type="button">Button</button>
  </div>
322
</div>
m5o's avatar
m5o committed
323
324
{% endcapture %}
{% include example.html content=example %}
325
326
327

### Custom file input

m5o's avatar
m5o committed
328
{% capture example %}
329
<div class="input-group mb-3">
330
  <div class="input-group-prepend">
331
    <span class="input-group-text" id="inputGroupFileAddon01">Upload</span>
332
  </div>
ysds's avatar
ysds committed
333
  <div class="custom-file">
334
    <input type="file" class="custom-file-input" id="inputGroupFile01" aria-describedby="inputGroupFileAddon01">
ysds's avatar
ysds committed
335
336
    <label class="custom-file-label" for="inputGroupFile01">Choose file</label>
  </div>
337
338
339
</div>

<div class="input-group mb-3">
ysds's avatar
ysds committed
340
341
  <div class="custom-file">
    <input type="file" class="custom-file-input" id="inputGroupFile02">
342
    <label class="custom-file-label" for="inputGroupFile02" aria-describedby="inputGroupFileAddon02">Choose file</label>
ysds's avatar
ysds committed
343
  </div>
344
  <div class="input-group-append">
345
    <span class="input-group-text" id="inputGroupFileAddon02">Upload</span>
346
  </div>
347
348
349
</div>

<div class="input-group mb-3">
350
  <div class="input-group-prepend">
351
    <button class="btn btn-outline-secondary" type="button" id="inputGroupFileAddon03">Button</button>
352
  </div>
ysds's avatar
ysds committed
353
  <div class="custom-file">
354
    <input type="file" class="custom-file-input" id="inputGroupFile03" aria-describedby="inputGroupFileAddon03">
ysds's avatar
ysds committed
355
356
    <label class="custom-file-label" for="inputGroupFile03">Choose file</label>
  </div>
357
358
359
</div>

<div class="input-group">
ysds's avatar
ysds committed
360
  <div class="custom-file">
361
    <input type="file" class="custom-file-input" id="inputGroupFile04" aria-describedby="inputGroupFileAddon04">
ysds's avatar
ysds committed
362
363
    <label class="custom-file-label" for="inputGroupFile04">Choose file</label>
  </div>
364
  <div class="input-group-append">
365
    <button class="btn btn-outline-secondary" type="button" id="inputGroupFileAddon04">Button</button>
366
  </div>
367
</div>
m5o's avatar
m5o committed
368
369
{% endcapture %}
{% include example.html content=example %}
370

371
372
## Accessibility

373
Ensure that all form controls have an appropriate accessible name so that their purpose can be conveyed to users of assistive technologies. The simplest way to achieve this is to use a `<label>` element, or—in the case of buttons—to include sufficiently descriptive text as part of the `<button>...</button>` content.
374

375
376
For situations where it's not possible to include a visible `<label>` or appropriate text content, there are alternative ways of still providing an accessible name, such as:

377
- `<label>` elements hidden using the `.sr-only` class
378
379
380
381
382
383
384
- Pointing to an existing element that can act as a label using `aria-labelledby`
- Providing a `title` attribute
- Explicitly setting the accessible name on an element using `aria-label`

If none of these are present, assistive technologies may resort to using the `placeholder` attribute as a fallback for the accessible name on `<input>` and `<textarea>` elements. The examples in this section provide a few suggested, case-specific approaches.

While using visually hidden content (`.sr-only`, `aria-label`, and even `placeholder` content, which disappears once a form field has content) will benefit assistive technology users, a lack of visible label text may still be problematic for certain users. Some form of visible label is generally the best approach, both for accessibility and usability.