mixins.less 26.4 KB
Newer Older
1
2
3
//
// Mixins
// --------------------------------------------------
4

5

6
7
// Utilities
// -------------------------
8
9

// Clearfix
10
11
12
13
14
15
16
17
18
// Source: http://nicolasgallagher.com/micro-clearfix-hack/
//
// For modern browsers
// 1. The space content is one way to avoid an Opera bug when the
//    contenteditable attribute is included anywhere else in the document.
//    Otherwise it causes space to appear at the top and bottom of elements
//    that are clearfixed.
// 2. The use of `table` rather than `block` is only necessary if using
//    `:before` to contain the top-margins of child elements.
19
.clearfix() {
20
  &:before,
21
  &:after {
22
23
    content: " "; // 1
    display: table; // 2
24
25
  }
  &:after {
26
    clear: both;
27
  }
28
29
}

Chris Rebert's avatar
Chris Rebert committed
30
// WebKit-style focus
Mark Otto's avatar
Mark Otto committed
31
32
.tab-focus() {
  // Default
33
  outline: thin dotted;
34
  // WebKit
Mark Otto's avatar
Mark Otto committed
35
36
37
38
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}

39
// Center-align a block level element
40
.center-block() {
41
  display: block;
42
43
  margin-left: auto;
  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
Mark Otto's avatar
Mark Otto committed
56
.placeholder(@color: @input-color-placeholder) {
57
  &::-moz-placeholder           { color: @color;   // Firefox
58
                                  opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526
59
60
  &:-ms-input-placeholder       { color: @color; } // Internet Explorer 10+
  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome
61
62
}

Mark Otto's avatar
Mark Otto committed
63
64
65
66
67
68
69
70
// Text overflow
// Requires inline-block or block for proper styling
.text-overflow() {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

71
// CSS image replacement
72
73
74
//
// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for
// mixins being reused as classes with the same name, this doesn't hold up. As
75
76
// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note
// that we cannot chain the mixins together in Less, so they are repeated.
77
//
78
// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
79

80
81
82
83
84
85
86
87
88
// Deprecated as of v3.0.1 (will be removed in v4)
.hide-text() {
  font: ~"0/0" a;
  color: transparent;
  text-shadow: none;
  background-color: transparent;
  border: 0;
}
// New mixin to use as of v3.0.1
89
.text-hide() {
90
  .hide-text();
91
}
92

93

94

95
96
97
// CSS3 PROPERTIES
// --------------------------------------------------

98
// Single side border-radius
99
.border-top-radius(@radius) {
100
101
  border-top-right-radius: @radius;
   border-top-left-radius: @radius;
102
103
}
.border-right-radius(@radius) {
104
105
  border-bottom-right-radius: @radius;
     border-top-right-radius: @radius;
Mark Otto's avatar
Mark Otto committed
106
107
}
.border-bottom-radius(@radius) {
108
109
  border-bottom-right-radius: @radius;
   border-bottom-left-radius: @radius;
Mark Otto's avatar
Mark Otto committed
110
111
}
.border-left-radius(@radius) {
112
113
  border-bottom-left-radius: @radius;
     border-top-left-radius: @radius;
114
115
}

116
// Drop shadows
117
118
119
120
//
// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's
//   supported browsers that have box shadow capabilities now support the
//   standard `box-shadow` property.
Mark Otto's avatar
Mark Otto committed
121
.box-shadow(@shadow) {
122
  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
123
          box-shadow: @shadow;
124
125
126
}

// Transitions
Mark Otto's avatar
Mark Otto committed
127
128
129
.transition(@transition) {
  -webkit-transition: @transition;
          transition: @transition;
130
}
131
132
133
134
.transition-property(@transition-property) {
  -webkit-transition-property: @transition-property;
          transition-property: @transition-property;
}
Tunghsiao Liu's avatar
Tunghsiao Liu committed
135
136
137
138
.transition-delay(@transition-delay) {
  -webkit-transition-delay: @transition-delay;
          transition-delay: @transition-delay;
}
Tunghsiao Liu's avatar
Tunghsiao Liu committed
139
140
141
142
.transition-duration(@transition-duration) {
  -webkit-transition-duration: @transition-duration;
          transition-duration: @transition-duration;
}
143
144
145
146
147
148
.transition-transform(@transition) {
  -webkit-transition: -webkit-transform @transition;
     -moz-transition: -moz-transform @transition;
       -o-transition: -o-transform @transition;
          transition: transform @transition;
}
149

Mark Otto's avatar
Mark Otto committed
150
// Transformations
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
.scale(@ratio) {
  -webkit-transform: scale(@ratio);
      -ms-transform: scale(@ratio); // IE9 only
          transform: scale(@ratio);
}
.scale(@ratioX; @ratioY) {
  -webkit-transform: scale(@ratioX, @ratioY);
      -ms-transform: scale(@ratioX, @ratioY); // IE9 only
          transform: scale(@ratioX, @ratioY);
}
.scaleX(@ratio) {
  -webkit-transform: scaleX(@ratio);
      -ms-transform: scaleX(@ratio); // IE9 only
          transform: scaleX(@ratio);
}
.scaleY(@ratio) {
  -webkit-transform: scaleY(@ratio);
      -ms-transform: scaleY(@ratio); // IE9 only
          transform: scaleY(@ratio);
170
}
171
172
173
174
.skew(@x; @y) {
  -webkit-transform: skew(@x, @y);
      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+
          transform: skew(@x, @y);
175
}
176
.translate(@x; @y) {
Mark Otto's avatar
Mark Otto committed
177
  -webkit-transform: translate(@x, @y);
178
      -ms-transform: translate(@x, @y); // IE9 only
Mark Otto's avatar
Mark Otto committed
179
180
          transform: translate(@x, @y);
}
181
.translate3d(@x; @y; @z) {
182
183
  -webkit-transform: translate3d(@x, @y, @z);
          transform: translate3d(@x, @y, @z);
184
}
185
186
187
188
189
.rotate(@degrees) {
  -webkit-transform: rotate(@degrees);
      -ms-transform: rotate(@degrees); // IE9 only
          transform: rotate(@degrees);
}
190
191
.rotateX(@degrees) {
  -webkit-transform: rotateX(@degrees);
192
      -ms-transform: rotateX(@degrees); // IE9 only
193
194
195
196
          transform: rotateX(@degrees);
}
.rotateY(@degrees) {
  -webkit-transform: rotateY(@degrees);
197
      -ms-transform: rotateY(@degrees); // IE9 only
198
199
200
201
202
203
204
205
206
207
208
209
          transform: rotateY(@degrees);
}
.perspective(@perspective) {
  -webkit-perspective: @perspective;
     -moz-perspective: @perspective;
          perspective: @perspective;
}
.perspective-origin(@perspective) {
  -webkit-perspective-origin: @perspective;
     -moz-perspective-origin: @perspective;
          perspective-origin: @perspective;
}
Zlatan Vasović's avatar
Zlatan Vasović committed
210
.transform-origin(@origin) {
211
212
  -webkit-transform-origin: @origin;
     -moz-transform-origin: @origin;
213
      -ms-transform-origin: @origin; // IE9 only
214
215
216
          transform-origin: @origin;
}

Zlatan Vasović's avatar
Zlatan Vasović committed
217
218
219
220
221
// Animations
.animation(@animation) {
  -webkit-animation: @animation;
          animation: @animation;
}
Zlatan Vasović's avatar
Zlatan Vasović committed
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
.animation-name(@name) {
  -webkit-animation-name: @name;
          animation-name: @name;
}
.animation-duration(@duration) {
  -webkit-animation-duration: @duration;
          animation-duration: @duration;
}
.animation-timing-function(@timing-function) {
  -webkit-animation-timing-function: @timing-function;
          animation-timing-function: @timing-function;
}
.animation-delay(@delay) {
  -webkit-animation-delay: @delay;
          animation-delay: @delay;
}
.animation-iteration-count(@iteration-count) {
  -webkit-animation-iteration-count: @iteration-count;
          animation-iteration-count: @iteration-count;
}
.animation-direction(@direction) {
  -webkit-animation-direction: @direction;
          animation-direction: @direction;
}
246

247
248
// Backface visibility
// Prevent browsers from flickering when using CSS 3D transforms.
Chris Rebert's avatar
Chris Rebert committed
249
// Default value is `visible`, but can be changed to `hidden`
250
.backface-visibility(@visibility){
251
252
253
  -webkit-backface-visibility: @visibility;
     -moz-backface-visibility: @visibility;
          backface-visibility: @visibility;
254
255
}

256
257
258
259
260
261
262
// Box sizing
.box-sizing(@boxmodel) {
  -webkit-box-sizing: @boxmodel;
     -moz-box-sizing: @boxmodel;
          box-sizing: @boxmodel;
}

263
264
265
266
267
// User select
// For selecting text on the page
.user-select(@select) {
  -webkit-user-select: @select;
     -moz-user-select: @select;
268
      -ms-user-select: @select; // IE10+
269
270
271
          user-select: @select;
}

272
// Resize anything
273
.resizable(@direction) {
274
275
276
277
  resize: @direction; // Options: horizontal, vertical, both
  overflow: auto; // Safari fix
}

278
// CSS3 Content Columns
279
.content-columns(@column-count; @column-gap: @grid-gutter-width) {
280
281
282
283
284
285
  -webkit-column-count: @column-count;
     -moz-column-count: @column-count;
          column-count: @column-count;
  -webkit-column-gap: @column-gap;
     -moz-column-gap: @column-gap;
          column-gap: @column-gap;
286
287
}

Synchro's avatar
Synchro committed
288
289
// Optional hyphenation
.hyphens(@mode: auto) {
Mark Otto's avatar
Mark Otto committed
290
  word-wrap: break-word;
Synchro's avatar
Synchro committed
291
292
  -webkit-hyphens: @mode;
     -moz-hyphens: @mode;
293
      -ms-hyphens: @mode; // IE10+
Synchro's avatar
Synchro committed
294
       -o-hyphens: @mode;
Synchro's avatar
Synchro committed
295
296
297
          hyphens: @mode;
}

298
// Opacity
299
.opacity(@opacity) {
300
301
  opacity: @opacity;
  // IE8 filter
302
  @opacity-ie: (@opacity * 100);
303
  filter: ~"alpha(opacity=@{opacity-ie})";
304
305
306
307
}



Mark Otto's avatar
Mark Otto committed
308
// GRADIENTS
309
310
// --------------------------------------------------

311
#gradient {
Mark Otto's avatar
Mark Otto committed
312
313
314
315
316

  // Horizontal gradient, from left to right
  //
  // Creates two color stops, start and end, by specifying a color and position for each color stop.
  // Color stops are not available in IE9 and below.
317
  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
318
319
    background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+
    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+
320
    background-repeat: repeat-x;
Mark Otto's avatar
Mark Otto committed
321
    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@start-color),argb(@end-color))); // IE9 and down
