forms.less 10.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
170
// Special styles for iOS date input
//
// In Mobile Safari, date inputs require a pixel line-height that matches the
// given height of the input.
171

172
173
174
175
input[type="date"] {
  line-height: @input-height-base;
}

Mark Otto's avatar
Mark Otto committed
176
177
178
179
180
181
182
183
184
185
186
187
188
189

// 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.
190
191
192

.radio,
.checkbox {
193
  display: block;
Mark Otto's avatar
Mark Otto committed
194
  min-height: @line-height-computed; // clear the floating input if there is no label text
Mark Otto's avatar
Mark Otto committed
195
196
  margin-top: 10px;
  margin-bottom: 10px;
197
  padding-left: 20px;
Mark Otto's avatar
Mark Otto committed
198
199
200
  label {
    display: inline;
    font-weight: normal;
201
    cursor: pointer;
Mark Otto's avatar
Mark Otto committed
202
  }
203
}
204
.radio input[type="radio"],
Mark Otto's avatar
Mark Otto committed
205
206
207
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
208
  float: left;
209
  margin-left: -20px;
210
}
Mark Otto's avatar
Mark Otto committed
211
212
.radio + .radio,
.checkbox + .checkbox {
Mark Otto's avatar
Mark Otto committed
213
  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing
Mark Otto's avatar
Mark Otto committed
214
}
215

216
// Radios and checkboxes on same line
Mark Otto's avatar
Mark Otto committed
217
218
.radio-inline,
.checkbox-inline {
219
  display: inline-block;
Mark Otto's avatar
Mark Otto committed
220
  padding-left: 20px;
221
  margin-bottom: 0;
222
  vertical-align: middle;
Mark Otto's avatar
Mark Otto committed
223
  font-weight: normal;
224
  cursor: pointer;
225
}
Mark Otto's avatar
Mark Otto committed
226
227
228
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
  margin-top: 0;
229
  margin-left: 10px; // space out consecutive inline controls
230
231
}

232
// Apply same disabled cursor tweak as for inputs
233
//
234
// Note: Neither radios nor checkboxes can be readonly.
235
236
input[type="radio"],
input[type="checkbox"],
237
238
239
240
241
242
243
244
245
.radio,
.radio-inline,
.checkbox,
.checkbox-inline {
  &[disabled],
  fieldset[disabled] & {
    cursor: not-allowed;
  }
}
246

Mark Otto's avatar
Mark Otto committed
247

Mark Otto's avatar
Mark Otto committed
248
// Form control sizing
Mark Otto's avatar
Mark Otto committed
249
250
251
252
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.

253
.input-sm {
254
  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
255
256
}

ggam's avatar
ggam committed
257
.input-lg {
258
  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
259
}
260

Mark Otto's avatar
Mark Otto committed
261

Mark Otto's avatar
Mark Otto committed
262
263
264
// Form control feedback states
//
// Apply contextual and semantic states to individual form controls.
265

266
267
268
269
270
271
272
273
274
275
276
277
.has-feedback {
  // Enable absolute positioning
  position: relative;

  // Ensure icons don't overlap text
  .form-control {
    padding-right: (@input-height-base * 1.25);
  }

  // Feedback icon (requires .glyphicon classes)
  .form-control-feedback {
    position: absolute;
Chris Rebert's avatar
Chris Rebert committed
278
    top: (@line-height-computed + 5); // Height of the `label` and its margin
279
280
281
282
283
284
285
286
287
288
    right: 0;
    display: block;
    width: @input-height-base;
    height: @input-height-base;
    line-height: @input-height-base;
    text-align: center;
  }
}

// Feedback states
289
290
291
.has-success {
  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);
}
292
.has-warning {
293
  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);
294
}
295
.has-error {
296
  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);
297
}
298
299


300
301
302
303
304
305
306
307
308
309
// 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
310
311
312
313
// 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.
314

315
.help-block {
316
  display: block; // account for any element using help-block
Mark Otto's avatar
Mark Otto committed
317
318
319
  margin-top: 5px;
  margin-bottom: 10px;
  color: lighten(@text-color, 25%); // lighten the text some for contrast
Jacob Thornton's avatar
Jacob Thornton committed
320
}
321
322
323
324
325



// Inline forms
//
326
327
328
329
330
331
// 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).
332
333
//
// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
334
335

.form-inline {
336

337
  // Kick in the inline
338
  @media (min-width: @screen-sm-min) {
339
    // Inline-block all the things for "inline"
340
    .form-group {
341
342
343
344
      display: inline-block;
      margin-bottom: 0;
      vertical-align: middle;
    }
345
346
347
348

    // In navbar-form, allow folks to *not* use `.form-group`
    .form-control {
      display: inline-block;
349
      width: auto; // Prevent labels from stacking above inputs in `.form-group`
350
      vertical-align: middle;
351
    }
352
353
354
355
    // Input groups need that 100% width though
    .input-group > .form-control {
      width: 100%;
    }
356

357
358
359
    .control-label {
      margin-bottom: 0;
      vertical-align: middle;
360
361
    }

362
363
364
365
366
367
368
369
370
    // 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;
371
      vertical-align: middle;
372
373
374
375
376
377
    }
    .radio input[type="radio"],
    .checkbox input[type="checkbox"] {
      float: none;
      margin-left: 0;
    }
378
379
380
381
382
383
384
385

    // 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;
    }
386
387
388
389
390
391
392
393
394
395
  }
}


// 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 {
396
397
398
399
400
401
402
403
404
405
406

  // Consistent vertical alignment of labels, radios, and checkboxes
  .control-label,
  .radio,
  .checkbox,
  .radio-inline,
  .checkbox-inline {
    margin-top: 0;
    margin-bottom: 0;
    padding-top: (@padding-base-vertical + 1); // Default padding plus a border
  }
407
408
409
410
  // Account for padding we're adding to ensure the alignment and of help text
  // and other content below items
  .radio,
  .checkbox {
411
    min-height: (@line-height-computed + (@padding-base-vertical + 1));
412
  }
413
414

  // Make form groups behave like rows
415
416
417
418
  .form-group {
    .make-row();
  }

419
420
  .form-control-static {
    padding-top: (@padding-base-vertical + 1);
421
    padding-bottom: (@padding-base-vertical + 1);
422
423
  }

424
  // Only right align form labels here when the columns stop stacking
Zlatan Vasović's avatar
Zlatan Vasović committed
425
  @media (min-width: @screen-sm-min) {
426
427
428
    .control-label {
      text-align: right;
    }
429
  }
430
431
432
433
434
435
436
437
438

  // 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);
  }
439
}