Sassifaction in Colour Palette Mixins

When I used to design sites as well as develop them. There was one blogpost that really helped me with my final colour choices. This was Andy Clarke's 2004 piece on creating colour palettes. At the bottom of that page (when I found it some years later) was a link to a web app that created the relevant CSS hex values.

Roll on some years

So, as I'm sure you're aware, I use Sass (SCSS). Recently I saw Andy included this colour palette idea into his Rock Hammer project library. I had a quick peek under the hood (or in the github repo) and saw how he was creating the colour palettes. Where he uses RGBA to give a representation of the possible colours from your primary, secondary or tertiary choices.

To the Pen

I then went swiftly to a fresh codepen and created a little bit of SCSS and HTML to recreate the palettes but using Sass's tint and shade colour functions. With this pen you would pass a primary($base-color), secondary($comp-color) and tertiary($tertiary-color) set of colour variables and it would then create a nice set of colour palettes.

This pen, found here - http://codepen.io/sturobson/pen/haiIe - can be taken an 'dropped' into a living styleguide (note: this is all a work in progress for my own Sass 'framework' and my HTML/CSS/JS starting point).

There's always a but

That's all well and good, it looks nice. But the way I set the page up using nth:child wasn't very good for actual use in a project so I decided to make a quick mixin.

This mixin has two variables within it. $color can be a hex colour or on of the variables from your styleguide or similar. There's alse $change where you'd want to lighten(tint) or darken(shade) the colour or not (which why it's predefined as 'n'. -

@mixin bgcolor($color, $change: n) {
     @if $change == n {
        background-color: $color;  
    }
    @if $change == l1 {
        background-color: tint($color, 10%);  
    }
    @if $change == l2 {
        background-color: tint($color, 25%);  
    }
    @if $change == l3 {
        background-color: tint($color, 50%);  
    }
    @if $change == l4 {
        background-color: tint($color, 75%);  
    }
    @if $change == d1 {
        background-color: shade($color, 10%);  
    }
    @if $change == d2 {
        background-color: shade($color, 25%);  
    }
    @if $change == d3 {
        background-color: shade($color, 50%);  
    }
    @if $change == d4 {
        background-color: shade($color, 75%);  
    }  

}

So by having our chosen colours for the design set up as variables from your styleguide, for example -

$base-color: #D13500;
$comp-color: #398CC2;
$tertiary-color: #dd4400;
$black: #000;
$white: #FFF;

We can now add a background colour to an element in our CSS that's from the colour palette we've got in our styleguide and $change is how you'd want to change the $color lightening (l) or darkening (d) it in 1 of 4 possible steps.

To do this you'd just @include the mixin into your CSS, for example

.an-example {
    @include bgcolor($comp-color, d3);
}

which would give you the compiled CSS as -

.an-example {
    background-color: #1c4661;
}

Making text colourful

That's good for background-color, but there's probably opurtune times when you'd like to use the colour palette colours on the color element too. So for that we can create this mixin. This mixin again has two variables. Both the same as the background colour mixin -

@mixin color($color, $change: n) {

    @if $change == n {
        color: $color;  
    }
    @if $change == l1 {
        color: tint($color, 10%);  
    }
    @if $change == l2 {
        color: tint($color, 25%);  
    }
    @if $change == l3 {
        color: tint($color, 50%);  
    }
    @if $change == l4 {
        color: tint($color, 75%);  
    }
    @if $change == d1 {
        color: shade($color, 10%);  
    }
    @if $change == d2 {
        color: shade($color, 25%);  
    }
    @if $change == d3 {
        color: shade($color, 50%);  
    }
    @if $change == d4 {
        color: shade($color, 75%);  
    }  

}

So we can use the mixin like this -

.an-example {
    @include color($comp-color, d3);
}

which would give you the compiled CSS as -

.an-example {
    color: #1c4661;
}

Box it with borders

We're getting some nice mixins out of this colour palette idea. What about borders? We like using borders and perhaps we want to have border colours from the colour palette that we've decided upon.

So to create this I decided to also allow for top, bottom, left and right border THINGS. So with this mixin there are 5 variables. £color and $change are the same except I've given them defaults of a black colour #000 and n for $change which I've used to express no change in colour. $border-size for the border thickness, $border-style for the style and $border-position for top, bottom, left or right -

@mixin border($color: #000, $border-size: 1px, $border-style: solid, $border-position: null) {

    @if $border-position == null {      
        @if $change == n {
            border-#{$border-position}: $border-size $border-style $color;
        }
        @if $change == l1 {
            border: $border-size $border-style #{tint($color, 10%)};
        }
        @if $change == l2 {
            border: $border-size $border-style #{tint($color, 25%)};
        }
        @if $change == l3 {
            border: $border-size $border-style #{tint($color, 50%)};
        }
        @if $change == l4 {
            border: $border-size $border-style #{tint($color, 75%)};
        }
        @if $change == d1 {
            border: $border-size $border-style #{shade($color, 10%)};
        }
        @if $change == d2 {
            border: $border-size $border-style #{shade($color, 25%)};
        }
        @if $change == d3 {
            border: $border-size $border-style #{shade($color, 50%)};
        }
        @if $change == d4 {
            border: $border-size $border-style #{shade($color, 75%)};
        }
    }

    @elseif $border-position != null {
        @if $change == n {
            border-#{$border-position}: $border-size $border-style $color;
        }
        @if $change == l1 {
            border-#{$border-position}: $border-size $border-style #{tint($color, 10%)};
        }
        @if $change == l2 {
            border-#{$border-position}: $border-size $border-style #{tint($color, 25%)};
        }
        @if $change == l3 {
            border-#{$border-position}: $border-size $border-style #{tint($color, 50%)};
        }
        @if $change == l4 {
            border-#{$border-position}: $border-size $border-style #{tint($color, 75%)};
        }
        @if $change == d1 {
            border-#{$border-position}: $border-size $border-style #{shade($color, 10%)};
        }
        @if $change == d2 {
            border-#{$border-position}: $border-size $border-style #{shade($color, 25%)};
        }
        @if $change == d3 {
            border-#{$border-position}: $border-size $border-style #{shade($color, 50%)};
        }
        @if $change == d4 {
            border-#{border-position}: $border-size $border-style #{shade($color, 75%)};
        }
    }

}

So for a simple border with colour you can write -

.an-example {
    @include border($base-color, l2);
}

Which would give you -

.an-example {
    border: 1px solid #dc673f;
}

If you wanted to create a border-top you could write -

.an-example {
    @include border($base-color, l2, 1px, solid, top);
}

Would give you this resulting CSS -

.an-example {
    border-top: 1px solid #dc673f;
}

To the end

So we've now got three ways of bringing our styleguides colour palette into our stylesheets. I've uploaded this to my Sassifaction Sass(SCSS) mixin library and also as a pen on Codepen.

Update (07/04/13)

Almost as soon as I posted this Ryan suggested I could do this with a function instead. He went off and some minutes later came back with this -


@function colorize($color, $change: n) {
  @if $change == n {
    @return $color;
  }
  @if $change == l1 {
    @return tint($color, 10%);
  }
  @if $change == l2 {
    @return tint($color, 25%);
  }
  @if $change == l3 {
    @return tint($color, 50%);
  }
  @if $change == l4 {
    @return tint($color, 75%);
  }
  @if $change == d1 {
    @return shade($color, 10%);
  }
  @if $change == d2 {
    @return shade($color, 25%);
  }
  @if $change == d3 {
    @return shade($color, 50%);
  }
  @if $change == d4 {
    @return shade($color, 75%);
  }
}

This lets you put the colorise function where you'd want to put color in the (S)CSS. So for example (still using our colour variables) -

body {
    color: colorize($base-color,l4);
    background: colorize(#fff,d2);
    border: 1px solid colorize($comp-color,d3);
}

Would give you this outputted css -

body {
  color: #f3ccbf;
  background: #bfbfbf;
  border: 1px solid #1c4661;
}

Pretty neat. I'll be updating my Sassifaction code with this great titbit of code