322
  }
Mark Otto's avatar
Mark Otto committed
323
324
325
326
327

  // Vertical gradient, from top to bottom
  //
  // Creates two color stops, start and end, by specifying a color and position for each color stop.
  // Color stops are not available in IE9 and below.
328
  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {
329
330
    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+
    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+
331
    background-repeat: repeat-x;
Mark Otto's avatar
Mark Otto committed
332
    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@start-color),argb(@end-color))); // IE9 and down
333
  }
Mark Otto's avatar
Mark Otto committed
334

335
  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {
336
    background-repeat: repeat-x;
337
338
    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+
    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+
339
  }
340
  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
Mark Otto's avatar
Mark Otto committed
341
342
    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);
    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);
Francisco arenas's avatar
Francisco arenas committed
343
    background-repeat: no-repeat;
Mark Otto's avatar
Mark Otto committed
344
    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
Francisco arenas's avatar
Francisco arenas committed
345
  }
346
  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {
Mark Otto's avatar
Mark Otto committed
347
348
    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);
    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);
349
    background-repeat: no-repeat;
Mark Otto's avatar
Mark Otto committed
350
    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
351
  }
352
  .radial(@inner-color: #555; @outer-color: #333) {
Mark Otto's avatar
Mark Otto committed
353
354
    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);
    background-image: radial-gradient(circle, @inner-color, @outer-color);
