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

5

6
// Non-controls
Mark Otto's avatar
Mark Otto committed
7
// -------------------------
Jacob Thornton's avatar
Jacob Thornton committed
8
9

form {
10
  margin: 0 0 @line-height-base;
11
12
13
14
15
16
}

fieldset {
  padding: 0;
  margin: 0;
  border: 0;
17
}
18

19
20
21
legend {
  display: block;
  width: 100%;
22
  padding: 0;
23
24
25
  margin-bottom: @line-height-base;
  font-size: @font-size-base * 1.5;
  line-height: @line-height-base * 2;
26
  color: @grayDark;
27
  border: 0;
28
  border-bottom: 1px solid #e5e5e5;
29
}
30

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

37
38
39
// Form controls
// -------------------------

40
// Shared size and type resets
41
select,
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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"],
56
57
input[type="color"],
.uneditable-input {
58
  display: inline-block;
59
  .box-sizing(border-box); // Makes inputs behave like true block-level elements
60
  min-height: @input-height; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
61
  padding: 6px 9px;
62
63
64
  margin-bottom: @line-height-base / 2;
  font-size: @font-size-base;
  line-height: @line-height-base;
65
  color: @gray;
66
  vertical-align: middle;
67
68
69
  background-color: @input-background;
  border: 1px solid @input-border;
  border-radius: @input-border-radius;
70
71
  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
  .transition(~"border linear .2s, box-shadow linear .2s");
72
73
}

Mark Otto's avatar
Mark Otto committed
74
// Reset appearance properties for textual inputs and textarea
Mark Otto's avatar
Mark Otto committed
75
// Can't be on input[type=*] selectors or it's too specific
Mark Otto's avatar
Mark Otto committed
76
input,
Mark Otto's avatar
Mark Otto committed
77
select,
78
79
textarea,
.uneditable-input {
Mark Otto's avatar
Mark Otto committed
80
  width: 100%;
Mark Otto's avatar
Mark Otto committed
81
}
Mark Otto's avatar
Mark Otto committed
82

83
84
85
86
87
88
89
90
91
92
93
// Reset width of input images, buttons, radios, checkboxes
input[type="file"],
input[type="image"],
input[type="submit"],
input[type="reset"],
input[type="button"],
input[type="radio"],
input[type="checkbox"] {
  width: auto; // Override of generic input selector
}

94
95
96
97
// Reset height since textareas have rows
textarea {
  height: auto;
}
Mark Otto's avatar
Mark Otto committed
98

Mark Otto's avatar
Mark Otto committed
99
// Everything else
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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"],
114
115
input[type="color"],
.uneditable-input {
116
117
118
119
120
  // Focus state
  &:focus {
    border-color: rgba(82,168,236,.8);
    outline: 0;
    outline: thin dotted \9; /* IE6-9 */
121
    .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)");
122
  }
123
}
124

Mark Otto's avatar
Mark Otto committed
125
// Position radios and checkboxes better
126
127
input[type="radio"],
input[type="checkbox"] {
128
  margin: 4px 0 0;
129
  margin-top: 1px \9; /* IE8-9 */
Mark Otto's avatar
Mark Otto committed
130
  line-height: normal;
131
}
Mark Otto's avatar
Mark Otto committed
132

133
// Set the height of select and file controls to match text inputs
134
select,
135
input[type="file"] {
136
137
  height: @input-height; /* In IE7, the height of the select element cannot be changed by height, only font-size. TODO: Check if this is still needed when dropping IE7 support */
  line-height: @input-height;
Mark Otto's avatar
Mark Otto committed
138
}
139

Mark Otto's avatar
Mark Otto committed
140
// Make select elements obey height by applying a border
Mark Otto's avatar
Mark Otto committed
141
// TODO: See if this can be part of the above selector stack
Mark Otto's avatar
Mark Otto committed
142
select {
143
  border: 1px solid @input-border;
Mark Otto's avatar
Mark Otto committed
144
145
}

Mark Otto's avatar
Mark Otto committed
146
// Make multiple select elements height not fixed
147
148
select[multiple],
select[size] {
Mark Otto's avatar
Mark Otto committed
149
  height: auto;
Mark Otto's avatar
Mark Otto committed
150
151
}

152
153
154
155
156
157
158
// Focus for select, file, radio, and checkbox
select:focus,
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
  .tab-focus();
}
159

