6 Powerful Sass (Scss) Mixins To Do More With Less Code

Sassy CSS is the secret sauce to DRY code, it easily ads 5x to my efficiency. Here's some powerful must have Sass/Scss mixins, suitable for any project.

I feel like an uber-efficient-superhuman developer when I find or write a really good Sass mixin.

If you’re unfamiliar, a mixin is a block of code that can accept arguments and output rules that you can reuse over and over with a simple one-line directive. Mixins are unique to Syntactically Awesome Stylesheets (Sass), a CSS pre-processing language.

To summarise, mixins are powerful and em-powering so, below i’ve curated a list of 6 powerful Sass mixins that save me time and make me feel superhuman.

1. Effortless @font-face rules

I loathe writing font faces — it’s one of many tasks I often fumble. Not anymore, I can markup all my project fonts utilising numerous formats with this super simple font-face mixin.

Mixin:

=font-face($name, $url, $weight, $style) { @font-face { font-family: quote($name); src: url('../../fonts/#{$url}.woff2') format('woff2'), url('../../fonts/#{$url}.woff') format('woff'), url('../../fonts/#{$url}.ttf') format('truetype'); font-weight: $weight; font-style: $style; font-display: swap; } }

Usage:

+font-face('Open Sans', 'OpenSans-Regular', 400, normal) +font-face('Open Sans', 'OpenSans-Italic', 400, italic) +font-face('Open Sans', 'OpenSans-SemiBold', 600, normal) +font-face('Open Sans', 'OpenSans-SemiBoldItalic', 600, italic) +font-face('Open Sans', 'OpenSans-Bold', 700, normal) +font-face('Open Sans', 'OpenSans-BoldItalic', 700, italic)

Output:

