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

5

Mark Otto's avatar
Mark Otto committed
6
7
// General styles
// -------------------------
Jacob Thornton's avatar
Jacob Thornton committed
8

Mark Otto's avatar
Mark Otto committed
9

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
21
22
legend {
  display: block;
  width: 100%;
23
  padding: 0;
24
  margin-bottom: @baseLineHeight;
25
26
  font-size: @baseFontSize * 1.5;
  line-height: @baseLineHeight * 2;
27
  color: @grayDark;
28
  border: 0;
29
  border-bottom: 1px solid #e5e5e5;
30
}
31

32
label {
33
34
  display: block;
  margin-bottom: 5px;
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
60
61
62
  .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;
63
64
  font-size: @baseFontSize;
  line-height: @baseLineHeight;
65
  color: @gray;
66
  vertical-align: middle;
67
68
  background-color: @inputBackground;
  border-radius: @inputBorderRadius;
69
70
}

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

80
81
82
83
// Reset height since textareas have rows
textarea {
  height: auto;
}
Mark Otto's avatar
Mark Otto committed
84

Mark Otto's avatar
Mark Otto committed
85
// Everything else
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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"],
100
101
input[type="color"],
.uneditable-input {
102
  border: 1px solid @inputBorder;
103
  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
104
  .transition(~"border linear .2s, box-shadow linear .2s");
105
106
107
108
109
110

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

Mark Otto's avatar
Mark Otto committed
115
// Position radios and checkboxes better
116
117
input[type="radio"],
input[type="checkbox"] {
118
  margin: 4px 0 0;
119
  margin-top: 1px \9; /* IE8-9 */
Mark Otto's avatar
Mark Otto committed
120
  line-height: normal;
121
}
Mark Otto's avatar
Mark Otto committed
122

123
// Reset width of input images, buttons, radios, checkboxes
124
input[type="file"],
125
input[type="image"],
126
input[type="submit"],
Mark Otto's avatar
Mark Otto committed
127
128
129
130
131
input[type="reset"],
input[type="button"],
input[type="radio"],
input[type="checkbox"] {
  width: auto; // Override of generic input selector
132
133
}

134
// Set the height of select and file controls to match text inputs
135
select,
136
input[type="file"] {
137
  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 */
138
  line-height: @inputHeight;
Mark Otto's avatar
Mark Otto committed
139
}
140

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

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

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

161

Mark Otto's avatar
Mark Otto committed
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// 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
// -------------------------

191
// 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
192
193
194
195
196
input,
textarea {
  .placeholder();
}

197

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

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

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

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

233
234


235
236
237
// INPUT SIZES
// -----------

238
239
240
241
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 {
    padding: @paddingLarge;
    padding-left: 14px;
    padding-right: 14px; // TODO: Resolve this override
    font-size: @fontSizeLarge;
260
    border-radius: @borderRadiusLarge;
261
262
263
264
  }
  &.input-small {
    padding: @paddingSmall;
    font-size: @fontSizeSmall;
265
    border-radius: @borderRadiusSmall;
266
267
268
269
  }
  &.input-mini {
    padding: @paddingMini;
    font-size: @fontSizeMini;
270
    border-radius: @borderRadiusSmall;
271
272
  }
}
273

Mark Otto's avatar
Mark Otto committed
274
275
276
277
278


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

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

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

293
294
295
296
// 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
297
.input-prepend .uneditable-input[class*="span"] {
298
299
  display: inline-block;
}
300

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

// Float to collapse white-space for proper grid alignment
Mark Otto's avatar
Mark Otto committed
313
.controls-row [class*="span"] {
314
  float: left;
315
}
316
317
318
319
320
// 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;
}
321
322


323

324
325
326

// DISABLED STATE
// --------------
327

328
329
330
331
332
333
334
// Disabled and read-only inputs
input[disabled],
select[disabled],
textarea[disabled],
input[readonly],
select[readonly],
textarea[readonly] {
Jacob Thornton's avatar
Jacob Thornton committed
335
  cursor: not-allowed;
336
  background-color: @inputDisabledBackground;
Jacob Thornton's avatar
Jacob Thornton committed
337
}
338
339
340
341
342
343
344
// 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
345

346
347


348

349
350
// FORM FIELD FEEDBACK STATES
// --------------------------
351

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

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

383
384
385
386
387
388


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

.form-actions {
389
390
391
  padding: (@baseLineHeight - 1) 20px @baseLineHeight;
  margin-top: @baseLineHeight;
  margin-bottom: @baseLineHeight;
392
  background-color: @formActionsBackground;
393
  border-top: 1px solid #e5e5e5;
394
  .clearfix(); // Adding clearfix to allow for .pull-right button containers
Jacob Thornton's avatar
Jacob Thornton committed
395
396
}

397
398


399
400
401
// HELP TEXT
// ---------

