Alejandro Mesa
Posted on February 19, 2020
Introduction
First post, here I go!! 🚀 give me hell 🔥.
This is a collection of powerful sass (scss) mixins that we used the most at Jam3 and some others I found to be useful. Mixins are pretty much functions that return css chunks, they are very powerful, make the code cleaner and will speed up your development process. These are not just for sass, for example, css-in-js fans could just create helper functions with these.
| You can skip ahead using this menu.
- 1. Box
- 2. Flexbox Toolkit
- 3. Font Size
- 4. Font Face
- 5. Cover Background
- 6. Pseudo
- 7. Media queries
- 8. z-index handling
- 9. Visibility
- 10. Background Transition
Let's dive into detail
1. Box
Let's start with a simple but popular one to define width and height in one go.
@mixin box($width, $height: $width) {
width: $width;
height: $height;
}
/* ===== Usage ===== */
div {
// You can pass width && height
@include box(200px, 300px);
/* or just pass width and the height
will default to the width value */
@include box(200px);
}
2. Flexbox Toolkit
Flexbox has taken over the front-end layout together with css grid. These are a set of mixins to quickly develop with it, the names are pretty self-descriptive and I highly use them because I always forget which one represents the main axis and which one the cross axis.
@mixin flex-column {
display: flex;
flex-direction: column;
}
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
@mixin flex-center-column {
@include flex-center;
flex-direction: column;
}
@mixin flex-center-vert {
display: flex;
align-items: center;
}
@mixin flex-center-horiz {
display: flex;
justify-content: center;
}
⚠️One warning is that since flexbox works as an axis and basis system, if the flex direction changes we're swapping the axis therefore you will need to use the opposite, for example:
/* ===== Usage ===== */
.vertical-centered-element {
@include flex-center-vert;
}
.horizontally-centered-element {
flex-direction: column;
@include flex-center-vert;
}
💡As a practice, you could try building the css grid
equals of these.
3. Font Size
This is one of my favorites because it keeps the code cleaner by shaving 2 lines off from multiple places. It sets font-size
, line-height
and letter-spacing
in one go and defaults to normal
for line-height
and letter-spacing
. It also keeps line-height unitless which I like.
You could adapt these mixins according to the type of units you work with, for example, you could make this work with a rem based font system.
@mixin font-size($font-size, $line-height: normal, $letter-spacing: normal) {
font-size: $font-size * 1px;
// font-size: $font-size * 0.1rem;
// example using rem values and 62.5% font-size so 1rem = 10px
@if $line-height==normal {
line-height: normal;
} @else {
line-height: $line-height / $font-size;
}
@if $letter-spacing==normal {
letter-spacing: normal;
} @else {
letter-spacing: #{$letter-spacing / $font-size}em;
}
}
/* ===== Usage ===== */
p {
@include font-size(12, 18, 1.2);
// returns
font-size: 12px;
line-height: 1.5; // 18 / 12
letter-spacing: 0.1em;
}
4. Font Face
This is just to quickly add font-face
with all sources ( Embedded OpenType, WOFF, TrueType, and SVG) in one command, very useful for big sites with multiple font types and weights.
@mixin font-face($font-name, $path, $weight: normal, $style: normal) {
@font-face {
font-family: quote($font-name);
src: url($path+".eot");
src: url($path+".eot?#iefix") format("embedded-opentype"), url($path+".woff")
format("woff"), url($path+".ttf") format("truetype"), url($path+".svg##{$font-name}")
format("svg");
font-weight: $weight;
font-style: $style;
}
}
/* ===== Usage ===== */
@include font-face(Roboto, "./assets/Roboto", normal, normal);
5. Cover Background
Saving two lines again 😄 this time to add a cover background to an element
@mixin cover-background {
background-repeat: no-repeat;
background-size: cover;
background-position: center;
}
/* ===== Usage ===== */
div {
background-image: url("cute-doggo.png");
@include cover-background;
}
6. Pseudo
This is a mixin that I use a lot for image masking but the idea is mostly to reduce lines since there is a lot of repetition when doing pseudo-elements;
@mixin pseudo(
$width: 100%,
$height: 100%,
$display: inline-block,
$pos: absolute,
$content: ""
) {
content: $content;
display: $display;
position: $pos;
@include box($width, $height);
}
/* ===== Usage ===== */
div {
position: relative;
width: 200px;
height: 200px;
&:after {
@include pseudo(100px, 100px);
}
}
7. Media queries
Since I have to google the @media
syntax every single time, this mixin comes in handy to handle breakpoints, add more as needed.
$tablet: 768;
$large: 1024;
$desktop: 1280;
@mixin tablet {
@media only screen and (min-width: $tablet * 1px) {
@content;
}
}
@mixin large {
@media only screen and (min-width: $large * 1px) {
@content;
}
}
@mixin desktop {
@media only screen and (min-width: $desktop * 1px) {
@content;
}
}
/* ===== Usage ===== */
h1 {
font-size: 10px;
@include tablet {
font-size: 12px;
}
@include desktop {
font-size: 20px;
}
}
8. z-index handling
Very straightforward mixin to control all the z-indexes from a central place.
- First, we have to define all elements in an array where the priority increases to the right
- Second, we use the
index
scss utility function to find the index of that array.
Pretty simple.
$elements: landing, header, modal, very-important-modal;
@mixin z-index($id) {
z-index: index($elements, $id);
}
⚠️As you might be thinking right now, this won't fix all your problems since z-index respects the stacking order of elements, for example in this case below div2
will still be on top of div1 > child
but is a decent solution
.div1 {
z-index: 2;
.child {
z-index: 5000;
}
}
.div2 {
z-index: 3; // This will still show on top of div1 > child
}
💻Here is an example:
⚠️Also, z-index only works on positioned elements, so if everything in your website is static
which is unlikely then it's all good and this mixin will be pure gold, if not, you must be careful and check the stacking of your elements.
9. Visibility
Quick mixin to hide or show an element, useful for fade in/out animations
@mixin fade($type) {
@if $type== "hide" {
visibility: hidden;
opacity: 0;
transition: visibility 1s, opacity 1s;
} @else if $type== "show" {
visibility: visible;
opacity: 1;
transition: visibility 1s, opacity 1s;
}
}
10. Background Transition
This one is more of a fun mixin, not highly reusable but I like this transition in buttons and is a way to show the power of mixins and encourage you to build your own and go a bit wild.
@mixin skew-background-transition($initial, $hover, $inverted: false) {
background: linear-gradient(
90deg,
$hover 0%,
$hover 50%,
$initial 50%,
$initial 100%
);
background-repeat: no-repeat;
background-size: 200% 100%;
background-position: right bottom;
@if $inverted {
background-position: left bottom;
}
transition: background-position 0.25s ease-out;
&:hover {
background-position: left bottom;
@if $inverted {
background-position: right bottom;
}
}
}
💻Here is an example of this mixin:
Conclusion
I hope you find some of these mixins useful. You should challenge yourself to create new ones depending on your requirements. As a good rule of thumb if you're repeating yourself more than times this is probably a good opportunity to check if a mixin could solve this. Since mixins could drastically change because of their opinionated nature you should make sure that your team is on board with the syntax and details.
I also put together everything that we covered in this article in this codepen as a playground in case you lovely people want to play around
References | Useful Links
- Sass Documentation
- Bourbon Tool Set - Huge library with extra scss tools
Collaborators
All the people at Jam3 that at some point touched these mixins.
Posted on February 19, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.