A story about overriding SASS variables and the ‘!default’ keyword

Jan Bajena
3 min readSep 2, 2018

--

Recently I stumbled upon a problem that took me much more time to solve than I expected. This story is mostly dedicated for the future me, but maybe it’ll be useful for somebody else as well :D

TLDR version

If you want to override a SASS variable defined with !default keyword located in file a.scss in a file named b.scss and then override the one from b.scss in c.scss your files should look like this:

// a.scss
$variable: red !default;
// b.scss
$variable: green !default;
@import 'a';
// c.scss
$variable: blue;
@import 'b';

Long version

Introduction

Let’s start with a few words of introduction — in Leadfeeder we’re sending a variety of emails which initially had been developed using the plain old HTML tables method and, as you probably can guess, weren’t very visually appealing. We decided to pimp up the emails a little bit and start developing our templates using Foundation for Emails. The nice thing about this framework is that Zurb provides a Ruby gem packaged with SASS files that make your templates good looking and responsive out-of-the-box.

We of course needed to give the emails a bit of soul, by changing things like text color which fortunately was pretty easy, because the foundation gem exposes a set of global variables you can override to customize the templates to your needs.
A sample variable definition in the gem looks like this:

/// Primary color for interactive components like links and buttons.
/// @type Color
$primary-color: #2199e8 !default;

Notice that the variable definition includes !default keyword which, citing this page, means that:

If the variable already has an assignment, it will not be re-assigned

So in order to override the default variables I just needed to create a file called_global-overrides.scss , redefine the variables there and in my main SASS file import this file before the foundation-emails.scss file, like this:

@import
'global-overrides',
'foundation-emails'

The thing worked like a charm.

The problem

Later, over the time we developed a base stylesheet for all the emails and called it mailer-common.scss which looked somewhat like this:

// mailer-common.scss@import
'global-overrides',
'foundation-emails',
'layout',
'header',
'typography';

Now every email stylesheet would have its own file that included the mailer-commonfile at the top and selectors specific for given email afterwards, like this:

// weekly-email.scss@import 'mailer-common';.ems-stats {
&__mailchimp-logo {
max-width: 100px;
}
}

The problem appeared when we started converting more emails to the Foundation framework — in one of them we needed to change the value of global-gutter variable. The variable was already overridden in global-overrides.scss , so I thought that all I had to do was to redefine it again on the top of the specific email file, like this:

// custom-feed-email.scss$global-gutter: 20px;@import 'mailer-common';

Unfortunately this didn’t change the gutter as I expected - the value was still at 40px defined in global-overrides.

This meme describes my feelings back then

The solution

The behavior described in the previous part got me a bit confused and wasted a lot of my time, but finally after a few hours of trials and errors I got to the point of understanding that what I needed to do is to override foundation variables in global-overrides.scss with additional !default keyword — it still feels pretty weird for me, but that’s how the thing works :D

So the final file structure looked like this:

// _globals.scsc in foundation-emails gem
$global-gutter: 16px !default;
// _global-overrides.scss
$global-gutter: 40px !default;
// _mailer-common.scss
@import
'global-overrides',
'foundation-emails',
'layout',
'header',
'typography';
// custom-feed-email.scss
$global-gutter: 20px;
@import 'mailer-common';

Now the gutter in custom feed email had a correct value of 20px and they lived happily ever after.

--

--

Jan Bajena

I’m a software developer @ Productboard, mostly interested in building backends using Ruby language. CSS doesn’t make me cry though ;)