Mixins - Chapter 5

  • 0
Let me remind you, you will be hearing this term "mix-ins" a 1000 times from now onwards, and another ten thousand times if you are in an actual sass implementation project.
Sounds like an alien term, but actually isnt.

Just like we create functions in javascript, and cut paste reuseable chunks of logics inside the function, and call it from some part of the code, Mixins also does a similar thing.
  /*Create a function*/
  function Calculate(){
    var a = 20;
    var b = 10;
    var sum = a + b;
    return sum;
  }
  /*Call a function*/
  var cost = Calculate();
  
  /*Functions that accepts parameters */
  function CalcumateSum(param1, param2){
    var total = parseInt(param1) + parseInt(param2);
    return total;
  }
  
  var newCost = CalcumateSum(10,20);

We can have parameterized functions. So does parameterized mixins.
The vendor prefixes, the box shadows, the border-radiuses, list-item-styles, bulleted lists, non-bulletted lists , clearfix, etc are perfect choices to be placed as mixins and called from various part of the application.

Lets go to css3 button generator and create  a button with a ton of features.
.btn {
  background: #3498db;
  background-image: -webkit-linear-gradient(top, #3498db, #2980b9);
  background-image: -moz-linear-gradient(top, #3498db, #2980b9);
  background-image: -ms-linear-gradient(top, #3498db, #2980b9);
  background-image: -o-linear-gradient(top, #3498db, #2980b9);
  background-image: linear-gradient(to bottom, #3498db, #2980b9);
  -webkit-border-radius: 28;
  -moz-border-radius: 28;
  border-radius: 28px;
  font-family: Arial;
  color: #ffffff;
  font-size: 28px;
  padding: 10px 30px 10px 30px;
  text-decoration: none;
}

.btn:hover {
  background: #3cb0fd;
  background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db);
  background-image: -moz-linear-gradient(top, #3cb0fd, #3498db);
  background-image: -ms-linear-gradient(top, #3cb0fd, #3498db);
  background-image: -o-linear-gradient(top, #3cb0fd, #3498db);
  background-image: linear-gradient(to bottom, #3cb0fd, #3498db);
  text-decoration: none;
}
We can see that the class itself is a mix of a lot of properties, vendor prefixes etc.
This is a good example of introducing the mixins concepts to create something that can be reused.

One section is for the background gradient, the other for border radius, and the other for hover if we can split the class accordingly. rather than mixing them up like a spaghetti sauce, separate them so that we get more opportunity to reuse them.

We can visualize mixin more or like a "Ctrl + C " followed by "Ctrl + V". It just copy pastes some chunk of styles from one area to other. Thats it. So keep in mind that the code will be duplicated as many times as the mixin is called. What all styles written inside the mixin, will be

To create a mixin, all we need to do is use "@mixin" followed by the name of the mixin.



Here we have created three mixins.
In the sass section at left, we can see , At Line 5, 13, and 18, we have created three mixins.

To use a mixin, we should use the "@include" along with the name of the mixin.
At lines 27, 28, 35, we can see that the three mixins has been included in our scss styles.
Check out the compiled css styles in the middle section.

The problem with this is that, the mixin is only useful if and only if we need a blueish button having a linear gradient and  with 28px border-radius.  What if we need to tweak the color of the gradient a bit? What is we need a flat button, what of we need a different hover style altogether?

We need to keep coming back at the mixin and change them continuously, or copy paste and create more and more mixins. ( Both doesnt help the principle of DRY - Or "Do not Repeat Yourselves" ).
We are trying to optimize the scss styles to the maximum possible extend. So as far as we can, Write less, and reuse more.

If we take a closer look, the linear gradient style and its corresponding hover style are same, but just that it accepts two different set of parameters only right? So could we have reused it rather than duplicated the same?

We can have a 100 mixins, but only those which are used will be reflected in our final output css.
Thats good news! So no unnecessary bloating of styles. If we use it , it will be in the output css, else wont. As simple as that.

PARAMETRIC MIXINS
Just like function accepts parameters, as we have discussed before, mixins too can accept parameters
/*Parametric mixins */
@mixin linear-gradient($posn,$start,$stop) {
    background: $start;
    background-image: -webkit-linear-gradient($posn, $start, $stop);
    background-image: -moz-linear-gradient($posn, $start, $stop);
    background-image: -ms-linear-gradient($posn, $start, $stop);
    background-image: -o-linear-gradient($posn, $start, $stop);
    background-image: linear-gradient(to bottom, $start, $stop);     
}
@mixin border-radius($radius){
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    border-radius: $radius;     
}

.btn {
  
  @include linear-gradient(top, #3498db, #2980b9);
  @include border-radius(28px); 
  font-family: Arial;
  color: #ffffff;
  font-size: 28px;
  padding: 10px 30px 10px 30px;
  text-decoration: none;
  
  &:hover{
      @include linear-gradient(top, #3498db, #2980b9);
      text-decoration:none;
  }
}

Here, our mixins accepts parameters.
To pass in a parameter, just use the braces right after the mixin name and pass the required ones as needed, making sure that we prefix the parameters with $.
eg: @include border-radius(28px);

Similarly the gradient colors too and its position is passed in as an argument.

We can see that we have removed the hover specific mixin from the previous example and reused the linear-gradient mixin by passing different set of params for the hover class as well.

PARAMETRIC MIXIN WITH DEFAULT VALUES:

We can pass in default values in case if we like to just use the mixin name only and only pass in parameters if we need to alter a default set of values.
/*Parametric mixins with default values */
@mixin linear-gradient($posn:top,$start:#3498db,$stop:#2980b9) {
    background: $start;
    background-image: -webkit-linear-gradient($posn, $start, $stop);
    background-image: -moz-linear-gradient($posn, $start, $stop);
    background-image: -ms-linear-gradient($posn, $start, $stop);
    background-image: -o-linear-gradient($posn, $start, $stop);
    background-image: linear-gradient(to bottom, $start, $stop);     
}
@mixin border-radius($radius:28px){
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    border-radius: $radius;     
}

.btn {  
  @include linear-gradient; /*no params passed here*/
  @include border-radius; /*no params passed here*/
  font-family: Arial;
  color: #ffffff;
  font-size: 28px;
  padding: 10px 30px 10px 30px;
  text-decoration: none;  
  &:hover{
      @include linear-gradient(top, #3498db, #2980b9);
      text-decoration:none;
  }
}

The linear-gradient and border-radius mixin are called as such without the brackets. And the same mixin is called with custom parameters  for the hover.

Feel free to play around the same at the sassmeister code above and see instant changes.

So bottom-line:
  1. Mixins is more or less copy pasting the code .
  2. You have a mixin with 10 lines, and call it in 3 different classes, that makes 30 lines of css in your final css output.
  3. It doesnt help duplication or redundancy
  4. What we would ideally want is to group the styles so that common ones are written only once followed by the specific property separately in a different class. That is what "Extend" does, and will take a look at that soon.

No comments:

Post a Comment