carlos-sanchez
11/14/2013 - 3:52 AM

More Mixins

More Mixins

/*

A CSS preprocessor allows you to use variables, mixins, functions, 
operations, nesting, importing and much more. For that concern, 
I personally use LESS but there are also Sass or Stylus which might fit your needs.

Anyway, I’m only going to talk about mixins here. Mixins are like variables but for whole classes. 
The best point of mixins is that they can behave like functions and have parameters.

Let’s start with something very simple: a mixin to handle all vendor prefixes whenever 
you want to apply a transform to an element.

*/

.transform(@string) {
    -webkit-transform:  @string;
    -moz-transform:     @string;
    -ms-transform:      @string;
    -o-transform:       @string;
    transform:          @string;
}


/*
Okay, that was just to show you the idea. 
Maybe we could build a mixin for every kind of transform? Or at least the most used ones?
*/

.rotate(@deg) {
    -webkit-transform:  rotate(@deg);
    -moz-transform:     rotate(@deg);
    -ms-transform:      rotate(@deg);
    -o-transform:       rotate(@deg);
    transform:          rotate(@deg);
}
 
.scale(@factor) {
    -webkit-transform:  scale(@factor);
    -moz-transform:     scale(@factor);
    -ms-transform:      scale(@factor);
    -o-transform:       scale(@factor);
    transform:          scale(@factor);
}
 
.translate (@x, @y) {
    -webkit-transform:  translate(@x, @y);
    -moz-transform:     translate(@x, @y);
    -ms-transform:      translate(@x, @y);
    -o-transform:       translate(@x, @y);
    transform:          translate(@x, @y);
}


/*

The only point of those mixins is to avoid writing vendor prefixes. Let’s go up a level.

*/

.transition(@string: all 0.3s ease-out) {
    -webkit-transition: @string;
    -moz-transition:    @string;
    -ms-transition:     @string;
    -o-transition:      @string;
    transition:         @string;
}


/*
What does this mixin do exactly? It takes as a value all 0.3s ease-out if no value 
is specified. This is where it’s getting interesting. From now on 
(unless I want a very specific transition) I don’t have to set a value to transition anymore. 
I only have to do this:
*/

.my-element {
    .transition;
}
 
/* Output CSS */
 
.my-element {
    -webkit-transition: all 0.3s ease-out;
    -moz-transition: all 0.3s ease-out;
    -ms-transition: all 0.3s ease-out;
    -o-transition: all 0.3s ease-out;
    transition: all 0.3s ease-out;
}

/*
Another example would be to create a mixin that handles the box-sizing property with
 a default parameter. Something like:
 */
 
 .box-sizing(@value: border-box) {
    -webkit-box-sizing: @value;
    -moz-box-sizing:    @value;
    -box-sizing:        @value;
}
 
*, *:before, *:after {
    .box-sizing;
}
 
/* Output CSS */
 
*, *:before, *:after {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}


/*
We often associate preprocessors with CSS3, mostly because of the power
 of these previous examples, but you can of course, do perfectly valid CSS2.1 with
  preprocessors and find plenty of cases where you might “need” them.
   Please, have a look at the following code:
*/

.placement(@top, @right, @bottom, @left) {
    top: @top;
    right: @right;
    bottom: @bottom;
    left: @left;
}
 
.my-element {
    position: absolute;
    .placement(0, 0, 0, 0);
}
 
/* Output CSS */
 
.my-element {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

/*
How cool is that? I’ve waited for ages to have a shorthand for this.
 I always found it annoying to have to type the 4 placement properties 
 over and over again. We could even tweak it to include the type of position.
*/

.placement(@type, @top, @right, @bottom, @left) {
    position: @type;
    top: @top;
    right: @right;
    bottom: @bottom;
    left: @left;
}
 
.my-element {
    .placement(absolute, 0, 0, 0, 0);
}
 
/* Output CSS */
 
.my-element {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
}

/*
I’d like to end with a very useful mixin mixing (see what I did there?)
CSS2.1 and CSS3 in order to provide something which could be very annoying
to do manually: a rem/px converter.

Rem stands for “root em”. Its behavior is similar to the em unit except 
that it’s relative to the root element, not its parent element. 
Every major browser now supports it except Opera Mini and Internet Explorer 6/7. 
For those browsers, we have to provide a fallback in px.
*/

.font-size($pxValue){
    @remValue: (@pxValue / 10);
    font-size: ~"@{pxValue}px";
    font-size: ~"@{remValue}rem";
}
 
html { font-size: 62.5%; }
 
.my-element {
    .font-size(13px);
}
 
/* Output CSS */
 
.my-element {
    font-size: 13px;   /* Internet Explorer 6/7/8 + Opera Mini */
    font-size: 1.3rem; /* Other browsers */
}

/*
Basically, you set the font-size you want in pixels, 
and it gives you both px and rem. Easy peasy, end of story.

Note: the font-size: 62.5% thing on the html element is for 
switching to base 10 for the ease of calculations (default 16px * 62.5 / 100 = 10). 
From there, it’s easy to say 1.3rem + 13px.
*/