355
356
    background-repeat: no-repeat;
  }
357
358
359
  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {
    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);
Piotrek Okoński's avatar
Piotrek Okoński committed
360
  }
361
}
Mark Otto's avatar
Mark Otto committed
362

363
// Reset filters for IE
Mark Otto's avatar
Mark Otto committed
364
//
Mike Pagé's avatar
Mike Pagé committed
365
// When you need to remove a gradient background, do not forget to use this to reset
Mark Otto's avatar
Mark Otto committed
366
// the IE filter for IE9 and below.
367
.reset-filter() {
368
  filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
369
}
370

371

Mark Otto's avatar
Mark Otto committed
372

373
374
// Retina images
//
Mark Otto's avatar
Mark Otto committed
375
// Short retina mixin for setting background-image and -size
376

377
.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {
Mark Otto's avatar
Mark Otto committed
378
379
380
381
  background-image: url("@{file-1x}");

  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
Mark Otto's avatar
Mark Otto committed
382
  only screen and (   min--moz-device-pixel-ratio: 2), // Not a typo
Mark Otto's avatar
Mark Otto committed
383
384
385
386
387
388
389
  only screen and (     -o-min-device-pixel-ratio: 2/1),
  only screen and (        min-device-pixel-ratio: 2),
  only screen and (                min-resolution: 192dpi),
  only screen and (                min-resolution: 2dppx) {
    background-image: url("@{file-2x}");
    background-size: @width-1x @height-1x;
  }
Danny Keane's avatar
Danny Keane committed
390
391
}

