forms.less 11.8 KB
Newer Older
1
2
3
//
// Forms
// --------------------------------------------------
4

5

Mark Otto's avatar
Mark Otto committed
6
7
8
// Normalize non-controls
//
// Restyle and baseline non-control form elements.
9
10
11
12
13

fieldset {
  padding: 0;
  margin: 0;
  border: 0;
14
15
16
17
  // Chrome and Firefox set a `min-width: -webkit-min-content;` on fieldsets,
  // so we reset that to ensure it behaves more like a standard block element.
  // See https://github.com/twbs/bootstrap/issues/12359.
  min-width: 0;
18
}
19

20
21
22
legend {
  display: block;
  width: 100%;
23
  padding: 0;
Mark Otto's avatar
Mark Otto committed
24
  margin-bottom: @line-height-computed;
25
  font-size: (@font-size-base * 1.5);
26
  line-height: inherit;
27
  color: @legend-color;
28
  border: 0;
29
  border-bottom: 1px solid @legend-border-color;
30
}
31

32
label {
33
  display: inline-block;
34
  margin-bottom: 5px;
35
  font-weight: bold;
36
}
37

38

Mark Otto's avatar
Mark Otto committed
39
// Normalize form controls
40
41
42
43
//
// While most of our form styles require extra classes, some basic normalization
// is required to ensure optimum display with or without those classes to better
// address browser inconsistencies.
44

45
46
47
48
49
// Override content-box in Normalize (* isn't specific enough)
input[type="search"] {
  .box-sizing(border-box);
}

Mark Otto's avatar
Mark Otto committed
50
// Position radios and checkboxes better
51
52
input[type="radio"],
input[type="checkbox"] {
53
  margin: 4px 0 0;
Chris Rebert's avatar
Chris Rebert committed
54
  margin-top: 1px \9; // IE8-9
Mark Otto's avatar
Mark Otto committed
55
  line-height: normal;
56
}
Mark Otto's avatar
Mark Otto committed
57

58
// Set the height of file controls to match text inputs
59
input[type="file"] {
60
  display: block;
Mark Otto's avatar
Mark Otto committed
61
}
62

63
64
65
66
67
68
// Make range inputs behave like textual form controls
input[type="range"] {
  display: block;
  width: 100%;
}

Mark Otto's avatar
Mark Otto committed
69
// Make multiple select elements height not fixed
70
71
select[multiple],
select[size] {
Mark Otto's avatar
Mark Otto committed
72
  height: auto;
Mark Otto's avatar
Mark Otto committed
73
74
}

75
// Focus for file, radio, and checkbox
76
77
78
79
80
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
  .tab-focus();
}
81

82
83
84
85
86
87
88
89
// Adjust output element
output {
  display: block;
  padding-top: (@padding-base-vertical + 1);
  font-size: @font-size-base;
  line-height: @line-height-base;
  color: @input-color;
}
90

91

Mark Otto's avatar
Mark Otto committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// Common form controls
//
// Shared size and type resets for form controls. Apply `.form-control` to any
// of the following form controls:
//
// select
// textarea
// input[type="text"]
// input[type="password"]
// input[type="datetime"]
// input[type="datetime-local"]
// input[type="date"]
// input[type="month"]
// input[type="time"]
// input[type="week"]
// input[type="number"]
// input[type="email"]
// input[type="url"]
// input[type="search"]
// input[type="tel"]
// input[type="color"]

.form-control {
  display: block;
  width: 100%;
  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
  padding: @padding-base-vertical @padding-base-horizontal;
  font-size: @font-size-base;
  line-height: @line-height-base;
121
  color: @input-color;
Mark Otto's avatar
Mark Otto committed
122
  background-color: @input-bg;
123
  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
Mark Otto's avatar
Mark Otto committed
124
125
126
127
128
  border: 1px solid @input-border;
  border-radius: @input-border-radius;
  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
  .transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s");

129
130
  // Customize the `:focus` state to imitate native WebKit styles.
  .form-control-focus();
Mark Otto's avatar
Mark Otto committed
131

132
133
134
  // Placeholder
  .placeholder();

Mark Otto's avatar
Mark Otto committed
135
  // Disabled and read-only inputs
136
137
138
139
  //
  // HTML5 says that controls under a fieldset > legend:first-child won't be
  // disabled if the fieldset is disabled. Due to implementation difficulty, we
  // don't honor that edge case; we style them as disabled anyway.
Mark Otto's avatar
Mark Otto committed
140
141
142
143
144
  &[disabled],
  &[readonly],
  fieldset[disabled] & {
    cursor: not-allowed;
    background-color: @input-bg-disabled;
145
    opacity: 1; // iOS fix for unreadable disabled content
Mark Otto's avatar
Mark Otto committed
146
147
148
149
150
151
152
153
  }

  // Reset height for `textarea`s
  textarea& {
    height: auto;
  }
}