@font-face { font-family: "Open Sans"; src: url(../fonts/OpenSans-Regular.woff2) format("woff2"), url(../fonts/OpenSans-Regular.woff) format("woff"), url(../fonts/OpenSans-Regular.ttf) format("truetype"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: "Open Sans"; src: url(../fonts/OpenSans-Italic.woff2) format("woff2"), url(../fonts/OpenSans-Italic.woff) format("woff"), url(../fonts/OpenSans-Italic.ttf) format("truetype"); font-weight: 400; font-style: italic; font-display: swap; } @font-face { font-family: "Open Sans"; src: url(../fonts/OpenSans-SemiBold.woff2) format("woff2"), url(../fonts/OpenSans-SemiBold.woff2) format("woff"), url(../fonts/OpenSans-SemiBold.ttf) format("truetype"); font-weight: 600; font-style: normal; font-display: swap; } @font-face { font-family: "Open Sans"; src: url(../fonts/OpenSans-SemiBoldItalic.woff2) format("woff2"), url(../fonts/OpenSans-SemiBoldItalic.woff) format("woff"), url(../fonts/OpenSans-SemiBoldItalic.ttf) format("truetype"); font-weight: 600; font-style: italic; font-display: swap; } @font-face { font-family: "Open Sans"; src: url(../fonts/OpenSans-Bold.woff2) format("woff2"), url(../fonts/OpenSans-Bold.woff) format("woff"), url(../fonts/OpenSans-Bold.ttf) format("truetype"); font-weight: 700; font-style: normal; font-display: swap; } @font-face { font-family: "Open Sans"; src: url(../fonts/OpenSans-BoldItalic.woff2) format("woff2"), url(../fonts/OpenSans-BoldItalic.woff) format("woff"), url(../fonts/OpenSans-BoldItalic.ttf) format("truetype"); font-weight: 700; font-style: italic; font-display: swap; }

2. A full width element inside fixed width container

This one is great for making a quick full width pseudo element inside a fixed width container. It’s ideal when you are faced with markup constraints.

Mixin:

=full-width($bg-color: transparent, $height: 100%) { background-color: $bg-color; content: ""; height: $height; left: calc(-50vw + 50%); position: absolute; top: 0; width: 100vw; }

Usage:

.call-to-action { &::before { +full-width(#ff7878, 200px) } }

Output:

.call-to-action::before { background-color: #ff7878; content: ""; height: 200px; left: calc(-50vw + 50%); position: absolute; top: 0; width: 100vw; }

3. Clean system dark mode styles

This mixin provides a super clean way to attribute dark mode styles to any combination of selectors. The dark-mode boolean variable will allow you to turn dark mode styles on and off globally (this is super useful for debugging). This code also has excellent browser support.

Mixin:

$dark-mode: true; =dark-mode { @if ($dark-mode) { @media (prefers-color-scheme: dark) { @content; } } }

Usage:

body { color: #000000; background-color: #ffffff; +dark-mode { color: #ffffff; background-color: #000000; } }

Output:

body { color: #000000; background-color: #ffffff; } @media (prefers-color-scheme: dark) { body { color: #ffffff; background-color: #000000; } }

4. Easy-to-read media queries

Crucial to almost any project, I use this mixin to develop mobile-first and code media queries legibly. It’s also super easy to add more custom widths as your project evolves.

Mixin:

$desktop: 1024px; $tablet: 768px; $mobile: 480px; =respond-to($media) { @if $media == desktop-and-up { @media only screen and (min-width: $desktop) { @content; } } @if $media == desktop-and-down { @media only screen and (max-width: $desktop - 1) { @content; } } @else if $media == tablet-and-up { @media only screen and (min-width: $tablet) { @content; } } @else if $media == tablet-and-down { @media only screen and (max-width: $tablet - 1) { @content; } } @else if $media == small-and-up { @media only screen and (min-width: $mobile) { @content; } }

Usage:

body { font-size: 16px; /* Applied to everything small and down (mobile first) */ +respond-to(tablet-and-up) { font-size: 18px; } +respond-to(desktop-and-up) { font-size: 20px; } }

Output:

body { font-size: 16px; /* Applied to everything small and down (mobile first) */ } @media only screen and (min-width: 768px) { body { font-size: 18px; } } @media only screen and (min-width: 1024px) { body { font-size: 20px; } }

5. Truly responsive font sizing

Adding truly responsive font sizing can be fiddly which is one of the reasons I often don't bother. This mixin makes it super easy.

Mixin:

=font-size($min-size, $viewport-min, $viewport-max, $max-size) { font-size: clamp(#{$min-size}, calc((100vw - #{$viewport-min}) * 1vw + #{$min-size}), #{$max-size}); }

Usage:

body { +font-size(16px, 350px, 1200px, 24px); }

Output:

body { font-size: clamp(16px, calc((100vw - 350px) * 1vw + 16px), 24px); }

6. Fluid aspect ratio

This is my favourite of them all, it gives you a super fast way to declare an aspect ratio that will work across all browsers. You will need to use the container as a selector for this to work.

You can either add the selector of a specific child of the parent into the second argument or leave it blank and the mixin will default to the first child of the container. Thanks to Jonathan for this one.

Mixin:

=fluid-aspect($ratio: 1 1, $selector: "> :first-child") { $selector: unquote($selector); padding-bottom: percentage(nth($ratio, 2) / nth($ratio, 1)); position: relative; #{$selector} { left: 0; height: 100%; position: absolute; top: 0; width: 100%; } }

Usage:

.my-container { +fluid-aspect(16 9); } /* Or */ .my-container { +fluid-aspect(4 3, iframe); }

Output:

.my-container { padding-bottom: 56.25%; position: relative; } .my-container > :first-child { left: 0; height: 100%; position: absolute; top: 0; width: 100%; } /* Or */ .my-container { padding-bottom: 75%; position: relative; } .my-container iframe { left: 0; height: 100%; position: absolute; top: 0; width: 100%; }

Conclusion

I hope one or two of these mixins prove to be as useful for you as they are for me. I find, as a rule of thumb, if you are repeating yourself more than twice, make a mixin.