160

Mark Otto's avatar
Mark Otto committed
161
162
163
164
165
166
167
// Uneditable inputs
// -------------------------

// Make uneditable inputs look inactive
.uneditable-input,
.uneditable-textarea {
  color: @grayLight;
168
169
  background-color: darken(@input-background, 1%);
  border-color: @input-border;
Mark Otto's avatar
Mark Otto committed
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
  .box-shadow(inset 0 1px 2px rgba(0,0,0,.025));
  cursor: not-allowed;
}

// For text that needs to appear as an input but should not be an input
.uneditable-input {
  overflow: hidden; // prevent text from wrapping, but still cut it off like an input does
  white-space: nowrap;
}

// Make uneditable textareas behave like a textarea
.uneditable-textarea {
  width: auto;
  height: auto;
}


// Placeholder
// -------------------------

190
// Placeholder text gets special styles because when browsers invalidate entire lines if it doesn't understand a selector
Mark Otto's avatar
Mark Otto committed
191
192
193
194
195
input,
textarea {
  .placeholder();
}

196

197
198
199
200
201
202
// CHECKBOXES & RADIOS
// -------------------

// Indent the labels to position radios/checkboxes as hanging
.radio,
.checkbox {
203
  display: block;
204
  min-height: @line-height-base; // clear the floating input if there is no label text
205
  padding-left: 20px;
206
}
207
208
209
210
.radio label,
.checkbox label {
  font-weight: normal;
}
211
212
.radio input[type="radio"],
.checkbox input[type="checkbox"] {
213
  float: left;
214
  margin-left: -20px;
215
216
217
218
219
}

// Move the options list down to align with labels
.controls > .radio:first-child,
.controls > .checkbox:first-child {
220
  padding-top: 5px; // has to be padding because margin collaspes
221
222
}

223
// Radios and checkboxes on same line
224
// TODO v3: Convert .inline to .control-inline
225
226
227
.radio.inline,
.checkbox.inline {
  display: inline-block;
228
  padding-top: 5px;
229
  margin-bottom: 0;
230
  vertical-align: middle;
231
232
233
}
.radio.inline + .radio.inline,
.checkbox.inline + .checkbox.inline {
234
  margin-left: 10px; // space out consecutive inline controls
235
236
}

237
238


239
240
241
// INPUT SIZES
// -----------

242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
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"],
.uneditable-input {
  &.input-large {
260
    padding: @padding-large;
261
262
    padding-left: 14px;
    padding-right: 14px; // TODO: Resolve this override
263
264
    font-size: @font-size-large;
    border-radius: @border-radius-large;
265
266
  }
  &.input-small {
267
268
269
    padding: @padding-small;
    font-size: @font-size-small;
    border-radius: @border-radius-small;
270
271
  }
  &.input-mini {
272
273
274
    padding: @padding-mini;
    font-size: @font-size-mini;
    border-radius: @border-radius-small;
275
276
  }
}
277

Mark Otto's avatar
Mark Otto committed
278
279
280
281
282


// GRID SIZING FOR INPUTS
// ----------------------

283
// Grid style input sizes
284
285
286
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
Mark Otto's avatar
Mark Otto committed
287
288
289
290
.uneditable-input[class*="span"] {
  float: none;
  margin-left: 0;
  margin-right: 0;
291
}
Mark Otto's avatar
Mark Otto committed
292
293
294
295
296

.controls-row {
  #grid > .input(@gridColumnWidth, @gridGutterWidth, @gridRowWidth);
}

297
298
299
300
// Ensure input-prepend/append never wraps
.input-append input[class*="span"],
.input-append .uneditable-input[class*="span"],
.input-prepend input[class*="span"],
Mark Otto's avatar
Mark Otto committed
301
.input-prepend .uneditable-input[class*="span"] {
302
303
  display: inline-block;
}
304

305
306
307
308
309
310
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input[class*="span"] {
  height: 30px;
}
311
312
313
314
// Control row for multiple inputs per line
.controls-row {
  .clearfix(); // Clear the float from controls
}
315
316

// Float to collapse white-space for proper grid alignment
Mark Otto's avatar
Mark Otto committed
317
.controls-row [class*="span"] {
318
  float: left;
319
}
320
321
322
323
324
// Explicity set top padding on all checkboxes/radios, not just first-child
.controls-row .checkbox[class*="span"],
.controls-row .radio[class*="span"] {
  padding-top: 5px;
}
325
326