392

393
394
395
396
// Responsive image
//
// Keep images from scaling beyond the width of their parents.

Zlatan Vasović's avatar
Zlatan Vasović committed
397
.img-responsive(@display: block) {
398
399
400
401
402
403
  display: @display;
  max-width: 100%; // Part 1: Set a maximum relative to the parent
  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
}


404
405
406
// COMPONENT MIXINS
// --------------------------------------------------

407
// Horizontal dividers
408
409
// -------------------------
// Dividers (basically an hr) within dropdowns and nav lists
Mark Otto's avatar
Mark Otto committed
410
411
.nav-divider(@color: #e5e5e5) {
  height: 1px;
412
  margin: ((@line-height-computed / 2) - 1) 0;
Jacob Thornton's avatar
Jacob Thornton committed
413
  overflow: hidden;
Mark Otto's avatar
Mark Otto committed
414
  background-color: @color;
415
416
}

417
418
// Panels
// -------------------------
419
.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {
420
  border-color: @border;
Mark Otto's avatar
spacing    
Mark Otto committed
421

422
  & > .panel-heading {
423
424
425
    color: @heading-text-color;
    background-color: @heading-bg-color;
    border-color: @heading-border;
Mark Otto's avatar
spacing    
Mark Otto committed
426

427
    + .panel-collapse > .panel-body {
Mark Otto's avatar
Mark Otto committed
428
429
430
      border-top-color: @border;
    }
  }
431
  & > .panel-footer {
432
    + .panel-collapse > .panel-body {
Mark Otto's avatar
Mark Otto committed
433
434
      border-bottom-color: @border;
    }
435
436
437
  }
}

Chris Rebert's avatar
Chris Rebert committed
438
439
// Alerts
// -------------------------
440
.alert-variant(@background; @border; @text-color) {
Chris Rebert's avatar
Chris Rebert committed
441
442
443
  background-color: @background;
  border-color: @border;
  color: @text-color;
Mark Otto's avatar
spacing    
Mark Otto committed
444

Chris Rebert's avatar
Chris Rebert committed
445
446
447
448
449
450
451
452
  hr {
    border-top-color: darken(@border, 5%);
  }
  .alert-link {
    color: darken(@text-color, 10%);
  }
}

