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

5

6
7
// GENERAL STYLES
// --------------
Jacob Thornton's avatar
Jacob Thornton committed
8

9
// Make all forms have space below them
Jacob Thornton's avatar
Jacob Thornton committed
10
form {
11
12
13
14
15
16
17
  margin: 0 0 @baseLineHeight;
}

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

20
// Groups of fields with labels on top (legends)
21
22
23
legend {
  display: block;
  width: 100%;
24
  padding: 0;
25
  margin-bottom: @baseLineHeight;
26
27
  font-size: @baseFontSize * 1.5;
  line-height: @baseLineHeight * 2;
28
  color: @grayDark;
29
  border: 0;
30
  border-bottom: 1px solid #e5e5e5;
Mark Otto's avatar
Mark Otto committed
31
32
33
34
35
36

  // Small
  small {
    font-size: @baseLineHeight * .75;
    color: @grayLight;
  }
37
}
38

39
40
41
// Set font for forms
label,
input,
42
button,
43
44
select,
textarea {
45
46
47
48
49
50
  #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here
}
input,
button,
select,
textarea {
51
  font-family: @baseFontFamily; // And only set font-family here for those that need it (note the missing label element)
52
}
53

54
// Identify controls by their labels
55
label {
56
57
  display: block;
  margin-bottom: 5px;
58
}
59

60
61
62
// Form controls
// -------------------------

63
// Shared size and type resets
64
select,
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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"],
79
80
input[type="color"],
.uneditable-input {
81
  display: inline-block;
82
83
84
85
  .box-sizing(border-box); // Makes inputs behave like true block-level elements
  min-height: @inputHeight; // Make inputs at least the height of their button counterpart (base line-height + padding + border)
  padding: 6px 9px;
  margin-bottom: @baseLineHeight / 2;
86
87
  font-size: @baseFontSize;
  line-height: @baseLineHeight;
88
  color: @gray;
89
  vertical-align: middle;
90
91
  background-color: @inputBackground;
  border-radius: @inputBorderRadius;
92
93
}

Mark Otto's avatar
Mark Otto committed
94
95
96
// Reset appearance properties for textual inputs and textarea
// Declare width for legacy (can't be on input[type=*] selectors or it's too specific)
input,
97
98
textarea,
.uneditable-input {
99
  width: 220px;
Mark Otto's avatar
Mark Otto committed
100
}
101
102
103
104
// Reset height since textareas have rows
textarea {
  height: auto;
}
Mark Otto's avatar
Mark Otto committed
105
// Everything else
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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"],
120
121
input[type="color"],
.uneditable-input {
122
  border: 1px solid @inputBorder;
123
  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
124
  .transition(~"border linear .2s, box-shadow linear .2s");
125
126
127
128
129
130

  // Focus state
  &:focus {
    border-color: rgba(82,168,236,.8);
    outline: 0;
    outline: thin dotted \9; /* IE6-9 */
131
    .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)");
132
  }
133
}
134

Mark Otto's avatar
Mark Otto committed
135
// Position radios and checkboxes better
136
137
input[type="radio"],
input[type="checkbox"] {
138
  margin: 4px 0 0;
139
  margin-top: 1px \9; /* IE8-9 */
Mark Otto's avatar
Mark Otto committed
140
  line-height: normal;
141
}
Mark Otto's avatar
Mark Otto committed
142

143
// Reset width of input images, buttons, radios, checkboxes
144
input[type="file"],
145
input[type="image"],
146
input[type="submit"],
Mark Otto's avatar
Mark Otto committed
147
148
149
150
151
input[type="reset"],
input[type="button"],
input[type="radio"],
input[type="checkbox"] {
  width: auto; // Override of generic input selector
152
153
}

154
// Set the height of select and file controls to match text inputs
155
select,
156
input[type="file"] {
157
  height: @inputHeight; /* 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 */
158
  line-height: @inputHeight;
Mark Otto's avatar
Mark Otto committed
159
}
160

