mixins.less 17.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
}

Mark Otto's avatar
Mark Otto committed
30
31
32
// Webkit-style focus
.tab-focus() {
  // Default
33
  outline: thin dotted #333;
Mark Otto's avatar
Mark Otto committed
34
35
36
37
38
  // Webkit
  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
58
59
60
  &:-moz-placeholder            { color: @color; } // Firefox 4-18
  &::-moz-placeholder           { color: @color; } // Firefox 19+
  &:-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
72
// CSS image replacement
// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757
73
.hide-text() {
74
75
  font: 0/0 a;
  color: transparent;
76
  text-shadow: none;
77
  background-color: transparent;
78
  border: 0;
79
}
80

81

82

83
84
85
// CSS3 PROPERTIES
// --------------------------------------------------

86
// Single side border-radius
87
.border-top-radius(@radius) {
88
89
  border-top-right-radius: @radius;
   border-top-left-radius: @radius;
90
91
}
.border-right-radius(@radius) {
92
93
  border-bottom-right-radius: @radius;
     border-top-right-radius: @radius;
Mark Otto's avatar
Mark Otto committed
94
95
}
.border-bottom-radius(@radius) {
96
97
  border-bottom-right-radius: @radius;
   border-bottom-left-radius: @radius;
Mark Otto's avatar
Mark Otto committed
98
99
}
.border-left-radius(@radius) {
100
101
  border-bottom-left-radius: @radius;
     border-top-left-radius: @radius;
102
103
}

104
// Drop shadows
Mark Otto's avatar
Mark Otto committed
105
.box-shadow(@shadow) {
106
  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1
107
          box-shadow: @shadow;
108
109
110
}

// Transitions
Mark Otto's avatar
Mark Otto committed
111
112
113
114
115
.transition(@transition) {
  -webkit-transition: @transition;
     -moz-transition: @transition;
       -o-transition: @transition;
          transition: @transition;
116
}
Tunghsiao Liu's avatar
Tunghsiao Liu committed
117
118
119
120
121
122
.transition-delay(@transition-delay) {
  -webkit-transition-delay: @transition-delay;
     -moz-transition-delay: @transition-delay;
       -o-transition-delay: @transition-delay;
          transition-delay: @transition-delay;
}
Tunghsiao Liu's avatar
Tunghsiao Liu committed
123
124
125
126
127
128
.transition-duration(@transition-duration) {
  -webkit-transition-duration: @transition-duration;
     -moz-transition-duration: @transition-duration;
       -o-transition-duration: @transition-duration;
          transition-duration: @transition-duration;
}
129

Mark Otto's avatar
Mark Otto committed
130
// Transformations
131
.rotate(@degrees) {
132
133
  -webkit-transform: rotate(@degrees);
     -moz-transform: rotate(@degrees);
Mark Otto's avatar
Mark Otto committed
134
135
      -ms-transform: rotate(@degrees);
       -o-transform: rotate(@degrees);
136
137
          transform: rotate(@degrees);
}
138
139
140
141
142
143
.scale(@ratio) {
  -webkit-transform: scale(@ratio);
     -moz-transform: scale(@ratio);
      -ms-transform: scale(@ratio);
       -o-transform: scale(@ratio);
          transform: scale(@ratio);
144
}
145
.translate(@x, @y) {
Mark Otto's avatar
Mark Otto committed
146
147
148
149
150
151
  -webkit-transform: translate(@x, @y);
     -moz-transform: translate(@x, @y);
      -ms-transform: translate(@x, @y);
       -o-transform: translate(@x, @y);
          transform: translate(@x, @y);
}
152
.skew(@x, @y) {
Mark Otto's avatar
Mark Otto committed
153
154
  -webkit-transform: skew(@x, @y);
     -moz-transform: skew(@x, @y);
155
      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twitter/bootstrap/issues/4885
Mark Otto's avatar
Mark Otto committed
156
157
158
       -o-transform: skew(@x, @y);
          transform: skew(@x, @y);
}
159
.translate3d(@x, @y, @z) {
160
161
162
163
  -webkit-transform: translate3d(@x, @y, @z);
     -moz-transform: translate3d(@x, @y, @z);
       -o-transform: translate3d(@x, @y, @z);
          transform: translate3d(@x, @y, @z);
164
}
165

166
167
168
169
// Backface visibility
// Prevent browsers from flickering when using CSS 3D transforms.
// Default value is `visible`, but can be changed to `hidden
// See git pull https://github.com/dannykeane/bootstrap.git backface-visibility for examples
170
.backface-visibility(@visibility){
171
	-webkit-backface-visibility: @visibility;
172
173
	   -moz-backface-visibility: @visibility;
	        backface-visibility: @visibility;
174
175
}

176
// Background clipping
Mark Otto's avatar
Mark Otto committed
177
178
179
180
.background-clip(@clip) {
  -webkit-background-clip: @clip;
     -moz-background-clip: @clip;
          background-clip: @clip;
181
182
}

183
// Background sizing
184
.background-size(@size) {
Mark Otto's avatar
Mark Otto committed
185
186
187
188
  -webkit-background-size: @size;
     -moz-background-size: @size;
       -o-background-size: @size;
          background-size: @size;
189
190
}

191
192
193
194
195
196
197
// Box sizing
.box-sizing(@boxmodel) {
  -webkit-box-sizing: @boxmodel;
     -moz-box-sizing: @boxmodel;
          box-sizing: @boxmodel;
}

198
199
200
201
202
// User select
// For selecting text on the page
.user-select(@select) {
  -webkit-user-select: @select;
     -moz-user-select: @select;
Han Lin Yap's avatar
Han Lin Yap committed
203
      -ms-user-select: @select;
204
205
206
207
       -o-user-select: @select;
          user-select: @select;
}

208
// Resize anything
209
.resizable(@direction) {
210
211
212
213
  resize: @direction; // Options: horizontal, vertical, both
  overflow: auto; // Safari fix
}

214
// CSS3 Content Columns
215
216
217
218
219
220
221
.content-columns(@column-count, @column-gap: @grid-gutter-width) {
  -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;
222
223
}

Synchro's avatar
Synchro committed
224
225
// Optional hyphenation
.hyphens(@mode: auto) {
Mark Otto's avatar
Mark Otto committed
226
  word-wrap: break-word;
Synchro's avatar
Synchro committed
227
228
229
  -webkit-hyphens: @mode;
     -moz-hyphens: @mode;
      -ms-hyphens: @mode;
Synchro's avatar
Synchro committed
230
       -o-hyphens: @mode;
Synchro's avatar
Synchro committed
231
232
233
          hyphens: @mode;
}

234
// Opacity
235
.opacity(@opacity) {
236
237
  opacity: @opacity;
  // IE8 filter
238
  @opacity-ie: (@opacity * 100);
239
  filter: ~"alpha(opacity=@{opacity-ie})";
240
241
242
243
244
245
246
}



// BACKGROUNDS
// --------------------------------------------------

247
248
// Gradients
#gradient {
249
  .horizontal(@startColor: #555, @endColor: #333) {
250
    background-color: @endColor;
251
    background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
252
    background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+
253
    background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+
254
    background-image: linear-gradient(to right, @startColor, @endColor); // Standard, IE10
255
    background-repeat: repeat-x;
256
    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@startColor),argb(@endColor))); // IE9 and down