ggam's avatar
ggam committed
453
454
// Tables
// -------------------------
Zlatan Vasović's avatar
Zlatan Vasović committed
455
.table-row-variant(@state; @background) {
ggam's avatar
ggam committed
456
457
  // Exact selectors below required to override `.table-striped` and prevent
  // inheritance to nested tables.
458
459
460
461
462
463
464
465
  .table > thead > tr,
  .table > tbody > tr,
  .table > tfoot > tr {
    > td.@{state},
    > th.@{state},
    &.@{state} > td,
    &.@{state} > th {
      background-color: @background;
ggam's avatar
ggam committed
466
467
    }
  }
468

ggam's avatar
ggam committed
469
470
  // Hover states for `.table-hover`
  // Note: this is not available for cells or rows within `thead` or `tfoot`.
471
472
473
474
475
  .table-hover > tbody > tr {
    > td.@{state}:hover,
    > th.@{state}:hover,
    &.@{state}:hover > td,
    &.@{state}:hover > th {
ggam's avatar
ggam committed
476
477
478
479
480
      background-color: darken(@background, 5%);
    }
  }
}

481
482
// List Groups
// -------------------------
Mark Otto's avatar
Mark Otto committed
483
484
485
.list-group-item-variant(@state; @background; @color) {
  .list-group-item-@{state} {
    color: @color;
486
    background-color: @background;
Mark Otto's avatar
Mark Otto committed
487

488
    a& {
Mark Otto's avatar
Mark Otto committed
489
      color: @color;
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504

      .list-group-item-heading { color: inherit; }

      &:hover,
      &:focus {
        color: @color;
        background-color: darken(@background, 5%);
      }
      &.active,
      &.active:hover,
      &.active:focus {
        color: #fff;
        background-color: @color;
        border-color: @color;
      }
Mark Otto's avatar
Mark Otto committed
505
    }
506
507
508
  }
}

509
// Button variants
510
511
512
// -------------------------
// Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons
513
.button-variant(@color; @background; @border) {
514
  color: @color;
515
516
  background-color: @background;
  border-color: @border;
517

Mark Otto's avatar
Mark Otto committed
518
  &:hover,
519
  &:focus,
520
  &:active,
521
522
  &.active,
  .open .dropdown-toggle& {
523
    color: @color;
524
525
    background-color: darken(@background, 8%);
        border-color: darken(@border, 12%);
Mark Otto's avatar
Mark Otto committed
526
  }
527
528
529
530
531
  &:active,
  &.active,
  .open .dropdown-toggle& {
    background-image: none;
  }
532
  &.disabled,
533
  &[disabled],
534
  fieldset[disabled] & {
535
    &,
536
537
    &:hover,
    &:focus,
538
539
    &:active,
    &.active {
540
      background-color: @background;
Zlatan Vasović's avatar
Zlatan Vasović committed
541
          border-color: @border;
542
    }
543
  }
544
545
546

  .badge {
    color: @background;
547
    background-color: @color;
548
  }
549
550
}

ggam's avatar
ggam committed
551
552
553
554
555
556
557
558
559
// Button sizes
// -------------------------
.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
  padding: @padding-vertical @padding-horizontal;
  font-size: @font-size;
  line-height: @line-height;
  border-radius: @border-radius;
}

ggam's avatar
ggam committed
560
561
// Pagination
// -------------------------
Guillermo González de Agüero's avatar
Guillermo González de Agüero committed
562
.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {
ggam's avatar
ggam committed
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
  > li {
    > a,
    > span {
      padding: @padding-vertical @padding-horizontal;
      font-size: @font-size;
    }
    &:first-child {
      > a,
      > span {
        .border-left-radius(@border-radius);
      }
    }
    &:last-child {
      > a,
      > span {
        .border-right-radius(@border-radius);
      }
    }
  }
}

Chris Rebert's avatar
Chris Rebert committed
584
585
586
587
588
589
590
591
592
593
594
595
// Labels
// -------------------------
.label-variant(@color) {
  background-color: @color;
  &[href] {
    &:hover,
    &:focus {
      background-color: darken(@color, 10%);
    }
  }
}

