Stuff I’ve learned: Mixins

Not long ago I got my first job as a web developer. Let me tell you; after eleven years in clothing and food retail this could not have happened too soon. If you’re reading this and you’re in a similar position then trust me, carry on learning to code and get out of whatever dead end career it is that you’re sick of. It’s a life saver.

Anyway. Not long ago I got my first job as a web developer. This came after a good 18 months of me trying to fit in as much self-taught web design and development as I could squeeze around the afore-mentioned full-time (boring-oh-god-make-it-stop-boring) job. I thought I had a pretty good grasp on how things worked; particularly the basics – HTML, CSS and a smattering of Javascript. Oh good lord, how wrong I was. Everything you read below I’ve learned thanks to my awesome new tutor.

Turns out there’s this things called ‘SASS’ (Syntactically Awesome Style Sheets – love that name) and it’s (cooler) younger sister (Sassy CSS – or Sassy Cascading Style Sheets). And they’re *awesome*.

This post isn’t a tutorial on SASS or SCSS, but you can read up on them here.

Instead I want to talk about one of the big advantages of these syntaxes – mixins. Mixins allow you to deal with the more tedious and time-consuming parts of basic CSS in one place and then call them in with a single line as and when they’re needed.

For example, you might want to use flexbox for your layout. To make sure it works in every browser you have to use vendor prefixes. In standard CSS3 syntax that might look something like this:

section {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}

That’s five lines of CSS just to make something reliably flex! That’s madness. Madness I saaay!

Instead, mixins allow you to dump all this extraneous code into one place – away from your main styling – give it a easily remembered name and then call it up as and when you need it in just one line of CSS. Something like this:

section {
  @include add-flex();
}

Isn’t that so much cleaner? We’ve cut out four lines of CSS already, and that happens every time we use the mixin. It’s freaking awesome.

So. With this wondrousness in mind I now present some of the mixins I use to save me time and line real estate. Are we sitting awkwardly? Then I’ll begin…

1) Flexbox

As I’ve mentioned, flexbox is one of those CSS modules that can be a right “ugh” to type out all the vendor prefixes for.

These are the mixins I use to save me time along with the relevant include statement to call them into my stylesheets.

For adding display: flex…

// The Mixin
// Adds flexbox to an element
@mixin add-flexbox() {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
}

// The Include
section{
  @include add-flexbox();
}

For vertically centring…

// The Mixin
// Align an element's child/ren vertically center
@mixin add-flex-vertical-centre() {
  -webkit-box-align: center;
  -moz-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
}

// The Include
section{
  @include add-flex-vertical-centre();
}

For horizontally centring…

// The Mixin
// Align an element's child/ren horizontally center
@mixin add-flex-horizontal-centre() {
  -webkit-box-justify: center;
  -moz-box-justify: center;
  -ms-flex-justify: center;
  -webkit-justify-content: center;
  justify-content: center;
}

// The Include
section{
  @include add-flex-horizontal-centre();
}

I think you get the picture. You can swap out the relevant properties to match whatever you require: justify-content: space-between, justify-content: space-around, etc. etc.

2) Responsive Padding

When building a site using responsive techniques you will inevitably come across various elements that require the same set of rules to be repeated. But we like DRY (Don’t Repeat Yourself) code, don’t we? So let’s not. Instead of typing out endless lists of media queries – all of which would have to be changed individually if your design changes – let’s chuck it in a mixin.

A good example for this is site-wide padding. While different elements will require different breakpoints depending on their content and size, site-wide padding – by which I mean the space between your site’s content and the edge of the screen – is usually consistent. Enter this mixin:

// The Mixin
// Add site-wide responsive padding to an element - adjust as required
@mixin site-wide-padding() {
  padding: 0 15vw;
  @media only screen and (max-width: 1000px) {
    padding: 0 10vw;
  }
  @media only screen and (max-width: 800px) {
    padding: 0 5vw;
  }
  @media only screen and (max-width: 550px) {
    padding: 0 2vw;
  }
}

// The Include
section {
  @include site-wide-padding();
}

This is just one example of course, you could use this set up for any media-query breakpoint shenanigans you find yourself using over and over. And over.

3) Absolute Positioning

This can actually be used for absolute and relative positioning, but my example is for absolute.

// The Mixin
// Apply absolute positioning with top, right, bottom and left values 
@mixin abs-position ($top, $right, $bottom, $left) {
   position: absolute; 
   top: $top;
   right: $right;
   bottom: $bottom;
   left: $left;
}

//The Include
section{
  @include abs-position(5px, 10px, 5px, 10px);
}

I love this one. It gets rid of 4 lines of code every time you use it and it works so intuitively – we’ve basically just created a custom shorthand property like ‘padding:’ or ‘margin:’.

4) Visually Hiding Elements for Accessibility

In order to make your site as accessible as possible, you often find yourself having to include elements you don’t necessarily want as part of your design. A good example of this is form labels. Often these days the design of forms does away with separate labels, instead using the placeholder attribute to do the work. But this creates a problem for assistive technologies like screen readers that rely on proper label attributes to describe the form to a user.

Enter visually hiding elements. This is a technique you can use on an element you have to include for accessibility reasons but don’t want to appear visually on the screen. Unfortunately, it’s quite a few lines of code and depending on your design you might want to be using it repeatedly. It’s a good job this post is about mixins then:

// The Mixin
// Make an element visually hidden but accessible for screen readers etc.
@mixin visuallyhidden() {
  margin: -1px;
  padding: 0;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip: rect(0, 0, 0, 0);
  position: absolute;
}

// The Include
label{
  @include visuallyhidden();
}

5) Linear gradients