257
  }
258
  .vertical(@startColor: #555, @endColor: #333) {
259
    background-color: @endColor;
260
    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
Mark Otto's avatar
Mark Otto committed
261
    background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+
262
    background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+
263
    background-image: linear-gradient(to bottom, @startColor, @endColor); // Standard, IE10
264
    background-repeat: repeat-x;
265
    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down
266
  }
267
  .directional(@startColor: #555, @endColor: #333, @deg: 45deg) {
268
269
    background-color: @endColor;
    background-repeat: repeat-x;
270
    background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+
271
    background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+
272
    background-image: linear-gradient(@deg, @startColor, @endColor); // Standard, IE10
273
  }
Francisco arenas's avatar
Francisco arenas committed
274
275
276
277
278
279
280
  .horizontal-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) {
    background-color: mix(@midColor, @endColor, 80%);
    background-image: -webkit-gradient(left, linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor));
    background-image: -webkit-linear-gradient(left, @startColor, @midColor @colorStop, @endColor);
    background-image: -moz-linear-gradient(left, @startColor, @midColor @colorStop, @endColor);
    background-image: linear-gradient(to right, @startColor, @midColor @colorStop, @endColor);
    background-repeat: no-repeat;
281
    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback
Francisco arenas's avatar
Francisco arenas committed
282
283
  }

sankage's avatar
sankage committed
284
  .vertical-three-colors(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) {
285
    background-color: mix(@midColor, @endColor, 80%);
286
    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor));
sankage's avatar
sankage committed
287
    background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor);
288
    background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor);
sankage's avatar
sankage committed
289
    background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor);
290
    background-repeat: no-repeat;
291
    filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",argb(@startColor),argb(@endColor))); // IE9 and down, gets no color-stop at all for proper fallback
292
  }
