forms.less 15.2 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
  height: @baseLineHeight;
83
  padding: 4px 6px;
84
  margin-bottom: 9px;
85
86
  font-size: @baseFontSize;
  line-height: @baseLineHeight;
87
  color: @gray;
Mark Otto's avatar
Mark Otto committed
88
  .border-radius(@inputBorderRadius);
89
  vertical-align: middle;
90
91
}

Mark Otto's avatar
Mark Otto committed
92
93
94
// 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,
95
96
textarea,
.uneditable-input {
97
  width: 206px; // plus 12px padding and 2px border
Mark Otto's avatar
Mark Otto committed
98
}
99
100
101
102
// Reset height since textareas have rows
textarea {
  height: auto;
}
Mark Otto's avatar
Mark Otto committed
103
// Everything else
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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"],
118
119
input[type="color"],
.uneditable-input {
Mark Otto's avatar
Mark Otto committed
120
  background-color: @inputBackground;
121
  border: 1px solid @inputBorder;
122
  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
123
  .transition(~"border linear .2s, box-shadow linear .2s");
124
125
126
127
128
129

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

Mark Otto's avatar
Mark Otto committed
134
// Position radios and checkboxes better
135
136
input[type="radio"],
input[type="checkbox"] {
137
  margin: 4px 0 0;
138
  margin-top: 1px \9; /* IE8-9 */
Mark Otto's avatar
Mark Otto committed
139
140
  line-height: normal;
  cursor: pointer;
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;
165
  background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color
Mark Otto's avatar
Mark Otto committed
166
167
}

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

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

182

Mark Otto's avatar
Mark Otto committed
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
211
// 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
// -------------------------

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

218

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

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

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

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

254
255


256
257
258
// INPUT SIZES
// -----------

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

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


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

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

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

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

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

// Float to collapse white-space for proper grid alignment
.controls-row [class*="span"],
// Redeclare the fluid grid collapse since we undo the float for inputs
.row-fluid .controls-row [class*="span"] {
  float: left;
338
339
340
}


341

342
343
344

// DISABLED STATE
// --------------
345

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

364
365


366

367
368
// FORM FIELD FEEDBACK STATES
// --------------------------
369

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

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

401
402
403
404
405
406


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

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

415
416


417
418
419
// HELP TEXT
// ---------

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

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

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

436

437

438
439
// INPUT GROUPS
// ------------
440

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

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

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

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

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

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

557

558

559

560
561
562
// SEARCH FORM
// -----------

563
input.search-query {
564
  padding-right: 14px;
565
  padding-right: 4px \9;
Jacob Thornton's avatar
Jacob Thornton committed
566
  padding-left: 14px;
567
  padding-left: 4px \9; /* IE8 doesn't have border-radius, so don't indent the padding */
568
  margin-bottom: 0; // Remove the default margin on all inputs
Mark Otto's avatar
Mark Otto committed
569
  .border-radius(15px);
570
571
}

572
573
574
575
576
577
/* Allow for input prepend/append in search forms */
.form-search .input-append .search-query,
.form-search .input-prepend .search-query {
  .border-radius(0); // Override due to specificity
}
.form-search .input-append .search-query {
Mark Otto's avatar
Mark Otto committed
578
  .border-radius(14px 0 0 14px);
579
580
}
.form-search .input-append .btn {
Mark Otto's avatar
Mark Otto committed
581
  .border-radius(0 14px 14px 0);
582
583
}
.form-search .input-prepend .search-query {
Mark Otto's avatar
Mark Otto committed
584
  .border-radius(0 14px 14px 0);
585
586
}
.form-search .input-prepend .btn {
Mark Otto's avatar
Mark Otto committed
587
  .border-radius(14px 0 0 14px);
588
589
590
}


591
592


593
594
595
596
// HORIZONTAL & VERTICAL FORMS
// ---------------------------

// Common properties
597
598
// -----------------

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

650

651
652
// Margin to space out fieldsets
.control-group {
653
  margin-bottom: @baseLineHeight / 2;
Jacob Thornton's avatar
Jacob Thornton committed
654
}
655

656
657
658
659
660
661
// Legend collapses margin, so next element is responsible for spacing
legend + .control-group {
  margin-top: @baseLineHeight;
  -webkit-margin-top-collapse: separate;
}

662
663
664
// Horizontal-specific styles
// --------------------------

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