596
597
598
599
600
601
602
603
604
// Contextual backgrounds
// -------------------------
.bg-variant(@color) {
  background-color: @color;
  a&:hover {
    background-color: darken(@color, 10%);
  }
}

605
606
607
608
// Typography
// -------------------------
.text-emphasis-variant(@color) {
  color: @color;
609
  a&:hover {
610
611
612
613
    color: darken(@color, 10%);
  }
}

614
615
616
// Navbar vertical align
// -------------------------
// Vertically center elements in the navbar.
617
// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
Mark Otto's avatar
Mark Otto committed
618
.navbar-vertical-align(@element-height) {
619
620
  margin-top: ((@navbar-height - @element-height) / 2);
  margin-bottom: ((@navbar-height - @element-height) / 2);
621
622
}

623
624
625
626
627
// Progress bars
// -------------------------
.progress-bar-variant(@color) {
  background-color: @color;
  .progress-striped & {
628
    #gradient > .striped();
629
630
631
  }
}

Mark Otto's avatar
Mark Otto committed
632
633
634
635
636
// Responsive utilities
// -------------------------
// More easily include all the states for responsive-utilities.less.
.responsive-visibility() {
  display: block !important;
637
638
  table&  { display: table; }
  tr&     { display: table-row !important; }
Mark Otto's avatar
Mark Otto committed
639
  th&,
640
  td&     { display: table-cell !important; }
Mark Otto's avatar
Mark Otto committed
641
642
}

643
.responsive-invisibility() {
Zlatan Vasović's avatar
Zlatan Vasović committed
644
  display: none !important;
645
646
}

647

648
649
650
// Grid System
// -----------

651
// Centered container element
652
653
.container-fixed() {
  margin-right: auto;
Jacob Thornton's avatar
Jacob Thornton committed
654
  margin-left: auto;
655
656
  padding-left:  (@grid-gutter-width / 2);
  padding-right: (@grid-gutter-width / 2);
657
  &:extend(.clearfix all);
658
659
}

660
// Creates a wrapper for a series of columns
661
.make-row(@gutter: @grid-gutter-width) {
662
663
  margin-left:  (@gutter / -2);
  margin-right: (@gutter / -2);
664
  &:extend(.clearfix all);
665
}
Mark Otto's avatar
Mark Otto committed
666

667
668
// Generate the extra small columns
.make-xs-column(@columns; @gutter: @grid-gutter-width) {
669
670
  position: relative;
  float: left;
671
  width: percentage((@columns / @grid-columns));
672
673
674
675
  min-height: 1px;
  padding-left:  (@gutter / 2);
  padding-right: (@gutter / 2);
}
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
.make-xs-column-offset(@columns) {
  @media (min-width: @screen-xs-min) {
    margin-left: percentage((@columns / @grid-columns));
  }
}
.make-xs-column-push(@columns) {
  @media (min-width: @screen-xs-min) {
    left: percentage((@columns / @grid-columns));
  }
}
.make-xs-column-pull(@columns) {
  @media (min-width: @screen-xs-min) {
    right: percentage((@columns / @grid-columns));
  }
}
691

Mark Otto's avatar
Mark Otto committed
692

693
// Generate the small columns
694
.make-sm-column(@columns; @gutter: @grid-gutter-width) {
695
  position: relative;
696
  min-height: 1px;
697
698
  padding-left:  (@gutter / 2);
  padding-right: (@gutter / 2);
699

700
  @media (min-width: @screen-sm-min) {
701
    float: left;
702
703
    width: percentage((@columns / @grid-columns));
  }
704
}
705
.make-sm-column-offset(@columns) {
706
  @media (min-width: @screen-sm-min) {
707
708
709
    margin-left: percentage((@columns / @grid-columns));
  }
}
710
.make-sm-column-push(@columns) {
711
  @media (min-width: @screen-sm-min) {
712
713
714
    left: percentage((@columns / @grid-columns));
  }
}
715
.make-sm-column-pull(@columns) {
716
  @media (min-width: @screen-sm-min) {
717
718
    right: percentage((@columns / @grid-columns));
  }
719
}
720

