Different Colours per Site Section in SASS (SCSS)

Sometimes you may need a different colour scheme for every section / primary category in your site. This can typically be a couple of hues of a colour per section, just to give a different personality to that corner of the site. For example at The Times each main section has a dominant colour which is used in typgraphy and block headings within that section. Here we took a basic approach of having CMS driven section variables which resolved to class names such as “bg-007469”, you will see these peppered around the markup, mischievously binding presentation information to the markup. Each page then has a dynamic <style> tag written out by the back end to marry things up.

Unfortunately this was built way before pre-processed CSS took off. Nowadays we have tools such as LESS & SASS to make structuring site colour more elegantly. With the use of mixins we can nominate which elements should inherit section colours all within our SCSS codebase. Here’s how..

1st in your mixins location add this.

$primaryColors: (home #E73159)
                (section2 #B0C038)
                (section3 #FDAD00)
                (anothersection #CB8840)
                (keepaddingasmany #EAA3C5)
                (sectionsasyouneed #8FBDCB);
@mixin section-color($properties:(background-color),$context:"body"){
  $postContext:"&";
  @if ($context=="&") {
    $postContext:"";
  }
  @each $i in $primaryColors {
    #{$context}.#{nth($i,1)} #{$postContext} {
      @each $property in $properties {
        #{$property}:#{nth($i,2)};
      }
    }
  }
}

$primaryColors is an array or ‘collection’ in sass language, fill this with all your sections’ colours. I’m using the nth sass function to treat the collection as a multi dimensional array. In SASS 3.3.0 there are ‘maps’ which will probably be a bit cleaner. To make this work you will need to ensure your CMS writes out the section name onto the body class. You can now call…

.content{
    @include section-color();
}

on each selector you wish to inherit a section colour. By default it will apply the colour to the background, but you can easily override this by passing a different CSS property or collection of properties e.g.

h1{
@include section-color((color,border-color));
}

(note double bracketing needed for a collection). The mixin iterates through all given properties and all possible sections and generates such CSS as…

body.home h1 {
  color: #e73159;
  border-color: #e73159;
}
body.section2 h1 {
  color: #b0c038;
  border-color: #b0c038;
}
body.section3 h1 {
  color: #fdad00;
  border-color: #fdad00;
}
body.anothersection h1 {
  color: #cb8840;
  border-color: #cb8840;
}
body.keepaddingasmany h1 {
  color: #eaa3c5;
  border-color: #eaa3c5;
}
body.sectionsasyouneed h1 {
  color: #8fbdcb;
  border-color: #8fbdcb;
}

You may have noticed this bit of conditional logic at the top:

  $postContext:"&";
  @if ($context=="&") {
    $postContext:"";
  }

This is to limit the trickery to a specific part of the site, for example the site nav. Here you may wish to render all section colours, and more than likely have your cms output a section classname on each nav entity. To switch into this mode there is a context parameter which by default is set to ‘body’. When you override this to “&” the rule will no longer use the body class prefix and instead use the normal context of the rule that you are in. So for example on your Nav elements you could call..

nav{
  li{
    @include section-color($context:"&");
  } 
}

Which compiles to

nav li.home {
  background-color: #e73159;
}
nav li.section2 {
  background-color: #b0c038;
}
nav li.section3 {
  background-color: #fdad00;
}
nav li.anothersection {
  background-color: #cb8840;
}
nav li.keepaddingasmany {
  background-color: #eaa3c5;
}
nav li.sectionsasyouneed {
  background-color: #8fbdcb;
}

Notice there is no longer a body prefix.

This all sounds a bit confusing so to help visualise what I’m talking about I’ve made a codepen.

This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

Leave a Reply

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