293
  .radial(@innerColor: #555, @outerColor: #333) {
294
295
296
297
    background-color: @outerColor;
    background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor));
    background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor);
    background-image: -moz-radial-gradient(circle, @innerColor, @outerColor);
298
    background-image: radial-gradient(circle, @innerColor, @outerColor);
299
300
    background-repeat: no-repeat;
  }
301
  .striped(@color: #555, @angle: 45deg) {
Piotrek Okoński's avatar
Piotrek Okoński committed
302
    background-color: @color;
303
304
305
306
    background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent));
    background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
    background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
    background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent);
Piotrek Okoński's avatar
Piotrek Okoński committed
307
  }
308
}
309
310
// Reset filters for IE
.reset-filter() {
311
  filter: e(%("progid:DXImageTransform.Microsoft.gradient(enabled = false)"));
312
}
313

314

Danny Keane's avatar
Danny Keane committed
315
316
317
// RETINA IMAGE SUPPORT
// --------------------------------------------------

Mark Otto's avatar
Mark Otto committed
318
319
320
321
322
323
324
325
326
327
328
329
330
331
// Short retina mixin for setting background-image and -size
.retina-image(@file-1x, @file-2x, @width-1x, @height-1x) {
  background-image: url("@{file-1x}");

  @media
  only screen and (-webkit-min-device-pixel-ratio: 2),
  only screen and (   min--moz-device-pixel-ratio: 2),
  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
332
333
}

334
335
336
337

// COMPONENT MIXINS
// --------------------------------------------------

338
// Horizontal dividers
339
340
// -------------------------
// Dividers (basically an hr) within dropdowns and nav lists
341
.nav-divider(@top: #e5e5e5, @bottom: #fff) {
Mark Otto's avatar
Mark Otto committed
342
  height: 2px; // 1px for background, one for border
Mark Otto's avatar
Mark Otto committed
343
  margin: ((@line-height-base / 2) - 1) 0;
Jacob Thornton's avatar
Jacob Thornton committed
344
  overflow: hidden;
345
346
  background-color: @top;
  border-bottom: 1px solid @bottom;
347
348
}

349
350
351
352
353
354
355
// Button psuedo states
// -------------------------
// Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons
.btn-pseudo-states(@background, @border) {
  background-color: @background;
  border-color: @border;
356

Mark Otto's avatar
Mark Otto committed
357
  &:hover,
358
  &:focus,
359
360
  &:active,
  &.active {
361
362
    background-color: darken(@background, 5%);
        border-color: darken(@border, 10%);
Mark Otto's avatar
Mark Otto committed
363
  }
364

365
  &.disabled,
366
  &[disabled],
367
  fieldset[disabled] & {
368
369
    &:hover,
    &:focus,
370
371
    &:active,
    &.active {
372
373
374
      background-color: @background;
          border-color: @border
    }
375
376
377
  }
}

378
379
380
381
// Navbar vertical align
// -------------------------
// Vertically center elements in the navbar.
// Example: an element has a height of 30px, so write out `.navbarVerticalAlign(30px);` to calculate the appropriate top margin.
Mark Otto's avatar
Mark Otto committed
382
.navbar-vertical-align(@element-height) {
383
384
  margin-top: ((@navbar-height - @element-height) / 2);
  margin-bottom: ((@navbar-height - @element-height) / 2);
385
386
}

387

388
389
390
391

// Grid System
// -----------

392
// Centered container element
393
394
.container-fixed() {
  margin-right: auto;
Jacob Thornton's avatar
Jacob Thornton committed
395
  margin-left: auto;
396
  .clearfix();
397
398
}

399
// Make a grid
400

401
// Creates a wrapper for a series of columns
402
.make-row() {
403
  // Then clear the floated columns
404
  .clearfix();
405
406
407
408
409
410

  // Negative margin nested rows out to align the content of columns
  .row {
    margin-left:  (@grid-gutter-width / -2);
    margin-right: (@grid-gutter-width / -2);
  }
411
}
412
// Generate the columns
413
.make-column(@columns) {
414
415
416
  @media (min-width: @grid-float-breakpoint) {
    float: left;
    // Calculate width based on number of columns available
Chris Rebert's avatar
Chris Rebert committed
417
    width: percentage((@columns / @grid-columns));
418
419
420
421
422
423
  }
  // Prevent columns from collapsing when empty
  min-height: 1px;
  // Set inner padding as gutters instead of margin
  padding-left:  (@grid-gutter-width / 2);
  padding-right: (@grid-gutter-width / 2);
424
}
425
// Generate the column offsets
426
.make-column-offset(@columns) {
427
428
429
430
431
432
433
434
435
436
437
438
439
  @media (min-width: @grid-float-breakpoint) {
    margin-left: percentage((@columns / @grid-columns));
  }
}
.make-column-push(@columns) {
  @media (min-width: @grid-float-breakpoint) {
    left: percentage((@columns / @grid-columns));
  }
}
.make-column-pull(@columns) {
  @media (min-width: @grid-float-breakpoint) {
    right: percentage((@columns / @grid-columns));
  }
440
}
441
442
443
444
445
446
447
448
449
450
// Small, mobile-first columns
.make-small-column(@columns) {
  position: relative;
  float: left;
  // Prevent columns from collapsing when empty
  min-height: 1px;
  // Set inner padding as gutters instead of margin
  padding-left:  (@grid-gutter-width / 2);
  padding-right: (@grid-gutter-width / 2);
}
451