327

328
329
330

// DISABLED STATE
// --------------
331

332
333
334
335
336
337
338
// Disabled and read-only inputs
input[disabled],
select[disabled],
textarea[disabled],
input[readonly],
select[readonly],
textarea[readonly] {
Jacob Thornton's avatar
Jacob Thornton committed
339
  cursor: not-allowed;
340
  background-color: @input-background-disabled;
Jacob Thornton's avatar
Jacob Thornton committed
341
}
342
343
344
345
346
347
348
// Explicitly reset the colors here
input[type="radio"][disabled],
input[type="checkbox"][disabled],
input[type="radio"][readonly],
input[type="checkbox"][readonly] {
  background-color: transparent;
}
Jacob Thornton's avatar
Jacob Thornton committed
349

350
351


352

353
354
// FORM FIELD FEEDBACK STATES
// --------------------------
355

356
// Warning
357
.control-group.warning {
358
  .formFieldState(@warningText, @warningText, @warningBackground);
359
360
361
}
// Error
.control-group.error {
362
  .formFieldState(@errorText, @errorText, @errorBackground);
363
364
}
// Success
365
.control-group.success {
366
  .formFieldState(@successText, @successText, @successBackground);
367
}
368
369
370
371
// Success
.control-group.info {
  .formFieldState(@infoText, @infoText, @infoBackground);
}
372

