A successful Sass theme structure

For some time I’ve been dealing with multiple projects that are target by the need of high levels of customization and all the strategies always begin with one thing, the need of multiple themes.
I won’t be giving you the perfect recipe to achieve the best theme you would ever have, instead I’ll be giving you the strategy that I’ve found the best until today and, as a trade off, I’ll be hoping you to give me your feedback and ideas so I can improve it :)
Note: Despite the title of this post, this approach is valid both for Sass projects as for other solutions . It can be applied using future CSS, Less, Post CSS or even styled components. The thing is… I’ll be giving you snippets using Sass, that’s all.
At the end of this reading, if you find any of these tips useful and you want to implement it, please stop for a minute and discuss each one of your decisions with the design team. They have to be aware of your concerns and you have to be aware of their needs. It’s the only way you’ll get the chance of having a nice and clean implementation along with a consistent style across the whole website. (“Been there, done that”)
Color palettes
It always starts with color palettes. Color might be one of the most, or even the most important thing to care about in your design. It must be consistent across your project and must match your design intent, contributing to the overall aesthetic of your site.
Here’s an example of 4 color palettes with 3 variations each one. This palettes have proved enough for most of my projects but hey! Feel free to define as much palettes and variations you find being useful for you. Just keep in mind, be consistent.
The primary color would be the brand’s color (ex: blue), the accent (as the name might suggest) would be the accent color (ex. the brand’s secondary color: orange), the foreground would be for primary objects with darker colors and the background essentially for lighter objects or for section backgrounds.
Now, how would we use these colors? We are dealing with maps and accessing the maps directly wouldn’t be much practical.
So I suggest you to use functions for that.
This way, you could easily access your color palettes like the following:
...
background-color: theme-color(); // "primary base" color;
boder: 1px solid theme-color('foreground', 'light'); // "foreground light" color;
...
If you find color variations not enough and you’re working with Sass you can play with other color functions like mix, lighten, darken and others.
At Scotch.io you can actually find a nice article about managing color palettes using the mix function. I would recommend you to take a look.
Contrast
One of the problems that I started to struggle with when I first started adopting this color palettes was the ability to have a good contrast rate between my text contents and my UI elements, no matter what colors I define in the palettes.
Thanks to Google Material Design guide I’ve seen that I should be using transparency rather than colors for text. You only have to be aware if you’re dealing with a dark or a light background and the transparency will take over from that.
So, I defined some more palettes:
And this time instead of using only functions to access it, I’ve created a mixin along with a helper function (since we’ll be using it mainly for font colors).
And now, when I’m dealing with UI elements with a light background I can manage my font color like:
.selector {
@include contrast();
// or @include contrast('light', 'secondary'); for more faded content
}
In the other hand, if I’m dealing with UI elements with a dark background I would do:
.selector {
@include contrast('dark');
// or @include contrast('dark', 'secondary'); for more faded content
}
(Don’t forget you can also use this contrast() function for other CSS properties)
Typography
Well at this point, you can imagine what I’ll propose for managing your font sizes, families and weights… Maps.
Font size
For font size I always use rem unit and each font size has a direct relation to the line-height.
The rem unit is relative to the root — or the
html
—element. That means that we can define a single font size on thehtml
element and define all rem units to be a percentage of that.
You can read more about it here.
Assuming the base size is 16px, we can build the following map of sizes and have in mind how much it is in px.
And now, to work with our font sizes we only have to use the text-setting mixin. This way we can easily change all our website’s content size and spacing through this single point of management.
.selector{
@include text-setting('xs');
}
I could describe what I follow for other things like font weight and font family but the trick is always the same. Usage of maps, functions and mixins.
The only thing you have to keep trying to achieve is to have single points of definition of colors, sizings, sharpness and other things that may change from theme to theme so you can change them with no pain.
I’ve found these strategies very useful in many different projects. Even when I don’t need customization layers… It helps me to have consistent styles and the code maintenance is much more healthy.
Hope it helped! And I’m sure you have some trick or practice you find as much useful as the tips I just gave you. I’ll be waiting to hear about it.