154
155
156
157
158
159
160
161
162
163
164
165
166

// Search inputs in iOS
//
// This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.

input[type="search"] {
  -webkit-appearance: none;
}


167
168
169
// Special styles for iOS date input
//
// In Mobile Safari, date inputs require a pixel line-height that matches the
170
171
// given height of the input. Since this fucks up everything else, we have to
// appropriately reset it for Internet Explorer and the size variations.
172

173
174
input[type="date"] {
  line-height: @input-height-base;
175
176
177
178
179
180
181
182
183
  // IE8+ misaligns the text within date inputs, so we reset
  line-height: @line-height-base ~"\0";

  &.input-sm {
    line-height: @input-height-small;
  }
  &.input-lg {
    line-height: @input-height-large;
  }
184
185
}

Mark Otto's avatar
Mark Otto committed
186
187
188
189
190
191
192
193
194
195
196
197
198
199

// Form groups
//
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, use the predefined grid classes.

.form-group {
  margin-bottom: 15px;
}


// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.
200
201
202

.radio,
.checkbox {
203
  display: block;
Mark Otto's avatar
Mark Otto committed
204
  min-height: @line-height-computed; // clear the floating input if there is no label text
Mark Otto's avatar
Mark Otto committed
205
206
  margin-top: 10px;
  margin-bottom: 10px;
207
  
Mark Otto's avatar
Mark Otto committed
208
  label {
209
210
211
    // display: inline;
    padding-left: 20px;
    margin-bottom: 0;
Mark Otto's avatar
Mark Otto committed
212
    font-weight: normal;
213
    cursor: pointer;
Mark Otto's avatar
Mark Otto committed
214
  }
215
}
216
.radio input[type="radio"],
Mark Otto's avatar
Mark Otto committed
217
218
219
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
220
  float: left;
221
  margin-left: -20px;
222
}
Mark Otto's avatar
Mark Otto committed
223
224
.radio + .radio,
.checkbox + .checkbox {
Mark Otto's avatar
Mark Otto committed
225
  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing
Mark Otto's avatar
Mark Otto committed
226
}
227

228
// Radios and checkboxes on same line
Mark Otto's avatar
Mark Otto committed
229
230
.radio-inline,
.checkbox-inline {
231
  display: inline-block;
Mark Otto's avatar
Mark Otto committed
232
  padding-left: 20px;
233
  margin-bottom: 0;
234
  vertical-align: middle;
Mark Otto's avatar
Mark Otto committed
235
  font-weight: normal;
236
  cursor: pointer;
237
}
Mark Otto's avatar
Mark Otto committed
238
239
240
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
  margin-top: 0;
241
  margin-left: 10px; // space out consecutive inline controls
242
243
}

244
// Apply same disabled cursor tweak as for inputs
245
//
246
// Note: Neither radios nor checkboxes can be readonly.
247
248
input[type="radio"],
input[type="checkbox"],
249
250
251
252
253
254
255
256
257
.radio,
.radio-inline,
.checkbox,
.checkbox-inline {
  &[disabled],
  fieldset[disabled] & {
    cursor: not-allowed;
  }
}
258

Mark Otto's avatar
Mark Otto committed
259

Mark Otto's avatar
Mark Otto committed
260
// Form control sizing
Mark Otto's avatar
Mark Otto committed
261
262
263
264
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.

265
.input-sm {
266
  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
267
268
}

ggam's avatar
ggam committed
269
.input-lg {
270
  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
271
}
272

Mark Otto's avatar
Mark Otto committed
273

Mark Otto's avatar
Mark Otto committed
274
275
276
// Form control feedback states
//
// Apply contextual and semantic states to individual form controls.
277

278
279
280
281
282
283
284
285
.has-feedback {
  // Enable absolute positioning
  position: relative;

  // Ensure icons don't overlap text
  .form-control {
    padding-right: (@input-height-base * 1.25);
  }
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
}
// Feedback icon (requires .glyphicon classes)
.form-control-feedback {
  position: absolute;
  top: (@line-height-computed + 5); // Height of the `label` and its margin
  right: 0;
  display: block;
  width: @input-height-base;
  height: @input-height-base;
  line-height: @input-height-base;
  text-align: center;
}
.input-lg + .form-control-feedback {
  width: @input-height-large;
  height: @input-height-large;
  line-height: @input-height-large;
}
.input-sm + .form-control-feedback {
  width: @input-height-small;
  height: @input-height-small;
  line-height: @input-height-small;
307
308
309
}