Mark Otto's avatar
Mark Otto committed
161
162
163
// Make select elements obey height by applying a border
select {
  width: 220px; // default input width + 10px of padding that doesn't get applied
164
  border: 1px solid @inputBorder;
Mark Otto's avatar
Mark Otto committed
165
166
}

Mark Otto's avatar
Mark Otto committed
167
// Make multiple select elements height not fixed
168
169
select[multiple],
select[size] {
Mark Otto's avatar
Mark Otto committed
170
  height: auto;
Mark Otto's avatar
Mark Otto committed
171
172
}

173
174
175
176
177
178
179
// Focus for select, file, radio, and checkbox
select:focus,
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
  .tab-focus();
}
180

181

Mark Otto's avatar
Mark Otto committed
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// Uneditable inputs
// -------------------------

// Make uneditable inputs look inactive
.uneditable-input,
.uneditable-textarea {
  color: @grayLight;
  background-color: darken(@inputBackground, 1%);
  border-color: @inputBorder;
  .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
// -------------------------

211
// 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
212
213
214
215
216
input,
textarea {
  .placeholder();
}

217

218
219
220
221
222
223
// CHECKBOXES & RADIOS
// -------------------

// Indent the labels to position radios/checkboxes as hanging
.radio,
.checkbox {
224
225
  min-height: @baseLineHeight; // clear the floating input if there is no label text
  padding-left: 20px;
226
}
227
228
.radio input[type="radio"],
.checkbox input[type="checkbox"] {
229
  float: left;
230
  margin-left: -20px;
231
232
233
234
235
}

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

239
// Radios and checkboxes on same line
240
// TODO v3: Convert .inline to .control-inline
241
242
243
.radio.inline,
.checkbox.inline {
  display: inline-block;
244
  padding-top: 5px;
245
  margin-bottom: 0;
246
  vertical-align: middle;
247
248
249
}
.radio.inline + .radio.inline,
.checkbox.inline + .checkbox.inline {
250
  margin-left: 10px; // space out consecutive inline controls
251
252
}

253
254


255
256
257
// INPUT SIZES
// -----------

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
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 {
    padding: @paddingLarge;
    padding-left: 14px;
    padding-right: 14px; // TODO: Resolve this override
    font-size: @fontSizeLarge;
280
    border-radius: @borderRadiusLarge;
281
282
283
284
  }
  &.input-small {
    padding: @paddingSmall;
    font-size: @fontSizeSmall;
285
    border-radius: @borderRadiusSmall;
286
287
288
289
  }
  &.input-mini {
    padding: @paddingMini;
    font-size: @fontSizeMini;
290
    border-radius: @borderRadiusSmall;
291
292
  }
}
293

Mark Otto's avatar
Mark Otto committed
294
295
296
297
298


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

299
// Grid style input sizes
300
301
302
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
Mark Otto's avatar
Mark Otto committed
303
304
305
306
.uneditable-input[class*="span"] {
  float: none;
  margin-left: 0;
  margin-right: 0;
307
}
Mark Otto's avatar
Mark Otto committed
308
309
310
311
312

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

313
314
315
316
// 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
317
.input-prepend .uneditable-input[class*="span"] {
318
319
  display: inline-block;
}
320

321
322
323
324
325
326
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input[class*="span"] {
  height: 30px;
}
327
328
329
330
// Control row for multiple inputs per line
.controls-row {
  .clearfix(); // Clear the float from controls
}
331
332

// Float to collapse white-space for proper grid alignment
Mark Otto's avatar
Mark Otto committed
333
.controls-row [class*="span"] {
334
  float: left;
335
}
336
337
338
339
340
// 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;
}
341
342


343

344
345
346

// DISABLED STATE
// --------------
347

