Sass Mapping Colours

Keeping things neat with sass maps for colour declarations.

Sometimes when working on a site that has a varied colour pallete it's easy for your colour variables in sass to all get a bit messy:

$gray : #808080;
$gray-light : #dddbd8;
$gray-light-2: #edefed;
$gray-light-5 : #dddbd8;
$gray-med : #666;
$gray-dark : #222;
$gray-dark-2 : #131313;
$gray-dark-3 : #2D3235;

Yep - that is actually a thing I did, yuk - I don't know what happened to $gray-light-3 & $gray-light-4!!

There is no way to know a couple of months into a project what the difference between

$gray-dark 
$gray-dark-2
$gray-dark-3

might actually be. If you throw in - say different categories on a blog, each with their own colour and shades of that colour things soon get even more out of hand.

Sass map sanity

I've been using sass maps to help avoid the above nastiness.

Taking the above grays as an example I set a 'base' color:

$gray : #808080;

Then set up the map using sass colour functions to get shady:

$colors:(
    'gray'   : (
        'lighter'   : scale-color($gray, $alpha: -30%),
        'light'     : lighten($gray, 20%),
        'base'      : $gray,
        'dark'      : darken($gray, 20%),
        'overlay'   : scale-color($gray, $alpha: -40%),
    )
);

I find this a really useful resource for all things sass colour-y: A visual guide to Sass & Compass Color Functions

Now I can add in the sass function to get the colours:

@function get-color($color, $value: 'base') {
    @return map-get(map-get($colors, $color), $value);
}

and then write out:

.classname {
    background: get-color('gray', dark);
}

More Power!

Where this all becomes really useful is in a scenario like the one I mentioned before - say 5 categories each with their own colours:

$gray               : #808080;
$red                : #d82a4b;
$orange             : #ea5731;
$gold               : #dc8c05;
$lime               : #9cb11f;
$grass              : #468e4f;


$colors:(
    'gray'   : (
        'lighter'   : scale-color($gray, $alpha: -30%),
        'light'     : lighten($gray, 20%),
        'base'      : $gray,
        'dark'      : darken($gray, 20%),
        'overlay'   : scale-color($gray, $alpha: -40%),
    ),
    'red'   : (
        'lighter'   : scale-color($red, $alpha: -30%),
        'light'     : lighten($red, 20%),
        'base'      : $red,
        'dark'      : darken($red, 20%),
        'overlay'   : scale-color($red, $alpha: -40%),
    ),
    'orange': (
        'lighter'   : scale-color($orange, $alpha: -30%),
        'light'     : lighten($orange, 20%),
        'base'      : $orange,
        'dark'      : darken($orange, 20%),
        'overlay'   : scale-color($orange, $alpha: -40%),
    ),
    'gold'  : (
        'lighter'   : scale-color($gold, $alpha: -30%),
        'light'     : lighten($gold, 20%),
        'base'      : $gold,
        'dark'      : darken($gold, 20%),
        'overlay'   : scale-color($gold, $alpha: -40%),
    ),
    'lime'  : (
        'lighter'   : scale-color($lime, $alpha: -30%),
        'light'     : lighten($lime, 20%),
        'base'      : $lime,
        'dark'      : darken($lime, 20%),
        'overlay'   : scale-color($lime, $alpha: -40%),
    ),
    'grass' : (
        'lighter'   : scale-color($grass, $alpha: -30%),
        'light'     : lighten($grass, 20%),
        'base'      : $grass,
        'dark'      : darken($grass, 20%),
        'overlay'   : scale-color($grass, $alpha: -40%),
    ),
);

$categories: (
    'john'          : 'red',
    'paul'          : 'orange',
    'george'        : 'gold',
    'ringo'         : 'lime',
    'pete'          : 'grass'
);

@function get-color($color, $value: 'base') {
    @return map-get(map-get($colors, $color), $value);
}

so let's say we have a menu with markup like this:

<nav>
    <ul class="menu">
        <li class="menu-item menu-item--john">John</li>
        <li class="menu-item menu-item--paul">Paul</li>
        <li class="menu-item menu-item--george">George</li>
        <li class="menu-item menu-item--ringo">Ringo</li>
        <li class="menu-item menu-item--pete">Pete</li>
    </ul>
</nav>

the pay off for the preparation is that we can now do this in our sass:

@each $categories, $color in $categories{
    .menu-item--#{$categories} {
        color: white; 
        background: get-color($color, base);
        border-top: 8px solid get-color($color, dark);
        border-bottom: 8px solid get-color($color, dark);
    }
}

Which results in something like:


Code and Process