// Feedback states
310
311
312
.has-success {
  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);
}
313
.has-warning {
314
  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);
315
}
316
.has-error {
317
  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);
318
}
319
320


321
322
323
324
325
326
327
328
329
330
// Static form control text
//
// Apply class to a `p` element to make any string of text align with labels in
// a horizontal form layout.

.form-control-static {
  margin-bottom: 0; // Remove default margin from `p`
}


Mark Otto's avatar
Mark Otto committed
331
332
333
334
// Help text
//
// Apply to any element you wish to create light text for placement immediately
// below a form control. Use for general help, formatting, or instructional text.
335

336
.help-block {
337
  display: block; // account for any element using help-block
Mark Otto's avatar
Mark Otto committed
338
339
340
  margin-top: 5px;
  margin-bottom: 10px;
  color: lighten(@text-color, 25%); // lighten the text some for contrast
Jacob Thornton's avatar
Jacob Thornton committed
341
}
342
343
344
345
346



// Inline forms
//
347
348
349
350
351
352
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
353
354
//
// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
355
356

.form-inline {
357

358
  // Kick in the inline
359
  @media (min-width: @screen-sm-min) {
360
    // Inline-block all the things for "inline"
361
    .form-group {
362
363
364
365
      display: inline-block;
      margin-bottom: 0;
      vertical-align: middle;
    }
366
367
368
369

    // In navbar-form, allow folks to *not* use `.form-group`
    .form-control {
      display: inline-block;
370
      width: auto; // Prevent labels from stacking above inputs in `.form-group`
371
      vertical-align: middle;
372
    }
Mark Otto's avatar
Mark Otto committed
373
374
375
376
377
378
379
380
381
382
383
384

    .input-group {
      display: inline-table;
      vertical-align: middle;

      .input-group-addon,
      .input-group-btn,
      .form-control {
        width: auto;
      }
    }

385
386
387
388
    // Input groups need that 100% width though
    .input-group > .form-control {
      width: 100%;
    }
389

390
391
392
    .control-label {
      margin-bottom: 0;
      vertical-align: middle;
393
394
    }

395
396
397
398
399
400
401
402
403
    // Remove default margin on radios/checkboxes that were used for stacking, and
    // then undo the floating of radios and checkboxes to match (which also avoids
    // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).
    .radio,
    .checkbox {
      display: inline-block;
      margin-top: 0;
      margin-bottom: 0;
      padding-left: 0;
404
      vertical-align: middle;
405
406
407
408
409
410
    }
    .radio input[type="radio"],
    .checkbox input[type="checkbox"] {
      float: none;
      margin-left: 0;
    }
411
412
413
414
415
416
417
418

    // Validation states
    //
    // Reposition the icon because it's now within a grid column and columns have
    // `position: relative;` on them. Also accounts for the grid gutter padding.
    .has-feedback .form-control-feedback {
      top: 0;
    }
419
420
421
422
423
424
425
426
427
428
  }
}


// Horizontal forms
//
// Horizontal forms are built on grid classes and allow you to create forms with
// labels on the left and inputs on the right.

.form-horizontal {
429

430
431
  // Consistent vertical alignment of radios and checkboxes
  //
432
  // Labels also get some reset styles, but that is scoped to a media query below.
433
434
435
436
437
438
439
440
  .radio,
  .checkbox,
  .radio-inline,
  .checkbox-inline {
    margin-top: 0;
    margin-bottom: 0;
    padding-top: (@padding-base-vertical + 1); // Default padding plus a border
  }
441
442
443
444
  // Account for padding we're adding to ensure the alignment and of help text
  // and other content below items
  .radio,
  .checkbox {
445
    min-height: (@line-height-computed + (@padding-base-vertical + 1));
446
  }
447
448

  // Make form groups behave like rows
449
450
451
452
  .form-group {
    .make-row();
  }

453
454
  .form-control-static {
    padding-top: (@padding-base-vertical + 1);
455
    padding-bottom: (@padding-base-vertical + 1);
456
457
  }

458
459
  // Reset spacing and right align labels, but scope to media queries so that
  // labels on narrow viewports stack the same as a default form example.
Zlatan Vasović's avatar
Zlatan Vasović committed
460
  @media (min-width: @screen-sm-min) {
461
462
    .control-label {
      text-align: right;
463
464
      margin-bottom: 0;
      padding-top: (@padding-base-vertical + 1); // Default padding plus a border
465
    }
466
  }
467
468
469
470
471
472
473
474
475

  // Validation states
  //
  // Reposition the icon because it's now within a grid column and columns have
  // `position: relative;` on them. Also accounts for the grid gutter padding.
  .has-feedback .form-control-feedback {
    top: 0;
    right: (@grid-gutter-width / 2);
  }
476
}