348
349
350
351
352
353
354
// Disabled and read-only inputs
input[disabled],
select[disabled],
textarea[disabled],
input[readonly],
select[readonly],
textarea[readonly] {
Jacob Thornton's avatar
Jacob Thornton committed
355
  cursor: not-allowed;
356
  background-color: @inputDisabledBackground;
Jacob Thornton's avatar
Jacob Thornton committed
357
}
358
359
360
361
362
363
364
// 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
365

366
367


368

369
370
// FORM FIELD FEEDBACK STATES
// --------------------------
371

372
// Warning
373
.control-group.warning {
374
  .formFieldState(@warningText, @warningText, @warningBackground);
375
376
377
}
// Error
.control-group.error {
378
  .formFieldState(@errorText, @errorText, @errorBackground);
379
380
}
// Success
381
.control-group.success {
382
  .formFieldState(@successText, @successText, @successBackground);
383
}
384
385
386
387
// Success
.control-group.info {
  .formFieldState(@infoText, @infoText, @infoBackground);
}
388

389
390
// HTML5 invalid states
// Shares styles with the .control-group.error above
Mark Otto's avatar
Mark Otto committed
391
392
393
input:focus:invalid,
textarea:focus:invalid,
select:focus:invalid {
394
395
396
397
  color: #b94a48;
  border-color: #ee5f5b;
  &:focus {
    border-color: darken(#ee5f5b, 10%);
398
399
    @shadow: 0 0 6px lighten(#ee5f5b, 20%);
    .box-shadow(@shadow);
400
401
402
  }
}

403
404
405
406
407
408


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

.form-actions {
409
410
411
  padding: (@baseLineHeight - 1) 20px @baseLineHeight;
  margin-top: @baseLineHeight;
  margin-bottom: @baseLineHeight;
412
  background-color: @formActionsBackground;
413
  border-top: 1px solid #e5e5e5;
414
  .clearfix(); // Adding clearfix to allow for .pull-right button containers
Jacob Thornton's avatar
Jacob Thornton committed
415
416
}

417
418


419
420
421
// HELP TEXT
// ---------

Mark Otto's avatar
Mark Otto committed
422
423
.help-block,
.help-inline {
424
  color: lighten(@textColor, 15%); // lighten the text some for contrast
Mark Otto's avatar
Mark Otto committed
425
426
}

427
.help-block {
428
  display: block; // account for any element using help-block
Mark Otto's avatar
Mark Otto committed
429
  margin-bottom: @baseLineHeight / 2;
Jacob Thornton's avatar
Jacob Thornton committed
430
}
431

Jacob Thornton's avatar
Jacob Thornton committed
432
.help-inline {
433
434
  display: inline-block;
  vertical-align: middle;
435
  padding-left: 5px;
Jacob Thornton's avatar
Jacob Thornton committed
436
}
437

438

439

440
441
// INPUT GROUPS
// ------------
442

Jacob Thornton's avatar
Jacob Thornton committed
443
// Allow us to put symbols and text within the input field for a cleaner look
444
445
.input-append,
.input-prepend {
446
  margin-bottom: 5px;
447
  font-size: 0; // white space collapse hack
448
  white-space: nowrap; // Prevent span and input from separating
Mark Otto's avatar
Mark Otto committed
449

450
451
452
453
454
455
456
457
  // Reset the white space collapse hack
  input,
  select,
  .uneditable-input,
  .dropdown-menu {
    font-size: @baseFontSize;
  }

458
  input,
459
  select,
460
  .uneditable-input {
461
    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
462
463
    float: none; // Undo the float from grid sizing
    margin: 0; // Prevent bottom margin from screwing up alignment in stacked forms
464
    font-size: @baseFontSize;
465
    vertical-align: top;
466
    border-radius: 0 @inputBorderRadius @inputBorderRadius 0;
467
    // Make input on top when focused so blue border and shadow always show
468
469
470
    &:focus {
      z-index: 2;
    }
Jacob Thornton's avatar
Jacob Thornton committed
471
  }
Mark Otto's avatar
Mark Otto committed
472
473
474
475
476
  input[class*="span"],
  select[class*="span"],
  .uneditable-input[class*="span"] {
    margin: 0;
  }
Jacob Thornton's avatar
Jacob Thornton committed
477
  .add-on {
478
    display: inline-block;
Jacob Thornton's avatar
Jacob Thornton committed
479
    width: auto;
480
    height: @baseLineHeight;
Jacob Thornton's avatar
Jacob Thornton committed
481
    min-width: 16px;
482
    padding: 6px;
483
    font-size: @baseFontSize;
Jacob Thornton's avatar
Jacob Thornton committed
484
    font-weight: normal;
485
    line-height: @baseLineHeight;
Jacob Thornton's avatar
Jacob Thornton committed
486
    text-align: center;
487
    text-shadow: 0 1px 0 @white;
488
    background-color: @grayLighter;
489
    border: 1px solid #ccc;
490
491
  }
  .add-on,
492
493
  .btn,
  .btn-group > .dropdown-toggle {
494
    vertical-align: top;
495
    border-radius: 0;
Jacob Thornton's avatar
Jacob Thornton committed
496
497
  }
  .active {
498
    background-color: lighten(@green, 30);
Jacob Thornton's avatar
Jacob Thornton committed
499
500
501
    border-color: @green;
  }
}
502

503
.input-prepend {
504
505
  .add-on,
  .btn {
506
507
    margin-right: -1px;
  }
508
509
  .add-on:first-child,
  .btn:first-child {
510
    // FYI, `.btn:first-child` accounts for a button group that's prepended
511
    border-radius: @inputBorderRadius 0 0 @inputBorderRadius;
512
  }
513
}
514

Mark Otto's avatar
Mark Otto committed
515
.input-append {
516
  input,
517
  select,
518
  .uneditable-input {
519
    border-radius: @inputBorderRadius 0 0 @inputBorderRadius;
520
    + .btn-group .btn,
521
    + .btn-group .btn:last-child {
522
      border-radius: 0 @inputBorderRadius @inputBorderRadius 0;
523
    }
Jacob Thornton's avatar
Jacob Thornton committed
524
  }
525
  .add-on,
526
527
  .btn,
  .btn-group {
528
529
    margin-left: -1px;
  }
530
  .add-on:last-child,
531
532
  .btn:last-child,
  .btn-group:last-child > .dropdown-toggle {
533
    border-radius: 0 @inputBorderRadius @inputBorderRadius 0;
534
535
  }
}
536

537
538
539
540
541
// Remove all border-radius for inputs with both prepend and append
.input-prepend.input-append {
  input,
  select,
  .uneditable-input {
542
    border-radius: 0;
543
    + .btn-group .btn {
544
      border-radius: 0 @inputBorderRadius @inputBorderRadius 0;
545
    }
546
  }
547
548
  .add-on:first-child,
  .btn:first-child {
549
    margin-right: -1px;
550
    border-radius: @inputBorderRadius 0 0 @inputBorderRadius;
551
  }
552
553
  .add-on:last-child,
  .btn:last-child {
554
    margin-left: -1px;
555
    border-radius: 0 @inputBorderRadius @inputBorderRadius 0;
Jacob Thornton's avatar
Jacob Thornton committed
556
  }
557
558
559
  .btn-group:first-child {
    margin-left: 0;
  }
Jacob Thornton's avatar
Jacob Thornton committed
560
561
}

562

563

564

565
566
567
// SEARCH FORM
// -----------

568
input.search-query {
569
  padding-right: 14px;
570
  padding-right: 4px \9;
Jacob Thornton's avatar
Jacob Thornton committed
571
  padding-left: 14px;
572
  padding-left: 4px \9; /* IE8 doesn't have border radius, so don't indent the padding */
573
  margin-bottom: 0; // Remove the default margin on all inputs
574
  border-radius: @inputSearchBorderRadius;
575
576
}

577
578
579
/* Allow for input prepend/append in search forms */
.form-search .input-append .search-query,
.form-search .input-prepend .search-query {
580
  border-radius: 0; // Override due to specificity
581
582
}
.form-search .input-append .search-query {
583
  border-radius: @inputSearchBorderRadius 0 0 @inputSearchBorderRadius;
584
585
}
.form-search .input-append .btn {
586
  border-radius: 0 @inputSearchBorderRadius @inputSearchBorderRadius 0;
587
588
}
.form-search .input-prepend .search-query {
589
  border-radius: 0 @inputSearchBorderRadius @inputSearchBorderRadius 0;
590
591
}
.form-search .input-prepend .btn {
592
  border-radius: @inputSearchBorderRadius 0 0 @inputSearchBorderRadius;
593
594
595
}


596
597


598
599
600
601
// HORIZONTAL & VERTICAL FORMS
// ---------------------------

// Common properties
602
603
// -----------------

604
605
606
.form-search,
.form-inline,
.form-horizontal {
607
608
609
  input,
  textarea,
  select,
610
  .help-inline,
611
612
613
  .uneditable-input,
  .input-prepend,
  .input-append {
614
615
    display: inline-block;
    margin-bottom: 0;
616
    vertical-align: middle;
617
  }
618
619
620
621
  // Re-hide hidden elements due to specifity
  .hide {
    display: none;
  }
622
}
623
.form-search label,
624
625
626
.form-inline label,
.form-search .btn-group,
.form-inline .btn-group {
627
628
  display: inline-block;
}
629
630
631
632
633
634
// 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;
635
}
636
// Inline checkbox/radio labels (remove padding on left)
Mark Otto's avatar
Mark Otto committed
637
638
.form-search .radio,
.form-search .checkbox,
639
.form-inline .radio,
Mark Otto's avatar
Mark Otto committed
640
.form-inline .checkbox {
641
  padding-left: 0;
Mark Otto's avatar
Mark Otto committed
642
643
644
  margin-bottom: 0;
  vertical-align: middle;
}
645
646
647
648
649
650
651
// 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
652
  margin-left: 0;
653
654
}