Mark Otto's avatar
Mark Otto committed
402
403
.help-block,
.help-inline {
404
  color: lighten(@textColor, 15%); // lighten the text some for contrast
Mark Otto's avatar
Mark Otto committed
405
406
}

407
.help-block {
408
  display: block; // account for any element using help-block
Mark Otto's avatar
Mark Otto committed
409
  margin-bottom: @baseLineHeight / 2;
Jacob Thornton's avatar
Jacob Thornton committed
410
}
411

Jacob Thornton's avatar
Jacob Thornton committed
412
.help-inline {
413
414
  display: inline-block;
  vertical-align: middle;
415
  padding-left: 5px;
Jacob Thornton's avatar
Jacob Thornton committed
416
}
417

418

419

420
421
// INPUT GROUPS
// ------------
422

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

430
431
432
433
434
435
436
437
  // Reset the white space collapse hack
  input,
  select,
  .uneditable-input,
  .dropdown-menu {
    font-size: @baseFontSize;
  }

438
  input,
439
  select,
440
  .uneditable-input {
441
    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
442
443
    float: none; // Undo the float from grid sizing
    margin: 0; // Prevent bottom margin from screwing up alignment in stacked forms
444
    font-size: @baseFontSize;
445
    vertical-align: top;
446
    border-radius: 0 @inputBorderRadius @inputBorderRadius 0;
447
    // Make input on top when focused so blue border and shadow always show
448
449
450
    &:focus {
      z-index: 2;
    }
Jacob Thornton's avatar
Jacob Thornton committed
451
  }
Mark Otto's avatar
Mark Otto committed
452
453
454
455
456
  input[class*="span"],
  select[class*="span"],
  .uneditable-input[class*="span"] {
    margin: 0;
  }
Jacob Thornton's avatar
Jacob Thornton committed
457
  .add-on {
458
    display: inline-block;
Jacob Thornton's avatar
Jacob Thornton committed
459
    width: auto;
460
    height: @baseLineHeight;
Jacob Thornton's avatar
Jacob Thornton committed
461
    min-width: 16px;
462
    padding: 6px;
463
    font-size: @baseFontSize;
Jacob Thornton's avatar
Jacob Thornton committed
464
    font-weight: normal;
465
    line-height: @baseLineHeight;
Jacob Thornton's avatar
Jacob Thornton committed
466
    text-align: center;
467
    text-shadow: 0 1px 0 @white;
468
    background-color: @grayLighter;
469
    border: 1px solid #ccc;
470
471
  }
  .add-on,
472
473
  .btn,
  .btn-group > .dropdown-toggle {
474
    vertical-align: top;
475
    border-radius: 0;
Jacob Thornton's avatar
Jacob Thornton committed
476
477
  }
  .active {
478
    background-color: lighten(@green, 30);
Jacob Thornton's avatar
Jacob Thornton committed
479
480
481
    border-color: @green;
  }
}
482

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

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

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

542

543

544

545
546
547
// SEARCH FORM
// -----------

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

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


576
577


578
579
580
581
// HORIZONTAL & VERTICAL FORMS
// ---------------------------

// Common properties
582
583
// -----------------

584
585
586
.form-search,
.form-inline,
.form-horizontal {
587
588
589
  input,
  textarea,
  select,
590
  .help-inline,
591
592
593
  .uneditable-input,
  .input-prepend,
  .input-append {
594
595
    display: inline-block;
    margin-bottom: 0;
596
    vertical-align: middle;
597
  }
598
599
600
601
  // Re-hide hidden elements due to specifity
  .hide {
    display: none;
  }
602
}
603
.form-search label,
604
605
606
.form-inline label,
.form-search .btn-group,
.form-inline .btn-group {
607
608
  display: inline-block;
}
609
610
611
612
613
614
// 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;
615
}
616
// Inline checkbox/radio labels (remove padding on left)
Mark Otto's avatar
Mark Otto committed
617
618
.form-search .radio,
.form-search .checkbox,
619
.form-inline .radio,
Mark Otto's avatar
Mark Otto committed
620
.form-inline .checkbox {
621
  padding-left: 0;
Mark Otto's avatar
Mark Otto committed
622
623
624
  margin-bottom: 0;
  vertical-align: middle;
}
625
626
627
628
629
630
631
// 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
632
  margin-left: 0;
633
634
}

635

636
637
// Margin to space out fieldsets
.control-group {
638
  margin-bottom: @baseLineHeight / 2;
Jacob Thornton's avatar
Jacob Thornton committed
639
}
640

641
642
643
644
645
646
// Legend collapses margin, so next element is responsible for spacing
legend + .control-group {
  margin-top: @baseLineHeight;
  -webkit-margin-top-collapse: separate;
}

647
648
649
// Horizontal-specific styles
// --------------------------

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