Mark Otto's avatar
Mark Otto committed
721

722
723
// Generate the medium columns
.make-md-column(@columns; @gutter: @grid-gutter-width) {
Bass Jobsen's avatar
Bass Jobsen committed
724
725
  position: relative;
  min-height: 1px;
726
727
  padding-left:  (@gutter / 2);
  padding-right: (@gutter / 2);
Mark Otto's avatar
Mark Otto committed
728

729
  @media (min-width: @screen-md-min) {
730
    float: left;
Bass Jobsen's avatar
Bass Jobsen committed
731
732
733
    width: percentage((@columns / @grid-columns));
  }
}
734
.make-md-column-offset(@columns) {
735
  @media (min-width: @screen-md-min) {
736
737
738
    margin-left: percentage((@columns / @grid-columns));
  }
}
739
.make-md-column-push(@columns) {
740
  @media (min-width: @screen-md-min) {
741
742
743
    left: percentage((@columns / @grid-columns));
  }
}
744
.make-md-column-pull(@columns) {
745
  @media (min-width: @screen-md-min) {
746
747
748
749
    right: percentage((@columns / @grid-columns));
  }
}

Mark Otto's avatar
Mark Otto committed
750

751
752
753
754
755
756
757
// Generate the large columns
.make-lg-column(@columns; @gutter: @grid-gutter-width) {
  position: relative;
  min-height: 1px;
  padding-left:  (@gutter / 2);
  padding-right: (@gutter / 2);

758
  @media (min-width: @screen-lg-min) {
759
760
761
762
763
    float: left;
    width: percentage((@columns / @grid-columns));
  }
}
.make-lg-column-offset(@columns) {
764
  @media (min-width: @screen-lg-min) {
765
766
767
768
    margin-left: percentage((@columns / @grid-columns));
  }
}
.make-lg-column-push(@columns) {
769
  @media (min-width: @screen-lg-min) {
770
771
772
773
    left: percentage((@columns / @grid-columns));
  }
}
.make-lg-column-pull(@columns) {
774
  @media (min-width: @screen-lg-min) {
775
776
777
778
    right: percentage((@columns / @grid-columns));
  }
}

Mark Otto's avatar
Mark Otto committed
779

780
781
782
783
784
785
786
787
788
// Framework grid generation
//
// Used only by Bootstrap to generate the correct number of grid classes given
// any value of `@grid-columns`.

.make-grid-columns() {
  // Common styles for all sizes of grid columns, widths 1-12
  .col(@index) when (@index = 1) { // initial
    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
789
    .col((@index + 1), @item);
790
791
792
  }
  .col(@index, @list) when (@index =< @grid-columns) { // general; "=<" isn't a typo
    @item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
793
    .col((@index + 1), ~"@{list}, @{item}");
794
795
796
797
798
799
800
801
802
803
804
805
806
807
  }
  .col(@index, @list) when (@index > @grid-columns) { // terminal
    @{list} {
      position: relative;
      // Prevent columns from collapsing when empty
      min-height: 1px;
      // Inner gutter via padding
      padding-left:  (@grid-gutter-width / 2);
      padding-right: (@grid-gutter-width / 2);
    }
  }
  .col(1); // kickstart it
}

808
.float-grid-columns(@class) {
809
810
  .col(@index) when (@index = 1) { // initial
    @item: ~".col-@{class}-@{index}";
811
    .col((@index + 1), @item);
812
  }
813
  .col(@index, @list) when (@index =< @grid-columns) { // general
814
    @item: ~".col-@{class}-@{index}";
815
    .col((@index + 1), ~"@{list}, @{item}");
816
  }
817
  .col(@index, @list) when (@index > @grid-columns) { // terminal
818
819
820
821
822
823
824
    @{list} {
      float: left;
    }
  }
  .col(1); // kickstart it
}