655

656
657
// Margin to space out fieldsets
.control-group {
658
  margin-bottom: @baseLineHeight / 2;
Jacob Thornton's avatar
Jacob Thornton committed
659
}
660

661
662
663
664
665
666
// Legend collapses margin, so next element is responsible for spacing
legend + .control-group {
  margin-top: @baseLineHeight;
  -webkit-margin-top-collapse: separate;
}

667
668
669
// Horizontal-specific styles
// --------------------------

670
.form-horizontal {
Mark Otto's avatar
Mark Otto committed
671
  // Increase spacing between groups
672
673
  .control-group {
    margin-bottom: @baseLineHeight;
674
    .clearfix();
675
  }
676
  // Float the labels left
677
  .control-label {
678
    float: left;
679
    width: @horizontalComponentOffset - 20;
680
681
682
683
684
    padding-top: 5px;
    text-align: right;
  }
  // Move over all input controls and content
  .controls {
685
    margin-left: @horizontalComponentOffset;
686
  }
Mark Otto's avatar
Mark Otto committed
687
688
689
690
  // Remove bottom margin on block level help text since that's accounted for on .control-group
  .help-block {
    margin-bottom: 0;
  }
691
692
693
  // And apply it only to .help-block instances that follow a form control
  input,
  select,
694
  textarea,
695
696
697
  .uneditable-input,
  .input-prepend,
  .input-append {
698
699
700
701
    + .help-block {
      margin-top: @baseLineHeight / 2;
    }
  }
702
703
  // Move over buttons in .form-actions to align with .controls
  .form-actions {
704
    padding-left: @horizontalComponentOffset;
705
  }
706
}