Linear gradients are lovely, aren’t they? To look at at least. To code they’re an “ugh”. You’ve got vendor prefixes to remember, various directions to consider, colours to get in the right order (I swear it’s like a phone charger, you’ve got a 50/50 chance of getting it right and you *always* get it wrong). Wouldn’t it be nice if we could do something to create a shorthand property of the custom variety….?

// The Mixin
// Apply linear gradients
@mixin background-gradient($start-color, $end-color, $orientation) {
    background: $start-color;

    @if $orientation == 'vertical' {
      background: -webkit-linear-gradient(top, $start-color, $end-color);
      background: linear-gradient(to bottom, $start-color, $end-color);
    } @else if $orientation == 'horizontal' {
      background: -webkit-linear-gradient(left, $start-color, $end-color);
      background: linear-gradient(to right, $start-color, $end-color);
    } @else {
      background: -webkit-radial-gradient(center, ellipse cover, $start-color, $end-color);
      background: radial-gradient(ellipse at center, $start-color, $end-color);
    }
}

// The Include
div{
  @include background-gradient(red, blue, vertical);
}

This mixin is a mixed bag. There’s so much to love; you’ve got no more vendor prefixes to worry about, you’ve got a shorthand-esque property to type just one line of, you’ve even got backup support for non-gradient-supporting browsers and a fallback to radiant gradient if you don’t specify a direction. The only thing it doesn’t include to an ‘every-angle’ approach. You’re limited to straight up and down or side to side, not 37 degree angles for us with this one. But still, a very useful mixin to have in your collection.

6) Text size and line height

Someone should run a survey on web developers to see what units they use to size their text. There’s so many options: px, %, em, rem… These mixins gives us a helping hand by taking a single unit and outputting it in both rem units as well as a px fallback (calculated using your root element’s stated font-size):

// The Mixin
// Font size REM output with px fallback
@mixin font-size($size-value: 1) {
  font-size: ($size-value * 16) * 1px;
  font-size: $size-value * 1rem;
}

// Line height REM output with px fallback
@mixin line-height($height-value: 1) {
    line-height: ($height-value * 16) * 1px;
    line-height: $height-value * 1rem;
}

// The Include
h2{
  @include font-size($size-value: 1.8);
}

7) Heading Sizes

// The Mixin
// Apply heading styles - includes support for mix-and-matching heading styles. 
// E.g. If you have an h2 heading in a sidebar that you want to be styled like an h4 heading, simply add '@include heading-4' to the sidebar h2.

@mixin heading {
  @include title-face;
  margin-bottom: 0.35em; // To maintain consistent spaces between headings and the rest of the content
  line-height: 1.2; // To maintain consistent spaces between headings and the rest of the content
  color: inherit;
  a {
    @include heading-link;
  }
}

@mixin heading-1 {
  @include heading;
  @include font-size($size-value: 3.375);
}

@mixin heading-2 {
  @include heading;
  @include font-size($size-value: 2.966);
}

@mixin heading-3 {
  @include heading;
  @include font-size($size-value: 1.5);
  
}

@mixin heading-4 {
  @include heading;
  @include font-size($size-value: 1.318);
}

@mixin heading-5 {
  @include heading;
  @include font-size($size-value: 1);
}

@mixin heading-6 {
  @include heading;
  @include font-size($size-value: 0.875);
}

// The Include
h2{
  @include heading();
  @include heading-4();
}

There’s quite a lot to take in here so let’s go through it.

We actually have seven separate mixins here but they’re grouped together because they relate to one another.

First off the we have the ‘heading’ mixin. This applies the same styles to all heading elements – useful, as when you’re building a site you quite often find that you have one set of styles for all your headings (excluding size) and then another set of styles for your paragraphs. Within this mixin you can see an @include for the title-face. This is calling in a font-family variable from elsewhere in you stylesheets – so all your headings will have the same font.

After that we have a series of mixins for heading sizes. They’re named after the six html heading tags but note, these mixins can be applied to any heading tag. This is useful because you may have a heading in a sidebar that you wish to convey relatively high importance to, say, search engines, so you’d want to use an h2 or h3. But it’s in the sidebar. You don’t necessarily want a big ‘ol in-your-face heading for something in a sidebar. This problem is solved by applying a different size mixin. So an a heading can have the SEO importance of an h2 tag but the visual styling of an h4 or h5 – or whatever – tag. Neat, huh?

8) Anchor state shorthand

It’s another of our friendly custom shorthand properties! This time for anchor tags – or links if you prefer. This particular example targets the text colour of the link, but it can be easily tweaked to apply styles to background colour, or border styles or whatever you link. Here we go:

// The Mixin
//Applies background colour styling to text-based links in all four states - link, visited, hover and active/focus.
@mixin link-color($link, $visited, $hover, $active) {
    & {
        color: $link;
        &:visited {
            color: $visited;
        }
        &:hover {
            color: $hover;
        }
        &:active, &:focus {
            color: $active;
        }
    }
}

// The Include
a{
  @include link-color(orange, orange, blue, green);

I’m using named colours here for the example, but obviously you can throw in HEX, RGB or whatever colour format you choose into their place.

This mixin truncates what can be eight to ten lines of code into one. Not too shabby.

That’s all folks

So there we go. There’s eight of the mixins I’ve collected over the last few weeks that you can use to make your Sassy CSS that bit DRYer.

I hope you enjoyed them. I’ll be seeing ya.

I'm Tom and I'm a self-taught Front-end Web Developer. I spend every moment I can learning about graphic design, web technologies and workflow in order to improve my knowledge, abilities and skill. I currently work as Junior Web Developer at the Webkick web design agency in Andover, Hampshire.

Leave a Comment

Your email address will not be published. Required fields are marked *