Fix E713 with stricter pep8 error checker
[cascardo/ipsilon.git] / less / bootstrap / mixins.less
1 //
2 // Mixins
3 // --------------------------------------------------
4
5
6 // Utilities
7 // -------------------------
8
9 // Clearfix
10 // Source: http://nicolasgallagher.com/micro-clearfix-hack/
11 //
12 // For modern browsers
13 // 1. The space content is one way to avoid an Opera bug when the
14 //    contenteditable attribute is included anywhere else in the document.
15 //    Otherwise it causes space to appear at the top and bottom of elements
16 //    that are clearfixed.
17 // 2. The use of `table` rather than `block` is only necessary if using
18 //    `:before` to contain the top-margins of child elements.
19 .clearfix() {
20   &:before,
21   &:after {
22     content: " "; // 1
23     display: table; // 2
24   }
25   &:after {
26     clear: both;
27   }
28 }
29
30 // WebKit-style focus
31 .tab-focus() {
32   // Default
33   outline: thin dotted;
34   // WebKit
35   outline: 5px auto -webkit-focus-ring-color;
36   outline-offset: -2px;
37 }
38
39 // Center-align a block level element
40 .center-block() {
41   display: block;
42   margin-left: auto;
43   margin-right: auto;
44 }
45
46 // Sizing shortcuts
47 .size(@width; @height) {
48   width: @width;
49   height: @height;
50 }
51 .square(@size) {
52   .size(@size; @size);
53 }
54
55 // Placeholder text
56 .placeholder(@color: @input-color-placeholder) {
57   &:-moz-placeholder            { color: @color; } // Firefox 4-18
58   &::-moz-placeholder           { color: @color;   // Firefox 19+
59                                   opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526
60   &:-ms-input-placeholder       { color: @color; } // Internet Explorer 10+
61   &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome
62 }
63
64 // Text overflow
65 // Requires inline-block or block for proper styling
66 .text-overflow() {
67   overflow: hidden;
68   text-overflow: ellipsis;
69   white-space: nowrap;
70 }
71
72 // CSS image replacement
73 //
74 // Heads up! v3 launched with with only `.hide-text()`, but per our pattern for
75 // mixins being reused as classes with the same name, this doesn't hold up. As
76 // of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note
77 // that we cannot chain the mixins together in Less, so they are repeated.
78 //
79 // Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
80
81 // Deprecated as of v3.0.1 (will be removed in v4)
82 .hide-text() {
83   font: ~"0/0" a;
84   color: transparent;
85   text-shadow: none;
86   background-color: transparent;
87   border: 0;
88 }
89 // New mixin to use as of v3.0.1
90 .text-hide() {
91   .hide-text();
92 }
93
94
95
96 // CSS3 PROPERTIES
97 // --------------------------------------------------
98
99 // Single side border-radius
100 .border-top-radius(@radius) {
101   border-top-right-radius: @radius;
102    border-top-left-radius: @radius;
103 }
104 .border-right-radius(@radius) {
105   border-bottom-right-radius: @radius;
106      border-top-right-radius: @radius;
107 }
108 .border-bottom-radius(@radius) {
109   border-bottom-right-radius: @radius;
110    border-bottom-left-radius: @radius;
111 }
112 .border-left-radius(@radius) {
113   border-bottom-left-radius: @radius;
114      border-top-left-radius: @radius;
115 }
116
117 // Drop shadows
118 .box-shadow(@shadow) {
119   -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
120           box-shadow: @shadow;
121 }
122
123 // Transitions
124 .transition(@transition) {
125   -webkit-transition: @transition;
126           transition: @transition;
127 }
128 .transition-property(@transition-property) {
129   -webkit-transition-property: @transition-property;
130           transition-property: @transition-property;
131 }
132 .transition-delay(@transition-delay) {
133   -webkit-transition-delay: @transition-delay;
134           transition-delay: @transition-delay;
135 }
136 .transition-duration(@transition-duration) {
137   -webkit-transition-duration: @transition-duration;
138           transition-duration: @transition-duration;
139 }
140 .transition-transform(@transition) {
141   -webkit-transition: -webkit-transform @transition;
142      -moz-transition: -moz-transform @transition;
143        -o-transition: -o-transform @transition;
144           transition: transform @transition;
145 }
146
147 // Transformations
148 .rotate(@degrees) {
149   -webkit-transform: rotate(@degrees);
150       -ms-transform: rotate(@degrees); // IE9 only
151           transform: rotate(@degrees);
152 }
153 .scale(@ratio; @ratio-y...) {
154   -webkit-transform: scale(@ratio, @ratio-y);
155       -ms-transform: scale(@ratio, @ratio-y); // IE9 only
156           transform: scale(@ratio, @ratio-y);
157 }
158 .translate(@x; @y) {
159   -webkit-transform: translate(@x, @y);
160       -ms-transform: translate(@x, @y); // IE9 only
161           transform: translate(@x, @y);
162 }
163 .skew(@x; @y) {
164   -webkit-transform: skew(@x, @y);
165       -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
166           transform: skew(@x, @y);
167 }
168 .translate3d(@x; @y; @z) {
169   -webkit-transform: translate3d(@x, @y, @z);
170           transform: translate3d(@x, @y, @z);
171 }
172
173 .rotateX(@degrees) {
174   -webkit-transform: rotateX(@degrees);
175       -ms-transform: rotateX(@degrees); // IE9 only
176           transform: rotateX(@degrees);
177 }
178 .rotateY(@degrees) {
179   -webkit-transform: rotateY(@degrees);
180       -ms-transform: rotateY(@degrees); // IE9 only
181           transform: rotateY(@degrees);
182 }
183 .perspective(@perspective) {
184   -webkit-perspective: @perspective;
185      -moz-perspective: @perspective;
186           perspective: @perspective;
187 }
188 .perspective-origin(@perspective) {
189   -webkit-perspective-origin: @perspective;
190      -moz-perspective-origin: @perspective;
191           perspective-origin: @perspective;
192 }
193 .transform-origin(@origin) {
194   -webkit-transform-origin: @origin;
195      -moz-transform-origin: @origin;
196       -ms-transform-origin: @origin; // IE9 only
197           transform-origin: @origin;
198 }
199
200 // Animations
201 .animation(@animation) {
202   -webkit-animation: @animation;
203           animation: @animation;
204 }
205 .animation-name(@name) {
206   -webkit-animation-name: @name;
207           animation-name: @name;
208 }
209 .animation-duration(@duration) {
210   -webkit-animation-duration: @duration;
211           animation-duration: @duration;
212 }
213 .animation-timing-function(@timing-function) {
214   -webkit-animation-timing-function: @timing-function;
215           animation-timing-function: @timing-function;
216 }
217 .animation-delay(@delay) {
218   -webkit-animation-delay: @delay;
219           animation-delay: @delay;
220 }
221 .animation-iteration-count(@iteration-count) {
222   -webkit-animation-iteration-count: @iteration-count;
223           animation-iteration-count: @iteration-count;
224 }
225 .animation-direction(@direction) {
226   -webkit-animation-direction: @direction;
227           animation-direction: @direction;
228 }
229
230 // Backface visibility
231 // Prevent browsers from flickering when using CSS 3D transforms.
232 // Default value is `visible`, but can be changed to `hidden`
233 .backface-visibility(@visibility){
234   -webkit-backface-visibility: @visibility;
235      -moz-backface-visibility: @visibility;
236           backface-visibility: @visibility;
237 }
238
239 // Box sizing
240 .box-sizing(@boxmodel) {
241   -webkit-box-sizing: @boxmodel;
242      -moz-box-sizing: @boxmodel;
243           box-sizing: @boxmodel;
244 }
245
246 // User select
247 // For selecting text on the page
248 .user-select(@select) {
249   -webkit-user-select: @select;
250      -moz-user-select: @select;
251       -ms-user-select: @select; // IE10+
252        -o-user-select: @select;
253           user-select: @select;
254 }
255
256 // Resize anything
257 .resizable(@direction) {
258   resize: @direction; // Options: horizontal, vertical, both
259   overflow: auto; // Safari fix
260 }
261
262 // CSS3 Content Columns
263 .content-columns(@column-count; @column-gap: @grid-gutter-width) {
264   -webkit-column-count: @column-count;
265      -moz-column-count: @column-count;
266           column-count: @column-count;
267   -webkit-column-gap: @column-gap;
268      -moz-column-gap: @column-gap;
269           column-gap: @column-gap;
270 }
271
272 // Optional hyphenation
273 .hyphens(@mode: auto) {
274   word-wrap: break-word;
275   -webkit-hyphens: @mode;
276      -moz-hyphens: @mode;
277       -ms-hyphens: @mode; // IE10+
278        -o-hyphens: @mode;
279           hyphens: @mode;
280 }
281
282 // Opacity
283 .opacity(@opacity) {
284   opacity: @opacity;
285   // IE8 filter
286   @opacity-ie: (@opacity * 100);
287   filter: ~"alpha(opacity=@{opacity-ie})";
288 }
289
290
291
292 // GRADIENTS
293 // --------------------------------------------------
294
295 #gradient {
296
297   // Horizontal gradient, from left to right
298   //
299   // Creates two color stops, start and end, by specifying a color and position for each color stop.
300   // Color stops are not available in IE9 and below.
301   .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
302     background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+
303     background-image:  linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
304     background-repeat: repeat-x;
305     filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down
306   }
307
308   // Vertical gradient, from top to bottom
309   //
310   // Creates two color stops, start and end, by specifying a color and position for each color stop.
311   // Color stops are not available in IE9 and below.
312   .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
313     background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+
314     background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
315     background-repeat: repeat-x;
316     filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down
317   }
318
319   .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {
320     background-repeat: repeat-x;
321     background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+
322     background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
323   }
324   .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
325     background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
326     background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);
327     background-repeat: no-repeat;
328     filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
329   }
330   .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
331     background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
332     background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);
333     background-repeat: no-repeat;
334     filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback
335   }
336   .radial(@inner-color: #555; @outer-color: #333) {
337     background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);
338     background-image: radial-gradient(circle, @inner-color, @outer-color);
339     background-repeat: no-repeat;
340   }
341   .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {
342     background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
343     background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
344   }
345 }
346
347 // Reset filters for IE
348 //
349 // When you need to remove a gradient background, do not forget to use this to reset
350 // the IE filter for IE9 and below.
351 .reset-filter() {
352   filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
353 }
354
355
356
357 // Retina images
358 //
359 // Short retina mixin for setting background-image and -size
360
361 .img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {
362   background-image: url("@{file-1x}");
363
364   @media
365   only screen and (-webkit-min-device-pixel-ratio: 2),
366   only screen and (   min--moz-device-pixel-ratio: 2),
367   only screen and (     -o-min-device-pixel-ratio: 2/1),
368   only screen and (        min-device-pixel-ratio: 2),
369   only screen and (                min-resolution: 192dpi),
370   only screen and (                min-resolution: 2dppx) {
371     background-image: url("@{file-2x}");
372     background-size: @width-1x @height-1x;
373   }
374 }
375
376
377 // Responsive image
378 //
379 // Keep images from scaling beyond the width of their parents.
380
381 .img-responsive(@display: block) {
382   display: @display;
383   max-width: 100%; // Part 1: Set a maximum relative to the parent
384   height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
385 }
386
387
388 // COMPONENT MIXINS
389 // --------------------------------------------------
390
391 // Horizontal dividers
392 // -------------------------
393 // Dividers (basically an hr) within dropdowns and nav lists
394 .nav-divider(@color: #e5e5e5) {
395   height: 1px;
396   margin: ((@line-height-computed / 2) - 1) 0;
397   overflow: hidden;
398   background-color: @color;
399 }
400
401 // Panels
402 // -------------------------
403 .panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {
404   border-color: @border;
405
406   & > .panel-heading {
407     color: @heading-text-color;
408     background-color: @heading-bg-color;
409     border-color: @heading-border;
410
411     + .panel-collapse .panel-body {
412       border-top-color: @border;
413     }
414   }
415   & > .panel-footer {
416     + .panel-collapse .panel-body {
417       border-bottom-color: @border;
418     }
419   }
420 }
421
422 // Alerts
423 // -------------------------
424 .alert-variant(@background; @border; @text-color) {
425   background-color: @background;
426   border-color: @border;
427   color: @text-color;
428
429   hr {
430     border-top-color: darken(@border, 5%);
431   }
432   .alert-link {
433     color: darken(@text-color, 10%);
434   }
435 }
436
437 // Tables
438 // -------------------------
439 .table-row-variant(@state; @background) {
440   // Exact selectors below required to override `.table-striped` and prevent
441   // inheritance to nested tables.
442   .table > thead > tr,
443   .table > tbody > tr,
444   .table > tfoot > tr {
445     > td.@{state},
446     > th.@{state},
447     &.@{state} > td,
448     &.@{state} > th {
449       background-color: @background;
450     }
451   }
452
453   // Hover states for `.table-hover`
454   // Note: this is not available for cells or rows within `thead` or `tfoot`.
455   .table-hover > tbody > tr {
456     > td.@{state}:hover,
457     > th.@{state}:hover,
458     &.@{state}:hover > td,
459     &.@{state}:hover > th {
460       background-color: darken(@background, 5%);
461     }
462   }
463 }
464
465 // List Groups
466 // -------------------------
467 .list-group-item-variant(@state; @background; @color) {
468   .list-group-item-@{state} {
469     color: @color;
470     background-color: @background;
471
472     a& {
473       color: @color;
474
475       .list-group-item-heading { color: inherit; }
476
477       &:hover,
478       &:focus {
479         color: @color;
480         background-color: darken(@background, 5%);
481       }
482       &.active,
483       &.active:hover,
484       &.active:focus {
485         color: #fff;
486         background-color: @color;
487         border-color: @color;
488       }
489     }
490   }
491 }
492
493 // Button variants
494 // -------------------------
495 // Easily pump out default styles, as well as :hover, :focus, :active,
496 // and disabled options for all buttons
497 .button-variant(@color; @background; @border) {
498   color: @color;
499   background-color: @background;
500   border-color: @border;
501
502   &:hover,
503   &:focus,
504   &:active,
505   &.active,
506   .open .dropdown-toggle& {
507     color: @color;
508     background-color: darken(@background, 8%);
509         border-color: darken(@border, 12%);
510   }
511   &:active,
512   &.active,
513   .open .dropdown-toggle& {
514     background-image: none;
515   }
516   &.disabled,
517   &[disabled],
518   fieldset[disabled] & {
519     &,
520     &:hover,
521     &:focus,
522     &:active,
523     &.active {
524       background-color: @background;
525           border-color: @border;
526     }
527   }
528
529   .badge {
530     color: @background;
531     background-color: @color;
532   }
533 }
534
535 // Button sizes
536 // -------------------------
537 .button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
538   padding: @padding-vertical @padding-horizontal;
539   font-size: @font-size;
540   line-height: @line-height;
541   border-radius: @border-radius;
542 }
543
544 // Pagination
545 // -------------------------
546 .pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {
547   > li {
548     > a,
549     > span {
550       padding: @padding-vertical @padding-horizontal;
551       font-size: @font-size;
552     }
553     &:first-child {
554       > a,
555       > span {
556         .border-left-radius(@border-radius);
557       }
558     }
559     &:last-child {
560       > a,
561       > span {
562         .border-right-radius(@border-radius);
563       }
564     }
565   }
566 }
567
568 // Labels
569 // -------------------------
570 .label-variant(@color) {
571   background-color: @color;
572   &[href] {
573     &:hover,
574     &:focus {
575       background-color: darken(@color, 10%);
576     }
577   }
578 }
579
580 // Contextual backgrounds
581 // -------------------------
582 .bg-variant(@color) {
583   background-color: @color;
584   a&:hover {
585     background-color: darken(@color, 10%);
586   }
587 }
588
589 // Typography
590 // -------------------------
591 .text-emphasis-variant(@color) {
592   color: @color;
593   a&:hover {
594     color: darken(@color, 10%);
595   }
596 }
597
598 // Navbar vertical align
599 // -------------------------
600 // Vertically center elements in the navbar.
601 // Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
602 .navbar-vertical-align(@element-height) {
603   margin-top: ((@navbar-height - @element-height) / 2);
604   margin-bottom: ((@navbar-height - @element-height) / 2);
605 }
606
607 // Progress bars
608 // -------------------------
609 .progress-bar-variant(@color) {
610   background-color: @color;
611   .progress-striped & {
612     #gradient > .striped();
613   }
614 }
615
616 // Responsive utilities
617 // -------------------------
618 // More easily include all the states for responsive-utilities.less.
619 .responsive-visibility() {
620   display: block !important;
621   table&  { display: table; }
622   tr&     { display: table-row !important; }
623   th&,
624   td&     { display: table-cell !important; }
625 }
626
627 .responsive-invisibility() {
628     &,
629   tr&,
630   th&,
631   td& { display: none !important; }
632 }
633
634
635 // Grid System
636 // -----------
637
638 // Centered container element
639 .container-fixed() {
640   margin-right: auto;
641   margin-left: auto;
642   padding-left:  (@grid-gutter-width / 2);
643   padding-right: (@grid-gutter-width / 2);
644   &:extend(.clearfix all);
645 }
646
647 // Creates a wrapper for a series of columns
648 .make-row(@gutter: @grid-gutter-width) {
649   margin-left:  (@gutter / -2);
650   margin-right: (@gutter / -2);
651   &:extend(.clearfix all);
652 }
653
654 // Generate the extra small columns
655 .make-xs-column(@columns; @gutter: @grid-gutter-width) {
656   position: relative;
657   float: left;
658   width: percentage((@columns / @grid-columns));
659   min-height: 1px;
660   padding-left:  (@gutter / 2);
661   padding-right: (@gutter / 2);
662 }
663 .make-xs-column-offset(@columns) {
664   @media (min-width: @screen-xs-min) {
665     margin-left: percentage((@columns / @grid-columns));
666   }
667 }
668 .make-xs-column-push(@columns) {
669   @media (min-width: @screen-xs-min) {
670     left: percentage((@columns / @grid-columns));
671   }
672 }
673 .make-xs-column-pull(@columns) {
674   @media (min-width: @screen-xs-min) {
675     right: percentage((@columns / @grid-columns));
676   }
677 }
678
679
680 // Generate the small columns
681 .make-sm-column(@columns; @gutter: @grid-gutter-width) {
682   position: relative;
683   min-height: 1px;
684   padding-left:  (@gutter / 2);
685   padding-right: (@gutter / 2);
686
687   @media (min-width: @screen-sm-min) {
688     float: left;
689     width: percentage((@columns / @grid-columns));
690   }
691 }
692 .make-sm-column-offset(@columns) {
693   @media (min-width: @screen-sm-min) {
694     margin-left: percentage((@columns / @grid-columns));
695   }
696 }
697 .make-sm-column-push(@columns) {
698   @media (min-width: @screen-sm-min) {
699     left: percentage((@columns / @grid-columns));
700   }
701 }
702 .make-sm-column-pull(@columns) {
703   @media (min-width: @screen-sm-min) {
704     right: percentage((@columns / @grid-columns));
705   }
706 }
707
708
709 // Generate the medium columns
710 .make-md-column(@columns; @gutter: @grid-gutter-width) {
711   position: relative;
712   min-height: 1px;
713   padding-left:  (@gutter / 2);
714   padding-right: (@gutter / 2);
715
716   @media (min-width: @screen-md-min) {
717     float: left;
718     width: percentage((@columns / @grid-columns));
719   }
720 }
721 .make-md-column-offset(@columns) {
722   @media (min-width: @screen-md-min) {
723     margin-left: percentage((@columns / @grid-columns));
724   }
725 }
726 .make-md-column-push(@columns) {
727   @media (min-width: @screen-md-min) {
728     left: percentage((@columns / @grid-columns));
729   }
730 }
731 .make-md-column-pull(@columns) {
732   @media (min-width: @screen-md-min) {
733     right: percentage((@columns / @grid-columns));
734   }
735 }
736
737
738 // Generate the large columns
739 .make-lg-column(@columns; @gutter: @grid-gutter-width) {
740   position: relative;
741   min-height: 1px;
742   padding-left:  (@gutter / 2);
743   padding-right: (@gutter / 2);
744
745   @media (min-width: @screen-lg-min) {
746     float: left;
747     width: percentage((@columns / @grid-columns));
748   }
749 }
750 .make-lg-column-offset(@columns) {
751   @media (min-width: @screen-lg-min) {
752     margin-left: percentage((@columns / @grid-columns));
753   }
754 }
755 .make-lg-column-push(@columns) {
756   @media (min-width: @screen-lg-min) {
757     left: percentage((@columns / @grid-columns));
758   }
759 }
760 .make-lg-column-pull(@columns) {
761   @media (min-width: @screen-lg-min) {
762     right: percentage((@columns / @grid-columns));
763   }
764 }
765
766
767 // Framework grid generation
768 //
769 // Used only by Bootstrap to generate the correct number of grid classes given
770 // any value of `@grid-columns`.
771
772 .make-grid-columns() {
773   // Common styles for all sizes of grid columns, widths 1-12
774   .col(@index) when (@index = 1) { // initial
775     @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
776     .col((@index + 1), @item);
777   }
778   .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
779     @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
780     .col((@index + 1), ~"@{list}, @{item}");
781   }
782   .col(@index, @list) when (@index > @grid-columns) { // terminal
783     @{list} {
784       position: relative;
785       // Prevent columns from collapsing when empty
786       min-height: 1px;
787       // Inner gutter via padding
788       padding-left:  (@grid-gutter-width / 2);
789       padding-right: (@grid-gutter-width / 2);
790     }
791   }
792   .col(1); // kickstart it
793 }
794
795 .make-grid-columns-float(@class) {
796   .col(@index) when (@index = 1) { // initial
797     @item: ~".col-@{class}-@{index}";
798     .col((@index + 1), @item);
799   }
800   .col(@index, @list) when (@index =< @grid-columns) { // general
801     @item: ~".col-@{class}-@{index}";
802     .col((@index + 1), ~"@{list}, @{item}");
803   }
804   .col(@index, @list) when (@index > @grid-columns) { // terminal
805     @{list} {
806       float: left;
807     }
808   }
809   .col(1); // kickstart it
810 }
811
812 .calc-grid(@index, @class, @type) when (@type = width) and (@index > 0) {
813   .col-@{class}-@{index} {
814     width: percentage((@index / @grid-columns));
815   }
816 }
817 .calc-grid(@index, @class, @type) when (@type = push) {
818   .col-@{class}-push-@{index} {
819     left: percentage((@index / @grid-columns));
820   }
821 }
822 .calc-grid(@index, @class, @type) when (@type = pull) {
823   .col-@{class}-pull-@{index} {
824     right: percentage((@index / @grid-columns));
825   }
826 }
827 .calc-grid(@index, @class, @type) when (@type = offset) {
828   .col-@{class}-offset-@{index} {
829     margin-left: percentage((@index / @grid-columns));
830   }
831 }
832
833 // Basic looping in LESS
834 .make-grid(@index, @class, @type) when (@index >= 0) {
835   .calc-grid(@index, @class, @type);
836   // next iteration
837   .make-grid((@index - 1), @class, @type);
838 }
839
840
841 // Form validation states
842 //
843 // Used in forms.less to generate the form validation CSS for warnings, errors,
844 // and successes.
845
846 .form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {
847   // Color the label and help text
848   .help-block,
849   .control-label,
850   .radio,
851   .checkbox,
852   .radio-inline,
853   .checkbox-inline  {
854     color: @text-color;
855   }
856   // Set the border and box shadow on specific inputs to match
857   .form-control {
858     border-color: @border-color;
859     .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
860     &:focus {
861       border-color: darken(@border-color, 10%);
862       @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);
863       .box-shadow(@shadow);
864     }
865   }
866   // Set validation states also for addons
867   .input-group-addon {
868     color: @text-color;
869     border-color: @border-color;
870     background-color: @background-color;
871   }
872   // Optional feedback icon
873   .form-control-feedback {
874     color: @text-color;
875   }
876 }
877
878 // Form control focus state
879 //
880 // Generate a customized focus state and for any input with the specified color,
881 // which defaults to the `@input-focus-border` variable.
882 //
883 // We highly encourage you to not customize the default value, but instead use
884 // this to tweak colors on an as-needed basis. This aesthetic change is based on
885 // WebKit's default styles, but applicable to a wider range of browsers. Its
886 // usability and accessibility should be taken into account with any change.
887 //
888 // Example usage: change the default blue border and shadow to white for better
889 // contrast against a dark gray background.
890
891 .form-control-focus(@color: @input-border-focus) {
892   @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);
893   &:focus {
894     border-color: @color;
895     outline: 0;
896     .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}");
897   }
898 }
899
900 // Form control sizing
901 //
902 // Relative text size, padding, and border-radii changes for form controls. For
903 // horizontal sizing, wrap controls in the predefined grid classes. `<select>`
904 // element gets special love because it's special, and that's a fact!
905
906 .input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
907   height: @input-height;
908   padding: @padding-vertical @padding-horizontal;
909   font-size: @font-size;
910   line-height: @line-height;
911   border-radius: @border-radius;
912
913   select& {
914     height: @input-height;
915     line-height: @input-height;
916   }
917
918   textarea& {
919     height: auto;
920   }
921 }