These top 10 CSS best practices will help you save time and collaborate better with your team.
We sometimes think that we know all we need to know about SCSS and that we can give that extra time to get ahead on JavaScript.
I’m sorry to be the one breaking this to you, but you should pay more attention to your stylesheets. I’ve worked in projects where the code turned into spaghetti just because a few simple best practices weren’t applied. I quickly learned how precious some good tips can be when working with other people on a code base that can become quite large in no time.
That’s why, today, I’m sharing with you 10 SCSS best practices that will help you and your team.
Start using them, your teammates and the people who’ll later take over your code will thank you. (By the way… that’s one of the few ways you get extra points in the good place. 👼)
Have you ever gotten into a project and didn’t know how to start reading or making sense of the CSS classes naming?
Yeah 💁♀️we’ve all been there. That’s why whenever I start a new project or join one, one of my first code style optimizations is implementing BEM and making sure that everyone follows it.
BEM stands for Block, Element, Modifiers. The added value that this CSS classes naming convention brings to the table is simple: it allows you to visualize how your template is styled in a structured way.
How it works is even simpler:
You name the main blocks of your page like this for instance: class="button"
.
Then, name the elements inside each block using two underscores (to show that it’s part of the block): class="button__icon"
.
And in case you have a variant of that block, use two dashes to name a modifier: class="button button--red"
.
So in your template, it will look like this:
<button class="button button--blue">
<img class="button__icon" src="http://www.bem-br.org/img/logo.png" alt="icon-blue"/>
<p class="button__label">Use BEM</p>
</button>
<button class="button button--red">
<img class="button__icon" src="http://www.bem-br.org/img/logo.png" alt="icon-red"/>
<p class="button__label">Please use BEM</p>
</button>
Editing your styles will become much easier, because you’ll be able to visualize the structure of your code:
.button {
border: none;
margin: 20px;
cursor: pointer;
.button__icon {
width: 20px;
height: 20px;
}
.button__label {
color: white;
padding: 20px 40px;
text-align: center;
text-transform: uppercase;
font-size: 16px;
}
// --> MODIFIERS: COLORS <--
&--blue {
background-color: blue;
}
&--red {
background-color: red;
}
}
To learn more about BEM: MindBEMding – getting your head ’round BEM syntax.
If you follow the BEM convention (or are going to), here is another good practice you can follow to speed up your development time: using variable extrapolation. This way, you will not repeat yourself.
It’s pretty simple — you just define your block class in a variable (in the example above it was .button
) and replace it using #{$c}
in your CSS code.
Let’s use the example above, to see how it works:
$c: “.button”
#{$c} {
border: none;
margin: 20px;
cursor: pointer;
&--blue {
background-color: blue;
}
&--red {
background-color: red;
}
#{$c}__icon {
width: 20px;
height: 20px;
}
#{$c}__label {
color: white;
padding: 20px 40px;
text-align: center;
text-transform: uppercase;
font-size: 16px;
}
}
It’s a small and simple improvement, but not having to rewrite your block class name every time (or just being able to update it in a single spot) speeds things up, improves code readability and makes the structure of your CSS code pop out. 🍿
You can think of InuitCSS as a CSS framework. Even though it does not provide you with UI components or anything like that.
Instead, InuitCSS helps you normalize, configure, homogenize and structure your stylesheets.
Sounds abstract? Okay, let’s see how it does that.
First, go ahead and install InuitCSS using npm install inuitcss --save
. Now all you have to do is get to know the InuitCSS-specific CSS directory structure that it provides and follow it to set structure you project’s assets:
/settings
: This is where all your global variables, site-wide settings and configs go. For example, instead of declaring colors variables in every one of my stylesheets, I just put them and organize them in one single file under this folder.
/tools
: The tools folder is where you define your project mixins and functions, most of the time, I use it to store the Sass mixin I use for responsive media queries.
/generic
: Here, you can specify low-specificity CSS rules, like normalize.css and reset rulesets.
/elements
: When you need to style unclassed HTML elements like links, pages, images, tables, and so on, you can simply create a stylesheet in this folder for that.
/objects
: The objects folder is where you put your objects, abstractions, and design patterns like your layouts.
/components
: This is where the style of specific UI components goes. Honestly, I never use it, simply because I code my projects with Vue.js and it uses single file components.
/utilities
: The utilities folder is for all the high-specificity, very explicit selectors like the animations you need to use in your project.
It’s pretty neat, I know! 😄
If you’re using Sass loops, I definitely recommend using datasets, especially if it involves defining colors.
Let’s check this one in play by taking the example of social buttons. As you can probably guess, social buttons (Facebook, Twitter, etc.) have different colors.
So instead of having to write this:
// VARIABLES
$c: ".c-social-button";
#{$c} {
border: none;
border-radius: 4px;
color: $white;
user-select: none;
cursor: pointer;
// --> NETWORKS <--
&--facebook {
background: #3b5998;
}
&--google {
background: #db4437;
}
&--messenger {
background: #0084ff;
}
&--twitter {
background: #1da1f2;
}
}
You can choose a more elegant way:
// VARIABLES
$c: ".c-social-button";
$networks: facebook, google, messenger, twitter;
// THE DATASET FOR SOCIAL COLORS
$socialColors: (
facebook: #3b5998,
google: #db4437,
messenger: #db4437,
twitter: #1da1f2
);
#{$c} {
border: none;
border-radius: 4px;
color: $white;
user-select: none;
cursor: pointer;
// --> NETWORKS <--
@each $network in $networks {
&--#{network} {
background: map-get($socialColors, $network);
}
}
}
🎵 If your color naming convention is light-pink 👏 clap your hands. 🎵 If your color naming convention is dark-blue 👏 clap your hands. 🎵 If your color naming color convention is medium-grey, clap your hands. 👏
Okay, you get it and you know it: using terms like light, dark, medium and so on as a naming convention for your project colors is very limiting, simply because there are some projects where you’ll have a lot of color and this is not going to take you very far.
Instead of scratching my head about this one every time, I simply use Veli’s colorpedia. This way you’ll get to give your colors names that a human can understand while not being limited by the light/medium/dark spectrum.
Additional perks come with using Veli’s colorpedia Veli’s colorpedia — it provides you with matching colors and even tells you how a colorblind person sees it.
Some designers are just angels sent from heaven.
When you don’t have to use mixins, just don’t do it! Why?
Because when you use mixins, they have to be well-structured and maintained in a rigorous way. Using mixins for no good reason is the best way to get lost when the project grows. They can cause side effects and become hard to update when they are used in many places. So use them carefully.
If you don’t know whether and when to use a mixin, remember this one rule: Mixins are here to avoid repeating yourself by keeping a Single Source of Truth.
Also, as of today for example, we don’t have to use mixins to prefix CSS properties because we have plugins like PostCSS Autoprefixer that exist and do the heavy lifting for you.
Sass MQ is an open-source mixin crafted by developers working at The Guardian (fancy!). It’s amazing for two reasons:
It compiles keywords and px
/em
values to em
-based queries, so when users zoom on your page, the content doesn’t get all scrambled up.
It provides fallbacks for older browsers like IE8.
It simply works by compiling this code:
$mq-breakpoints: (
mobile: 320px,
tablet: 740px,
desktop: 980px,
wide: 1300px
);
@import 'mq';
.foo {
@include mq($from: mobile, $until: tablet) {
background: red;
}
@include mq($from: tablet) {
background: green;
}
}
Into this:
@media (min-width: 20em) and (max-width: 46.24em) {
.foo {
background: red;
}
}
@media (min-width: 46.25em) {
.foo {
background: green;
}
}
Elegant, simple and useful. What’s not to like?
To start using it, just go ahead and follow the instructions on their GitHub page.
One more final thing to get you a clean CSS code. I know that each one of us has our own way of writing CSS code, but doing so will leave you steps behind when working with somebody else or a team on a project.
That’s why I use CSS Comb. I installed the extension on VSCode, and every time I start a new project I set a .csscomb.json
file in its root.
This .csscomb.json
file includes a configuration that transforms your CSS code and your teammate’s into one single format whenever you run the extension.
You can use my own CSS Comb configuration below, or configure your own just by choosing the way you want your CSS code to look.
In a project, I have a set of properties that define a dark background. I very often find myself having to type them over and over again. Here is how using a placeholder can come very handy:
// The placeholder selector
%darkbg {
border: 1px solid #000000;
background: #101010;
box-shadow: 0 1px 5px 0 rgba(#404040, 0.6);
}
.my-dark-block-for-errors {
@extend %darkbg;
// Some other properties for errors
}
.my-dark-block-for-success {
@extend %darkbg;
// Some other properties for success
}
This will compile into the following css code:
.my-dark-block-for-errors, .my-dark-block-for-success {
border: 1px solid #000000;
background: #101010;
box-shadow: 0 1px 5px 0 rgba(#404040, 0.6);
}
.my-dark-block-for-errors {
// Some other properties for errors
}
.my-dark-block-for-success {
// Some other properties for success
}
Notice how it made our two blocks extend the placeholder? No need to repeat ourselves now and to remember these properties anymore. 😇
Awesome-Sass is a curated list of awesome Sass and SCSS frameworks, libraries, style guides and articles. It is a fantastic resource that keeps getting updates as of today. It includes so many interesting resources and it will deepen your Sass skills just by browsing it for a few hours.
For instance, this is where I discovered the Sass Guidelines or Sassline. 😇
I hope this article was useful. Sass will definitely save you time, and I also believe it made me a better developer. You can follow me on Twitter at @RifkiNada if you want to share more tips with me. 👋
Want to learn more about creating great web apps? It all starts out with Kendo UI - the complete UI component library that allows you to quickly build high-quality, responsive apps. It includes everything you need, from grids and charts to dropdowns and gauges.
Nada is a JavaScript developer who likes to play with UI components to create interfaces with great UX. She specializes in Vue/Nuxt, and loves sharing anything and everything that could help her fellow frontend web developers. Nada also dabbles in digital marketing, dance and Chinese. You can reach her on Twitter @RifkiNada or visit her website, nadarifki.com.