7 min to read
Mixins
Mixins
Doing magic
Hi friends! As promised, it’s a debt here I’m bringing the post closer to share some #experiences and #tips for my dear powerful @mixins that SASS gives us .. take ittt
What is a mixin? A mixin represents a block of code that allows us to group css statements that we know we are going to reuse throughout our project.
So to create our first mixin we could create inside the styles folder, a file called _mixins.scss and write a block for a certain element, for example a title:
@mixin title {
font-size: 30px; line-height: 22px; color: $random-color-from-previous-post; font-weight: bold; }
So every time we need to include a title in our template, we will add it to the class that contains it, the mixin, our html could be something like
<h1 class="title">Title</h1>
and we are going to ask it to render that title with our convention declared in our mixin in our .scss: .title { @include title; }
With only that line we are already rendering the 4 css rules that we defined in our mixin. Whenever we have an element that we want to render with the characteristics of that title, we just write @include title; and the magic happens.
Now, we can go further and start scaling or flexing our mixin. Yes there is more magic!
If, for example, we want to keep our title structure but we want small things to vary, without altering that structure, we could modify our mixin so that it is parameterizable, then:
@mixin title($color: blue) {
font-size: 30px; line-height: 22px; colour: $colour; font-weight: bold; }
Alllllta magic there… with that we just made our mixin ready with a default title color (blue). And, if we pass another color to it from another page with another css we will continue to reuse our dynamic mixin:
.title {
@include title(red);
}
In turn, we can create another small plugin mixin:
@mixin bottom-line($color: blue, $margin: 1rem, $padding: 1rem 0) {
margin: $margin; border-bottom: 3px solid $color; padding: $padding; }
That way if we have another title that we want to draw a line under the title, with our mixin already created, we just have to write:
.title {
@include title(red);
@include bottom-line(red, 2rem, 1rem); }
Note: If we don’t pass it parameters, it would also work with the default values @include bottom-line();
Nesting
Yessily! We can nest and include other mixins within our mixin if we wish, for example we create a link-style mixin:
@mixin special-link($hover-color: white) {
text-decoration: underline; cursor: pointer; &:hover { background-color: $hover-color; } }
We created it as a mixin because the idea is to use these link rules on any element, not just titles.
@mixin title($color: blue, $hover-color) {
@include special-link($hover-color); font-size: 30px; line-height: 22px; colour: $colour; font-weight: bold; }
So now, every time we use our mixin title it will always have the link characteristics included, and not only that, but we can also define the hover color if we want a different one than the one we choose by default (the one that is almost always applied is the one we are going to choose by default):
.title {
@include title(red, black);
}
With that we are going to render our title with link and hover in black.
As we define the rules of our project, we can see how convenient it is for us to parameterize and make our mixins more flexible, and how convenient it is for us to attach options within them. For example nesting has no limits, if we want to follow the first example, instead of including 2 mixins we could add the mixin bottom-line and special-link inside the main mixin title:
@mixin title($color: blue, $hover-color, $size: 30px) {
@include special-link($hover-color); @include bottom-line(red, 2rem, 1rem); font-size: $size… }
That way we would only invoke the title mixin, if we always want to include the other mixins by default (special-link, bottom-line, etc) and we avoid always adding the same 2 or 3 mixins every time we decorate a title.
In fact, if we start to notice that we almost always include the same mixins to the same elements, the ideal is to nest them directly in the mixin and we can insert a logic for the cases in which we don’t want them… what happened? did you stay face????
arguments
Let’s see how it would be!!!
@mixin title($color: blue, $hover-color, $size: 30px, $include-specials: true) {
@if ($include-specials) { @include special-link($hover-color); @include bottom-line(red); } font-size: $size… BLA bla… }
Now in our classes we have to choose when we want the special mixins for link and bottom line NOT to be added
.title {
@include title(red, black, 30px, false);
}
@content
Just as in ANGULAR we have content projection or transclusion with ng-content, here we have something similar! with @content what we do is allow to project other blocks of code in a css block for example, let’s see:
@mixin small($width: 320px) {
@media only screen and (min-width: $width) {
@content;
}
}
@mixin tablet($width: 768px) {
@media only screen and (min-width: $width) {
@content;
}
}
@mixin desktop($width: 992px) {
@media only screen and (min-width: $width) {
@content;
}
}
And we call it: @include small(345px) { font-size: 20px; … }
@include tablet() {
bla bla
...
}
@include desktop(360px) {
ble ble
...
}
By having our @content in a mixin, we can save ourselves the media queries that after a long time can be very tedious, having to write them in each css, or in each class is a bit much hahahaha this way we only write include small..or whatever we put on it, that’s your favorite dev’s choice :D
Also, as we have seen so far, we could easily include these mixins of the media query type in our own mixins, so that once we invoke our mixins, we do not have to worry about the breakpoint since the mixin will automatically adapt to each scenario.
#experience
The other day I had to render some very visual marks on a screen, I remember there were like 4 marks, very very similar, almost the same but what differentiated the position of each one, what did I do? mixinnnn comes out with fries please
I was able to render all 4 marks with something like:
@include mark($top, $left);
And voila, I really saved all the css of the marks themselves, and only passed the position as dynamic. Throw a mixin daaaale
Conclution
As we can see, the mixins are totally scalable and flexible to any element, we can calmly render and draw structures that we know we have been repeating or we noticed in the project we are working on that they begin to repeat a lot throughout the styles in general, that is when we We realize that it is better to apply @mixins.
The idea is always to handle not so powerful mixins or bazooka from the start, we don’t want to kill a fly with a rifle either, do we? or not? or if? Let’s not be too fanatical about the arguments either because after the mixin we have anything left and we have to pass 10 arguments to it to do something mmmmmm no, NOT LIKE THAT. The idea is to pass only 2 or 3 parameters as far as possible, if we see that we need to expand, it is better to create another mixin, simple, pure, that we can even reuse elsewhere.
Let’s see whenever we can what is really used and useful, let’s remember the principle YAGNI
As a gift for reading you earned the fly with the rifle