BEM flavored SASS/SCSS Variable Names
Let's be honest, we all know this joke:
There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton
And that's bugging us too. Most of our projects are done using the Atomic Design Pattern to structure our components into atoms, molecules and organisms. For implementing and structuring components and their subparts we use BEM in combination with SCSS.
In the beginning the varibable names that we used felt rather arbitrary. They also changed between projects, which made it harder to onboard other developers. When looking back at older projects I sometimes do not remember why I chose a certain naming scheme.
This is when I realized that we need a well articulated naming scheme.
After quite some pondering I ended up with a naming scheme that solves the following problems:
1. Generalizing different naming schemes
2. Difficult recognition of variables in the autocompletion of my IDE
3. Refactoring of component names is not much fun
Improving your SASS variables naming with BEM
First let's start with a simple component following the BEM naming scheme.
This might leave us with the following SCSS:
Now we start introducing new variables for background and opacity:
We concatenate the BEM class name "button--success" with the name of the property "background". The property can be the name of the CSS property, but in some cases it makes sense to choose a more semantical meaning.
In the following example we change the variable naming from "...--background" to "...--color", as we are now using the variable for different CSS properties.
Adding semantics to your variables (e.g. by using "...--color" instead of "...--background") drastically helps others to better understand your code.
For the sake of naming a naming scheme, let me introduce you to $BEMP
Why I really enjoy using it
1. The autocompletion of my IDE is more fun to use, because variables have better semantics and are therefore easier to recognize.
2. Refactoring component names becomes so much easier, because we use the same naming scheme for component class names and variables.
Refactoring component names normally leads to ...
- refactoring of HTML class attributes
- refactoring of CSS class declarations
- refactoring of SCSS variables
Usually the IDE support for this doesn't hit the point and takes quite some work to set up. The pragmatic approach would be search and replace, which naturally is easier when using consistent naming.
E.g. we only need to replace "button--success" with "button--positive" and alle the variables will be changedcorrectly.
3. Onboarding new developers will be much faster with a well thought trough naming scheme.
But what about Global Variables?
Besides variables that are semantically tied to components we usually have some global variables, e.g. for typography, colors, spacings and sizes. For this I use "global" variables that have their own namespace and can be reused for the component specific variables.
I always have a _Variables.scss where all those variables can be found.
File structure - Where to place your variables
I normally use the Atomic Design Pattern which leads to the following structure:
I tried different approaches for structuring my variables, but for me it boils down to the following two:
Approach A: Putting it all in one file (e.g. _Variables.scss)
I suggest using one SCSS file for each component (e.g. _Button.scss) for the components styling declarations, but keep all variables inside one file (e.g. _Variables.scss). This way you have all the variables that drive your styling in one place making it easier to allow e.g. theming.
This approach however makes it harder to reuse components. A way around this, would be to only use the component specific variables, move them to the SCSS of the component, e.g. the _Button.scss. This way you can directly see the styling API of your component.
Approach B: Keep component specific variables in designated files
This approach might lead to problems for more complicated components (e.g. organisms), that cannot be completely separated because they need to share knowledge about their styling.
In this example the body has to know about the width of the sidebar. This is why I would move the $sidebar__width to the _Variables.scss to show that it can be used by other components, leaving me with some component specific variables outside of their designated SCSS files, which does not really feel consistent.
This is why I decided to go with approach A, keeping component specific AND global variables inside the _Variables.scss.
For me, the proposed naming has increased my speed when developing. It also makes it easier to onboard new developers to a project and it drastically improves code quality if you have a naming scheme that does not feel arbitrary.
Let's see how this will evolve in the future and let us know what you think of it!