One of my favourite parts about SCSS/Sass is creating more ‘dynamic’ and visually maintainable code. I like organizing my code into as many partials as possible, and creating modular approaches to SCSS/CSS. As you may or may not know (depending on if you have read my previous blog posts or not), I am a big fan of the BEM class naming methodology. One of the more frustrating problems newcomers to BEM experience is their frustration with –modifiers in BEM. Often it leads to people doubling up on classes, and appending a modifier. In one of my previous posts, I explained the ‘&’ selector in SCSS and the @extend operator to maximize the use of BEM in a project, but there are even more ways to maximize BEM.
A BEM-y nav
If you’re unfamiliar with BEM, this is what a BEM-y header navigation might look like;
The items are differentiated with BEM –modifiers that suggest what the link is for. The design for the mobile nav we are working with requires different colours for each <li> in the mobile nav. It will look like this;
Usually this would be a pain to style. Each list item would require a separate declaration. BEM names are long, and they require a lot of typing. We can create a really bloated nested BEM declaration using the & selector but that may be frustrating to maintain in the future!
SCSS maps, ahoy!
Version 3.3 of Sass/SCSS brought a whole bunch of awesome organizational changes. One of the most useful was the use of SCSS/Sass maps! SCSS maps are data types which accept key/value pairs.
The above creates a really organized look at what colour we are using where! Because we are using a BEM –modifier for each link, we can keep everything organized and maintainable. This is great, but how do we actually use this SCSS map?
@each through ‘dat map
We can actual make use of this by running that map through a @each operator in SCSS. The @each operator will itterate through a SCSS map and output the desired CSS. @each takes ‘arguments’, as well as the SCSS map that we are running it on. We need to create a scoped variable for the key, and a scoped variable for the value in the map, this will look like…
Taking the SCSS map we made previously, we will assign the keys the value “$link” and the colors the value of “$colors”. These variable can be anything we want, as long as they start with a $ (as stated in Sass’s documentation). Now we can use our @each loop through the key/values in our map and output the desired CSS! First we will make use of the $link variable with our BEM class names!
Using SCSS interpolation, we can take the key value append it on the class selector. This will create a new selector for each key in the map, and because we named things with BEM, we will be able to target the classes we want!
Next, we will use the $color value for each key pair…
In the @each loop we will go through and create all the CSS we want for each of the selectors. Anywhere we want to use the color from the SCSS map, we will use the scoped $color variable. However, in the above code we are repeating ourselves a whole lot. Each time this loops through, the @each will create new css properties. Instead, we should wrap all the static CSS deceleration in a placeholder.
Placeholders for Maximum BEM!
If you’re not familar with SCSS/Sass placeholders, you can check out more of their uses on the SASS documentation. They are used over mixins in SCSS because they don’t re-write the code in the declaration. Instead, a placeholder will be unwritten in until called upon and when called upon, it will group all the selectors together. This creates much DRYer code. Creating a placeholder looks like this…
Then we can @extend this placeholder in our loop in the appropriate section, making our final @each loop look…
The @extend in the loop will add all the selectors to one CSS declaration when compiled, instead of re-writing all the CSS properties! I find showing the compiled CSS helpful for understanding this process…
Use Maps Forever, for Always!
I hope this has helped convince some of you BEM skeptics about the powers it has. If anything, it mostly shows what a consistent naming convention holds whatever that might be! I like BEM, but there are many other naming schools of thought out there. If we have a strong naming convention, we can use crazy SCSS magic to do really cool things with SCSS maps and @each loops! Now go into the world and use SCSS maps for everything!
Originally published at getgarrett.work on March 25, 2016.