452

453

454
455
// The Grid
.generate-grid-columns(@grid-columns) {
456

457
  // Default columns
Mark Otto's avatar
Mark Otto committed
458
459
460
  .col-span-X (@index) when (@index > 0) {
    .col-span-@{index} { .col-span-(@index); }
    .col-span-X((@index - 1));
461
  }
Mark Otto's avatar
Mark Otto committed
462
  .col-span-X(0) {}
463

464
  // Offsets (gaps between columns)
Mark Otto's avatar
Mark Otto committed
465
466
467
  .col-offset-X (@index) when (@index > 0) {
    .col-offset-@{index} { .col-offset-(@index); }
    .col-offset-X((@index - 1));
468
  }
Mark Otto's avatar
Mark Otto committed
469
  .col-offset-X (0) {}
470

471
  // Source ordering
Mark Otto's avatar
Mark Otto committed
472
473
474
  .col-push-X (@index) when (@index > 0) {
    .col-push-@{index} { .col-push-(@index); }
    .col-push-X((@index - 1));
475
  }
Mark Otto's avatar
Mark Otto committed
476
  .col-push-X (0) {}
477

478
  // Source ordering
Mark Otto's avatar
Mark Otto committed
479
480
481
  .col-pull-X (@index) when (@index > 0) {
    .col-pull-@{index} { .col-pull-(@index); }
    .col-pull-X((@index - 1));
482
  }
Mark Otto's avatar
Mark Otto committed
483
  .col-pull-X (0) {}
484

485
  // Apply the styles
Mark Otto's avatar
Mark Otto committed
486
  .col-span-(@columns) {
487
488
    width: percentage((@columns / @grid-columns));
  }
Mark Otto's avatar
Mark Otto committed
489
  .col-offset-(@columns) {
490
491
    margin-left: percentage((@columns / @grid-columns));
  }
Mark Otto's avatar
Mark Otto committed
492
  .col-push-(@columns) {
493
    left: percentage((@columns / @grid-columns));
494
  }
Mark Otto's avatar
Mark Otto committed
495
  .col-pull-(@columns) {
496
497
498
499
    right: percentage((@columns / @grid-columns));
  }

  // Generate .spanX and .offsetX
Mark Otto's avatar
Mark Otto committed
500
501
502
503
  .col-span-X(@grid-columns);
  .col-offset-X(@grid-columns);
  .col-push-X(@grid-columns);
  .col-pull-X(@grid-columns);
504
}
Mark Otto's avatar
Mark Otto committed
505

506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
// Small device grid
.generate-small-grid-columns(@grid-columns) {

  // Deterimine the classes
  .col-small-span-X (@index) when (@index > 0) {
    .col-small-span-@{index} { .col-small-span-(@index); }
    .col-small-span-X((@index - 1));
  }
  .col-small-span-X(0) {}

  // Specify widths
  .col-small-span-(@columns) {
    width: percentage((@columns / @grid-columns));
  }

  // Generate the CSS
  .col-small-span-X(@grid-columns);
}
Mark Otto's avatar
Mark Otto committed
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554


// Framework mixins
// --------------------------------------------------

// Generate rem font-sizes with pixel fallbacks
// By default uses `@font-size-base` with an initial value of 14 (1.4rem or 14px)
.font-size(@font-size: @font-size-base) {
  @rem-size: (@font-size / 10);
  font-size: ~"@{font-size}px";
  font-size: ~"@{rem-size}rem";
}

// Generate form validation states
.formFieldState(@text-color: #555, @border-color: #ccc, @background-color: #f5f5f5) {
  // Color the label text
  .control-label {
    color: @text-color;
  }
  // Set the border and box shadow on specific inputs to match
  .input-with-feedback {
    padding-right: 32px; // to account for the feedback icon
    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);
    }
  }
}