825
.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {
826
827
828
829
  .col-@{class}-@{index} {
    width: percentage((@index / @grid-columns));
  }
}
830
.calc-grid-column(@index, @class, @type) when (@type = push) {
831
832
833
834
  .col-@{class}-push-@{index} {
    left: percentage((@index / @grid-columns));
  }
}
835
.calc-grid-column(@index, @class, @type) when (@type = pull) {
836
837
838
839
  .col-@{class}-pull-@{index} {
    right: percentage((@index / @grid-columns));
  }
}
840
.calc-grid-column(@index, @class, @type) when (@type = offset) {
841
842
843
844
845
846
  .col-@{class}-offset-@{index} {
    margin-left: percentage((@index / @grid-columns));
  }
}

// Basic looping in LESS
847
848
.loop-grid-columns(@index, @class, @type) when (@index >= 0) {
  .calc-grid-column(@index, @class, @type);
849
  // next iteration
850
  .loop-grid-columns((@index - 1), @class, @type);
851
852
}

853
854
855
856
857
858
859
860
// Create grid for specific class
.make-grid(@class) {
  .float-grid-columns(@class);
  .loop-grid-columns(@grid-columns, @class, width);
  .loop-grid-columns(@grid-columns, @class, pull);
  .loop-grid-columns(@grid-columns, @class, push);
  .loop-grid-columns(@grid-columns, @class, offset);
}
861

Mark Otto's avatar
Mark Otto committed
862
863
864
865
866
// Form validation states
//
// Used in forms.less to generate the form validation CSS for warnings, errors,
// and successes.

867
.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {
Mark Otto's avatar
Mark Otto committed
868
  // Color the label and help text
869
  .help-block,
870
871
872
873
874
  .control-label,
  .radio,
  .checkbox,
  .radio-inline,
  .checkbox-inline  {
Mark Otto's avatar
Mark Otto committed
875
876
877
    color: @text-color;
  }
  // Set the border and box shadow on specific inputs to match
Mark Otto's avatar
Mark Otto committed
878
  .form-control {
Mark Otto's avatar
Mark Otto committed
879
880
881
882
883
884
885
886
    border-color: @border-color;
    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work
    &:focus {
      border-color: darken(@border-color, 10%);
      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);
      .box-shadow(@shadow);
    }
  }
887
888
889
890
891
  // Set validation states also for addons
  .input-group-addon {
    color: @text-color;
    border-color: @border-color;
    background-color: @background-color;
Mark Otto's avatar
Mark Otto committed
892
  }
893
  // Optional feedback icon
894
895
896
  .form-control-feedback {
    color: @text-color;
  }
Mark Otto's avatar
Mark Otto committed
897
}
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919

// Form control focus state
//
// Generate a customized focus state and for any input with the specified color,
// which defaults to the `@input-focus-border` variable.
//
// We highly encourage you to not customize the default value, but instead use
// this to tweak colors on an as-needed basis. This aesthetic change is based on
// WebKit's default styles, but applicable to a wider range of browsers. Its
// usability and accessibility should be taken into account with any change.
//
// Example usage: change the default blue border and shadow to white for better
// contrast against a dark gray background.

.form-control-focus(@color: @input-border-focus) {
  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);
  &:focus {
    border-color: @color;
    outline: 0;
    .box-shadow(~"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}");
  }
}
ggam's avatar
ggam committed
920
921
922
923
924
925
926
927
928
929
930
931
932

// Form control sizing
//
// Relative text size, padding, and border-radii changes for form controls. For
// horizontal sizing, wrap controls in the predefined grid classes. `<select>`
// element gets special love because it's special, and that's a fact!

.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {
  height: @input-height;
  padding: @padding-vertical @padding-horizontal;
  font-size: @font-size;
  line-height: @line-height;
  border-radius: @border-radius;
933

ggam's avatar
ggam committed
934
935
936
937
  select& {
    height: @input-height;
    line-height: @input-height;
  }
938

939
940
  textarea&,
  select[multiple]& {
ggam's avatar
ggam committed
941
942
943
    height: auto;
  }
}