]>
Commit | Line | Data |
---|---|---|
59c06b17 CS |
1 | // |
2 | // Forms | |
3 | // -------------------------------------------------- | |
4 | ||
5 | ||
6 | // GENERAL STYLES | |
7 | // -------------- | |
8 | ||
9 | // Make all forms have space below them | |
10 | form { | |
11 | margin: 0 0 @baseLineHeight; | |
12 | } | |
13 | ||
14 | fieldset { | |
15 | padding: 0; | |
16 | margin: 0; | |
17 | border: 0; | |
18 | } | |
19 | ||
20 | // Groups of fields with labels on top (legends) | |
21 | legend { | |
22 | display: block; | |
23 | width: 100%; | |
24 | padding: 0; | |
25 | margin-bottom: @baseLineHeight; | |
26 | font-size: @baseFontSize * 1.5; | |
27 | line-height: @baseLineHeight * 2; | |
28 | color: @grayDark; | |
29 | border: 0; | |
30 | border-bottom: 1px solid #e5e5e5; | |
31 | ||
32 | // Small | |
33 | small { | |
34 | font-size: @baseLineHeight * .75; | |
35 | color: @grayLight; | |
36 | } | |
37 | } | |
38 | ||
39 | // Set font for forms | |
40 | label, | |
41 | input, | |
42 | button, | |
43 | select, | |
44 | textarea { | |
45 | #font > .shorthand(@baseFontSize,normal,@baseLineHeight); // Set size, weight, line-height here | |
46 | } | |
47 | input, | |
48 | button, | |
49 | select, | |
50 | 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 | display: block; | |
57 | margin-bottom: 5px; | |
58 | } | |
59 | ||
60 | // Form controls | |
61 | // ------------------------- | |
62 | ||
63 | // Shared size and type resets | |
64 | select, | |
65 | textarea, | |
66 | input[type="text"], | |
67 | input[type="password"], | |
68 | input[type="datetime"], | |
69 | input[type="datetime-local"], | |
70 | input[type="date"], | |
71 | input[type="month"], | |
72 | input[type="time"], | |
73 | input[type="week"], | |
74 | input[type="number"], | |
75 | input[type="email"], | |
76 | input[type="url"], | |
77 | input[type="search"], | |
78 | input[type="tel"], | |
79 | input[type="color"], | |
80 | .uneditable-input { | |
81 | display: inline-block; | |
82 | height: @baseLineHeight; | |
83 | padding: 4px 6px; | |
84 | margin-bottom: 9px; | |
85 | font-size: @baseFontSize; | |
86 | line-height: @baseLineHeight; | |
87 | color: @gray; | |
88 | .border-radius(@inputBorderRadius); | |
89 | } | |
90 | ||
91 | // Reset appearance properties for textual inputs and textarea | |
92 | // Declare width for legacy (can't be on input[type=*] selectors or it's too specific) | |
93 | input, | |
94 | textarea, | |
95 | .uneditable-input { | |
96 | width: 206px; // plus 12px padding and 2px border | |
97 | } | |
98 | // Reset height since textareas have rows | |
99 | textarea { | |
100 | height: auto; | |
101 | } | |
102 | // Everything else | |
103 | textarea, | |
104 | input[type="text"], | |
105 | input[type="password"], | |
106 | input[type="datetime"], | |
107 | input[type="datetime-local"], | |
108 | input[type="date"], | |
109 | input[type="month"], | |
110 | input[type="time"], | |
111 | input[type="week"], | |
112 | input[type="number"], | |
113 | input[type="email"], | |
114 | input[type="url"], | |
115 | input[type="search"], | |
116 | input[type="tel"], | |
117 | input[type="color"], | |
118 | .uneditable-input { | |
119 | background-color: @inputBackground; | |
120 | border: 1px solid @inputBorder; | |
121 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); | |
122 | .transition(~"border linear .2s, box-shadow linear .2s"); | |
123 | ||
124 | // Focus state | |
125 | &:focus { | |
126 | border-color: rgba(82,168,236,.8); | |
127 | outline: 0; | |
128 | outline: thin dotted \9; /* IE6-9 */ | |
129 | .box-shadow(inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(82,168,236,.6)); | |
130 | } | |
131 | } | |
132 | ||
133 | // Position radios and checkboxes better | |
134 | input[type="radio"], | |
135 | input[type="checkbox"] { | |
136 | margin: 4px 0 0; | |
137 | *margin-top: 0; /* IE7 */ | |
138 | margin-top: 1px \9; /* IE8-9 */ | |
139 | line-height: normal; | |
140 | cursor: pointer; | |
141 | } | |
142 | ||
143 | // Reset width of input images, buttons, radios, checkboxes | |
144 | input[type="file"], | |
145 | input[type="image"], | |
146 | input[type="submit"], | |
147 | input[type="reset"], | |
148 | input[type="button"], | |
149 | input[type="radio"], | |
150 | input[type="checkbox"] { | |
151 | 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: 30px; /* In IE7, the height of the select element cannot be changed by height, only font-size */ | |
158 | *margin-top: 4px; /* For IE7, add top margin to align select with labels */ | |
159 | line-height: 30px; | |
160 | } | |
161 | ||
162 | // Make select elements obey height by applying a border | |
163 | select { | |
164 | width: 220px; // default input width + 10px of padding that doesn't get applied | |
165 | border: 1px solid @inputBorder; | |
166 | background-color: @inputBackground; // Chrome on Linux and Mobile Safari need background-color | |
167 | } | |
168 | ||
169 | // Make multiple select elements height not fixed | |
170 | select[multiple], | |
171 | select[size] { | |
172 | height: auto; | |
173 | } | |
174 | ||
175 | // Focus for select, file, radio, and checkbox | |
176 | select:focus, | |
177 | input[type="file"]:focus, | |
178 | input[type="radio"]:focus, | |
179 | input[type="checkbox"]:focus { | |
180 | .tab-focus(); | |
181 | } | |
182 | ||
183 | ||
184 | // Uneditable inputs | |
185 | // ------------------------- | |
186 | ||
187 | // Make uneditable inputs look inactive | |
188 | .uneditable-input, | |
189 | .uneditable-textarea { | |
190 | color: @grayLight; | |
191 | background-color: darken(@inputBackground, 1%); | |
192 | border-color: @inputBorder; | |
193 | .box-shadow(inset 0 1px 2px rgba(0,0,0,.025)); | |
194 | cursor: not-allowed; | |
195 | } | |
196 | ||
197 | // For text that needs to appear as an input but should not be an input | |
198 | .uneditable-input { | |
199 | overflow: hidden; // prevent text from wrapping, but still cut it off like an input does | |
200 | white-space: nowrap; | |
201 | } | |
202 | ||
203 | // Make uneditable textareas behave like a textarea | |
204 | .uneditable-textarea { | |
205 | width: auto; | |
206 | height: auto; | |
207 | } | |
208 | ||
209 | ||
210 | // Placeholder | |
211 | // ------------------------- | |
212 | ||
213 | // Placeholder text gets special styles because when browsers invalidate entire lines if it doesn’t understand a selector | |
214 | input, | |
215 | textarea { | |
216 | .placeholder(); | |
217 | } | |
218 | ||
219 | ||
220 | // CHECKBOXES & RADIOS | |
221 | // ------------------- | |
222 | ||
223 | // Indent the labels to position radios/checkboxes as hanging | |
224 | .radio, | |
225 | .checkbox { | |
226 | min-height: 18px; // clear the floating input if there is no label text | |
227 | padding-left: 18px; | |
228 | } | |
229 | .radio input[type="radio"], | |
230 | .checkbox input[type="checkbox"] { | |
231 | float: left; | |
232 | margin-left: -18px; | |
233 | } | |
234 | ||
235 | // Move the options list down to align with labels | |
236 | .controls > .radio:first-child, | |
237 | .controls > .checkbox:first-child { | |
238 | padding-top: 5px; // has to be padding because margin collaspes | |
239 | } | |
240 | ||
241 | // Radios and checkboxes on same line | |
242 | // TODO v3: Convert .inline to .control-inline | |
243 | .radio.inline, | |
244 | .checkbox.inline { | |
245 | display: inline-block; | |
246 | padding-top: 5px; | |
247 | margin-bottom: 0; | |
248 | vertical-align: middle; | |
249 | } | |
250 | .radio.inline + .radio.inline, | |
251 | .checkbox.inline + .checkbox.inline { | |
252 | margin-left: 10px; // space out consecutive inline controls | |
253 | } | |
254 | ||
255 | ||
256 | ||
257 | // INPUT SIZES | |
258 | // ----------- | |
259 | ||
260 | // General classes for quick sizes | |
261 | .input-mini { width: 60px; } | |
262 | .input-small { width: 90px; } | |
263 | .input-medium { width: 150px; } | |
264 | .input-large { width: 210px; } | |
265 | .input-xlarge { width: 270px; } | |
266 | .input-xxlarge { width: 530px; } | |
267 | ||
268 | // Grid style input sizes | |
269 | input[class*="span"], | |
270 | select[class*="span"], | |
271 | textarea[class*="span"], | |
272 | .uneditable-input[class*="span"], | |
273 | // Redeclare since the fluid row class is more specific | |
274 | .row-fluid input[class*="span"], | |
275 | .row-fluid select[class*="span"], | |
276 | .row-fluid textarea[class*="span"], | |
277 | .row-fluid .uneditable-input[class*="span"] { | |
278 | float: none; | |
279 | margin-left: 0; | |
280 | } | |
281 | // Ensure input-prepend/append never wraps | |
282 | .input-append input[class*="span"], | |
283 | .input-append .uneditable-input[class*="span"], | |
284 | .input-prepend input[class*="span"], | |
285 | .input-prepend .uneditable-input[class*="span"], | |
286 | .row-fluid input[class*="span"], | |
287 | .row-fluid select[class*="span"], | |
288 | .row-fluid textarea[class*="span"], | |
289 | .row-fluid .uneditable-input[class*="span"], | |
290 | .row-fluid .input-prepend [class*="span"], | |
291 | .row-fluid .input-append [class*="span"] { | |
292 | display: inline-block; | |
293 | } | |
294 | ||
295 | ||
296 | ||
297 | // GRID SIZING FOR INPUTS | |
298 | // ---------------------- | |
299 | ||
300 | // Grid sizes | |
301 | #grid > .input(@gridColumnWidth, @gridGutterWidth); | |
302 | ||
303 | // Control row for multiple inputs per line | |
304 | .controls-row { | |
305 | .clearfix(); // Clear the float from controls | |
306 | } | |
307 | .controls-row [class*="span"] { | |
308 | float: left; // Float to collapse white-space for proper grid alignment | |
309 | } | |
310 | ||
311 | ||
312 | ||
313 | ||
314 | // DISABLED STATE | |
315 | // -------------- | |
316 | ||
317 | // Disabled and read-only inputs | |
318 | input[disabled], | |
319 | select[disabled], | |
320 | textarea[disabled], | |
321 | input[readonly], | |
322 | select[readonly], | |
323 | textarea[readonly] { | |
324 | cursor: not-allowed; | |
325 | background-color: @inputDisabledBackground; | |
326 | } | |
327 | // Explicitly reset the colors here | |
328 | input[type="radio"][disabled], | |
329 | input[type="checkbox"][disabled], | |
330 | input[type="radio"][readonly], | |
331 | input[type="checkbox"][readonly] { | |
332 | background-color: transparent; | |
333 | } | |
334 | ||
335 | ||
336 | ||
337 | ||
338 | // FORM FIELD FEEDBACK STATES | |
339 | // -------------------------- | |
340 | ||
341 | // Warning | |
342 | .control-group.warning { | |
343 | .formFieldState(@warningText, @warningText, @warningBackground); | |
344 | } | |
345 | // Error | |
346 | .control-group.error { | |
347 | .formFieldState(@errorText, @errorText, @errorBackground); | |
348 | } | |
349 | // Success | |
350 | .control-group.success { | |
351 | .formFieldState(@successText, @successText, @successBackground); | |
352 | } | |
353 | // Success | |
354 | .control-group.info { | |
355 | .formFieldState(@infoText, @infoText, @infoBackground); | |
356 | } | |
357 | ||
358 | // HTML5 invalid states | |
359 | // Shares styles with the .control-group.error above | |
360 | input:focus:required:invalid, | |
361 | textarea:focus:required:invalid, | |
362 | select:focus:required:invalid { | |
363 | color: #b94a48; | |
364 | border-color: #ee5f5b; | |
365 | &:focus { | |
366 | border-color: darken(#ee5f5b, 10%); | |
367 | .box-shadow(0 0 6px lighten(#ee5f5b, 20%)); | |
368 | } | |
369 | } | |
370 | ||
371 | ||
372 | ||
373 | // FORM ACTIONS | |
374 | // ------------ | |
375 | ||
376 | .form-actions { | |
377 | padding: (@baseLineHeight - 1) 20px @baseLineHeight; | |
378 | margin-top: @baseLineHeight; | |
379 | margin-bottom: @baseLineHeight; | |
380 | background-color: @formActionsBackground; | |
381 | border-top: 1px solid #e5e5e5; | |
382 | .clearfix(); // Adding clearfix to allow for .pull-right button containers | |
383 | } | |
384 | ||
385 | ||
386 | ||
387 | // HELP TEXT | |
388 | // --------- | |
389 | ||
390 | .help-block, | |
391 | .help-inline { | |
392 | color: lighten(@textColor, 15%); // lighten the text some for contrast | |
393 | } | |
394 | ||
395 | .help-block { | |
396 | display: block; // account for any element using help-block | |
397 | margin-bottom: @baseLineHeight / 2; | |
398 | } | |
399 | ||
400 | .help-inline { | |
401 | display: inline-block; | |
402 | .ie7-inline-block(); | |
403 | vertical-align: middle; | |
404 | padding-left: 5px; | |
405 | } | |
406 | ||
407 | ||
408 | ||
409 | // INPUT GROUPS | |
410 | // ------------ | |
411 | ||
412 | // Allow us to put symbols and text within the input field for a cleaner look | |
413 | .input-append, | |
414 | .input-prepend { | |
415 | margin-bottom: 5px; | |
416 | font-size: 0; | |
417 | white-space: nowrap; // Prevent span and input from separating | |
418 | ||
419 | input, | |
420 | select, | |
421 | .uneditable-input { | |
422 | 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 | |
423 | margin-bottom: 0; // prevent bottom margin from screwing up alignment in stacked forms | |
424 | *margin-left: 0; | |
425 | font-size: @baseFontSize; | |
426 | vertical-align: top; | |
427 | .border-radius(0 @inputBorderRadius @inputBorderRadius 0); | |
428 | // Make input on top when focused so blue border and shadow always show | |
429 | &:focus { | |
430 | z-index: 2; | |
431 | } | |
432 | } | |
433 | .add-on { | |
434 | display: inline-block; | |
435 | width: auto; | |
436 | height: @baseLineHeight; | |
437 | min-width: 16px; | |
438 | padding: 4px 5px; | |
439 | font-size: @baseFontSize; | |
440 | font-weight: normal; | |
441 | line-height: @baseLineHeight; | |
442 | text-align: center; | |
443 | text-shadow: 0 1px 0 @white; | |
444 | background-color: @grayLighter; | |
445 | border: 1px solid #ccc; | |
446 | } | |
447 | .add-on, | |
448 | .btn { | |
449 | vertical-align: top; | |
450 | .border-radius(0); | |
451 | } | |
452 | .active { | |
453 | background-color: lighten(@green, 30); | |
454 | border-color: @green; | |
455 | } | |
456 | } | |
457 | .input-prepend { | |
458 | .add-on, | |
459 | .btn { | |
460 | margin-right: -1px; | |
461 | } | |
462 | .add-on:first-child, | |
463 | .btn:first-child { | |
464 | .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); | |
465 | } | |
466 | } | |
467 | .input-append { | |
468 | input, | |
469 | select, | |
470 | .uneditable-input { | |
471 | .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); | |
472 | } | |
473 | .add-on, | |
474 | .btn { | |
475 | margin-left: -1px; | |
476 | } | |
477 | .add-on:last-child, | |
478 | .btn:last-child { | |
479 | .border-radius(0 @inputBorderRadius @inputBorderRadius 0); | |
480 | } | |
481 | } | |
482 | // Remove all border-radius for inputs with both prepend and append | |
483 | .input-prepend.input-append { | |
484 | input, | |
485 | select, | |
486 | .uneditable-input { | |
487 | .border-radius(0); | |
488 | } | |
489 | .add-on:first-child, | |
490 | .btn:first-child { | |
491 | margin-right: -1px; | |
492 | .border-radius(@inputBorderRadius 0 0 @inputBorderRadius); | |
493 | } | |
494 | .add-on:last-child, | |
495 | .btn:last-child { | |
496 | margin-left: -1px; | |
497 | .border-radius(0 @inputBorderRadius @inputBorderRadius 0); | |
498 | } | |
499 | } | |
500 | ||
501 | ||
502 | ||
503 | // SEARCH FORM | |
504 | // ----------- | |
505 | ||
506 | input.search-query { | |
507 | padding-right: 14px; | |
508 | padding-right: 4px \9; | |
509 | padding-left: 14px; | |
510 | padding-left: 4px \9; /* IE7-8 doesn't have border-radius, so don't indent the padding */ | |
511 | margin-bottom: 0; // Remove the default margin on all inputs | |
512 | .border-radius(15px); | |
513 | } | |
514 | ||
515 | /* Allow for input prepend/append in search forms */ | |
516 | .form-search .input-append .search-query, | |
517 | .form-search .input-prepend .search-query { | |
518 | .border-radius(0); // Override due to specificity | |
519 | } | |
520 | .form-search .input-append .search-query { | |
521 | .border-radius(14px 0 0 14px); | |
522 | } | |
523 | .form-search .input-append .btn { | |
524 | .border-radius(0 14px 14px 0); | |
525 | } | |
526 | .form-search .input-prepend .search-query { | |
527 | .border-radius(0 14px 14px 0); | |
528 | } | |
529 | .form-search .input-prepend .btn { | |
530 | .border-radius(14px 0 0 14px); | |
531 | } | |
532 | ||
533 | ||
534 | ||
535 | ||
536 | // HORIZONTAL & VERTICAL FORMS | |
537 | // --------------------------- | |
538 | ||
539 | // Common properties | |
540 | // ----------------- | |
541 | ||
542 | .form-search, | |
543 | .form-inline, | |
544 | .form-horizontal { | |
545 | input, | |
546 | textarea, | |
547 | select, | |
548 | .help-inline, | |
549 | .uneditable-input, | |
550 | .input-prepend, | |
551 | .input-append { | |
552 | display: inline-block; | |
553 | .ie7-inline-block(); | |
554 | margin-bottom: 0; | |
555 | vertical-align: middle; | |
556 | } | |
557 | // Re-hide hidden elements due to specifity | |
558 | .hide { | |
559 | display: none; | |
560 | } | |
561 | } | |
562 | .form-search label, | |
563 | .form-inline label, | |
564 | .form-search .btn-group, | |
565 | .form-inline .btn-group { | |
566 | display: inline-block; | |
567 | } | |
568 | // Remove margin for input-prepend/-append | |
569 | .form-search .input-append, | |
570 | .form-inline .input-append, | |
571 | .form-search .input-prepend, | |
572 | .form-inline .input-prepend { | |
573 | margin-bottom: 0; | |
574 | } | |
575 | // Inline checkbox/radio labels (remove padding on left) | |
576 | .form-search .radio, | |
577 | .form-search .checkbox, | |
578 | .form-inline .radio, | |
579 | .form-inline .checkbox { | |
580 | padding-left: 0; | |
581 | margin-bottom: 0; | |
582 | vertical-align: middle; | |
583 | } | |
584 | // Remove float and margin, set to inline-block | |
585 | .form-search .radio input[type="radio"], | |
586 | .form-search .checkbox input[type="checkbox"], | |
587 | .form-inline .radio input[type="radio"], | |
588 | .form-inline .checkbox input[type="checkbox"] { | |
589 | float: left; | |
590 | margin-right: 3px; | |
591 | margin-left: 0; | |
592 | } | |
593 | ||
594 | ||
595 | // Margin to space out fieldsets | |
596 | .control-group { | |
597 | margin-bottom: @baseLineHeight / 2; | |
598 | } | |
599 | ||
600 | // Legend collapses margin, so next element is responsible for spacing | |
601 | legend + .control-group { | |
602 | margin-top: @baseLineHeight; | |
603 | -webkit-margin-top-collapse: separate; | |
604 | } | |
605 | ||
606 | // Horizontal-specific styles | |
607 | // -------------------------- | |
608 | ||
609 | .form-horizontal { | |
610 | // Increase spacing between groups | |
611 | .control-group { | |
612 | margin-bottom: @baseLineHeight; | |
613 | .clearfix(); | |
614 | } | |
615 | // Float the labels left | |
616 | .control-label { | |
617 | float: left; | |
618 | width: @horizontalComponentOffset - 20; | |
619 | padding-top: 5px; | |
620 | text-align: right; | |
621 | } | |
622 | // Move over all input controls and content | |
623 | .controls { | |
624 | // Super jank IE7 fix to ensure the inputs in .input-append and input-prepend | |
625 | // don't inherit the margin of the parent, in this case .controls | |
626 | *display: inline-block; | |
627 | *padding-left: 20px; | |
628 | margin-left: @horizontalComponentOffset; | |
629 | *margin-left: 0; | |
630 | &:first-child { | |
631 | *padding-left: @horizontalComponentOffset; | |
632 | } | |
633 | } | |
634 | // Remove bottom margin on block level help text since that's accounted for on .control-group | |
635 | .help-block { | |
636 | margin-bottom: 0; | |
637 | } | |
638 | // And apply it only to .help-block instances that follow a form control | |
639 | input, | |
640 | select, | |
641 | textarea { | |
642 | + .help-block { | |
643 | margin-top: @baseLineHeight / 2; | |
644 | } | |
645 | } | |
646 | // Move over buttons in .form-actions to align with .controls | |
647 | .form-actions { | |
648 | padding-left: @horizontalComponentOffset; | |
649 | } | |
650 | } |