373
374
// HTML5 invalid states
// Shares styles with the .control-group.error above
Mark Otto's avatar
Mark Otto committed
375
376
377
input:focus:invalid,
textarea:focus:invalid,
select:focus:invalid {
378
379
380
381
  color: #b94a48;
  border-color: #ee5f5b;
  &:focus {
    border-color: darken(#ee5f5b, 10%);
382
383
    @shadow: 0 0 6px lighten(#ee5f5b, 20%);
    .box-shadow(@shadow);
384
385
386
  }
}

387
388
389
390
391
392


// FORM ACTIONS
// ------------

.form-actions {
393
394
395
  padding: (@line-height-base - 1) 20px @line-height-base;
  margin-top: @line-height-base;
  margin-bottom: @line-height-base;
396
  background-color: @form-actions-background;
397
  border-top: 1px solid #e5e5e5;
398
  .clearfix(); // Adding clearfix to allow for .pull-right button containers
Jacob Thornton's avatar
Jacob Thornton committed
399
400
}

401
402


403
404
405
// HELP TEXT
// ---------

Mark Otto's avatar
Mark Otto committed
406
407
.help-block,
.help-inline {
Mark Otto's avatar
Mark Otto committed
408
  color: lighten(@text-color, 25%); // lighten the text some for contrast
Mark Otto's avatar
Mark Otto committed
409
410
}

411
.help-block {
412
  display: block; // account for any element using help-block
413
  margin-bottom: @line-height-base / 2;
Jacob Thornton's avatar
Jacob Thornton committed
414
}
415

Jacob Thornton's avatar
Jacob Thornton committed
416
.help-inline {
417
418
  display: inline-block;
  vertical-align: middle;
419
  padding-left: 5px;
Jacob Thornton's avatar
Jacob Thornton committed
420
}
421

422

423

424
425
// INPUT GROUPS
// ------------
426

Jacob Thornton's avatar
Jacob Thornton committed
427
// Allow us to put symbols and text within the input field for a cleaner look
428
429
.input-append,
.input-prepend {
430
  margin-bottom: 5px;
431
  font-size: 0; // white space collapse hack
432
  white-space: nowrap; // Prevent span and input from separating
Mark Otto's avatar
Mark Otto committed
433

434
435
436
437
438
  // Reset the white space collapse hack
  input,
  select,
  .uneditable-input,
  .dropdown-menu {
439
    font-size: @font-size-base;
440
441
  }

442
  input,
443
  select,
444
  .uneditable-input {
445
    position: relative; // placed here by default so that on :focus we can place the input above the .add-on for full border and box-shadow goodness
Mark Otto's avatar
Mark Otto committed
446
447
    float: none; // Undo the float from grid sizing
    margin: 0; // Prevent bottom margin from screwing up alignment in stacked forms
448
    font-size: @font-size-base;
449
    vertical-align: top;
450
    border-radius: 0 @input-border-radius @input-border-radius 0;
451
    // Make input on top when focused so blue border and shadow always show
452
453
454
    &:focus {
      z-index: 2;
    }
Jacob Thornton's avatar
Jacob Thornton committed
455
  }
Mark Otto's avatar
Mark Otto committed
456
457
458
459
460
  input[class*="span"],
  select[class*="span"],
  .uneditable-input[class*="span"] {
    margin: 0;
  }
Jacob Thornton's avatar
Jacob Thornton committed
461
  .add-on {
462
    display: inline-block;
Jacob Thornton's avatar
Jacob Thornton committed
463
    width: auto;
464
    height: @line-height-base;
Jacob Thornton's avatar
Jacob Thornton committed
465
    min-width: 16px;
466
    padding: 6px;
467
    font-size: @font-size-base;
Jacob Thornton's avatar
Jacob Thornton committed
468
    font-weight: normal;
469
    line-height: @line-height-base;
Jacob Thornton's avatar
Jacob Thornton committed
470
    text-align: center;
471
    text-shadow: 0 1px 0 #fff;
472
    background-color: @grayLighter;
473
    border: 1px solid #ccc;
474
475
  }
  .add-on,
476
477
  .btn,
  .btn-group > .dropdown-toggle {
478
    vertical-align: top;
479
    border-radius: 0;
Jacob Thornton's avatar
Jacob Thornton committed
480
481
  }
  .active {
482
483
    background-color: @successBackground;
    border-color: @successText;
Jacob Thornton's avatar
Jacob Thornton committed
484
485
  }
}
486

487
.input-prepend {
488
489
  .add-on,
  .btn {
490
491
    margin-right: -1px;
  }
492
493
  .add-on:first-child,
  .btn:first-child {
494
    // FYI, `.btn:first-child` accounts for a button group that's prepended
495
    border-radius: @input-border-radius 0 0 @input-border-radius;
496
  }
497
}
498

Mark Otto's avatar
Mark Otto committed
499
.input-append {
500
  input,
501
  select,
502
  .uneditable-input {
503
    border-radius: @input-border-radius 0 0 @input-border-radius;
504
    + .btn-group .btn,
505
    + .btn-group .btn:last-child {
506
      border-radius: 0 @input-border-radius @input-border-radius 0;
507
    }
Jacob Thornton's avatar
Jacob Thornton committed
508
  }
509
  .add-on,
510
511
  .btn,
  .btn-group {
512
513
    margin-left: -1px;
  }
514
  .add-on:last-child,
515
516
  .btn:last-child,
  .btn-group:last-child > .dropdown-toggle {
517
    border-radius: 0 @input-border-radius @input-border-radius 0;
518
519
  }
}
520

521
522
523
524
525
// Remove all border-radius for inputs with both prepend and append
.input-prepend.input-append {
  input,
  select,
  .uneditable-input {
526
    border-radius: 0;
527
    + .btn-group .btn {
528
      border-radius: 0 @input-border-radius @input-border-radius 0;
529
    }
530
  }
531
532
  .add-on:first-child,
  .btn:first-child {
533
    margin-right: -1px;
534
    border-radius: @input-border-radius 0 0 @input-border-radius;
535
  }
536
537
  .add-on:last-child,
  .btn:last-child {
538
    margin-left: -1px;
539
    border-radius: 0 @input-border-radius @input-border-radius 0;
Jacob Thornton's avatar
Jacob Thornton committed
540
  }
541
542
543
  .btn-group:first-child {
    margin-left: 0;
  }
Jacob Thornton's avatar
Jacob Thornton committed
544
545
}

546

547

548

549
550
551
// SEARCH FORM
// -----------

552
input.search-query {
553
  padding-right: 14px;
554
  padding-right: 4px \9;
Jacob Thornton's avatar
Jacob Thornton committed
555
  padding-left: 14px;
556
  padding-left: 4px \9; /* IE8 doesn't have border radius, so don't indent the padding */
557
  margin-bottom: 0; // Remove the default margin on all inputs
558
  border-radius: @input-border-radius-search;
559
560
}

561
562
563
/* Allow for input prepend/append in search forms */
.form-search .input-append .search-query,
.form-search .input-prepend .search-query {
564
  border-radius: 0; // Override due to specificity
565
566
}
.form-search .input-append .search-query {
567
  border-radius: @input-border-radius-search 0 0 @input-border-radius-search;
568
569
}
.form-search .input-append .btn {
570
  border-radius: 0 @input-border-radius-search @input-border-radius-search 0;
571
572
}
.form-search .input-prepend .search-query {
573
  border-radius: 0 @input-border-radius-search @input-border-radius-search 0;
574
575
}
.form-search .input-prepend .btn {
576
  border-radius: @input-border-radius-search 0 0 @input-border-radius-search;
577
578
579
}


580
581


582
583
584
585
// HORIZONTAL & VERTICAL FORMS
// ---------------------------

// Common properties
586
587
// -----------------

588
589
590
.form-search,
.form-inline,
.form-horizontal {
591
592
593
  input,
  textarea,
  select,
594
  .help-inline,
595
596
597
  .uneditable-input,
  .input-prepend,
  .input-append {
598
599
    display: inline-block;
    margin-bottom: 0;
600
    vertical-align: middle;
601
  }
602
603
604
605
  // Re-hide hidden elements due to specifity
  .hide {
    display: none;
  }
606
}
607
.form-search label,
608
609
610
.form-inline label,
.form-search .btn-group,
.form-inline .btn-group {
611
612
  display: inline-block;
}
613
614
615
616
617
618
// Remove margin for input-prepend/-append
.form-search .input-append,
.form-inline .input-append,
.form-search .input-prepend,
.form-inline .input-prepend {
  margin-bottom: 0;
619
}
620
// Inline checkbox/radio labels (remove padding on left)
Mark Otto's avatar
Mark Otto committed
621
622
.form-search .radio,
.form-search .checkbox,
623
.form-inline .radio,
Mark Otto's avatar
Mark Otto committed
624
.form-inline .checkbox {
625
  display: inline-block;
626
  padding-left: 0;
627
628
629
630
  label {
    margin-bottom: 0;
    vertical-align: middle;
  }
Mark Otto's avatar
Mark Otto committed
631
}
632
633
634
635
636
637
638
// Remove float and margin, set to inline-block
.form-search .radio input[type="radio"],
.form-search .checkbox input[type="checkbox"],
.form-inline .radio input[type="radio"],
.form-inline .checkbox input[type="checkbox"] {
  float: left;
  margin-right: 3px;
Jacob Thornton's avatar
Jacob Thornton committed
639
  margin-left: 0;
640
641
}

642

643
644
// Margin to space out fieldsets
.control-group {
645
  margin-bottom: @line-height-base / 2;
Jacob Thornton's avatar
Jacob Thornton committed
646
}
647

648
649
// Legend collapses margin, so next element is responsible for spacing
legend + .control-group {
650
  margin-top: @line-height-base;
651
652
653
  -webkit-margin-top-collapse: separate;
}

654
655
656
// Horizontal-specific styles
// --------------------------

657
.form-horizontal {
Mark Otto's avatar
Mark Otto committed
658
  // Increase spacing between groups
659
  .control-group {
660
    margin-bottom: @line-height-base;
661
    .clearfix();
662
  }
663
  // Float the labels left
664
  .control-label {
665
    float: left;
Mark Otto's avatar
Mark Otto committed
666
    width: @component-offset-horizontal - 20;
667
668
669
670
671
    padding-top: 5px;
    text-align: right;
  }
  // Move over all input controls and content
  .controls {
Mark Otto's avatar
Mark Otto committed
672
    margin-left: @component-offset-horizontal;
673
  }
Mark Otto's avatar
Mark Otto committed
674
675
676
677
  // Remove bottom margin on block level help text since that's accounted for on .control-group
  .help-block {
    margin-bottom: 0;
  }
678
679
680
  // And apply it only to .help-block instances that follow a form control
  input,
  select,
681
  textarea,
682
683
684
  .uneditable-input,
  .input-prepend,
  .input-append {
685
    + .help-block {
686
      margin-top: @line-height-base / 2;
687
688
    }
  }
689
690
  // Move over buttons in .form-actions to align with .controls
  .form-actions {
Mark Otto's avatar
Mark Otto committed
691
    padding-left: @component-offset-horizontal;
692
  }
693
}