This past week I had an opportunity to browse through a company's coding guideline, some of which I found very useful not only in collaborative settings but also in developing personal projects.
Here are eight of SCSS best practices from the guideline that made me rethink the way I structure my CSS code:
Note: The following tips are geared toward SCSS, so some might not apply to pure CSS. Big thanks to @yzoja and @8detect for the great reminder!
1. Mobile First
When it comes to responsive design, it's common to prioritize the desktop version, which can make customizing for mobile a painful process. Instead, we should design to expand, not cram things to fit mobile.
Don't:
.bad {
// Desktop code
@media (max-width: 768px) {
// Mobile code
}
}
Do:
.good {
// Mobile code
@media (min-width: 768px) {
// Desktop code
}
}
2. Set Variables
Defining CSS variables and mixins should be part of the initial setup, which can make the project much more maintainable.
According to the guideline, here are some common properties that will benefit from variables:
border-radius
color
font-family
font-weight
-
margin
(gutters, grid gutters) -
transition
(duration, easing) – consider a mixin
3. Avoid #id
and !important
Both !important
and #id
s are considered overly specific and can mess with the order of CSS rendering especially when developing collaboratively.
Don't:
#bad {
#worse {
background-color: #000;
}
}
Do:
.good {
.better {
background-color: rgb(0, 0, 0);
}
}
4. Avoid Magic Numbers
Try not to set arbitrary numbers because they "just work"; other developers might not understand why the property has to be set in such particular numbers. Instead, create relative values whenever possible.
If you're interested, CSS Tricks have a clear explainer of why Magic Numbers are bad.
Don't:
.bad {
left: 20px;
}
Do:
.good {
// 20px because of font height
left: ($GUTTER - 20px - ($NAV_HEIGHT / 2));
}
5. Descriptive Naming
It's easy to define CSS selectors according to the looks. It's better to describe the hierarchy.
Don't:
.huge-font {
font-family: 'Impact', sans-serif;
}
.blue {
color: $COLOR_BLUE;
}
Do:
.brand__title {
font-family: 'Impact', serif;
}
.u-highlight {
color: $COLOR_BLUE;
}
6. Zero Values and Units
This one might be up to personal choice or specific project style guide, but consistency is key. The rule below asks that you specify units on zero-duration times, but not on zero-length values. Also, add a leading zero for decimal places, but don't go crazy (more than three) on decimal places.
Don't:
.not-so-good {
animation-delay: 0;
margin: 0px;
opacity: .4567;
}
Do:
.better {
animation-delay: 0s;
margin: 0;
opacity: 0.4;
}
7. Inline Commenting
The best practice here is to comment on top of the property you're describing. Also, use inline commenting (//
) instead of block-level comments (/* */
), which is harder to uncomment.
Don't:
.bad {
background-color: red; // Not commenting on top of property
/* padding-top: 30px;
width: 100% */
}
Do:
.good {
// Commenting on top of property
background-color: red;
// padding-top: 30px;
// width: 100%;
}
8. Nesting Media Queries
In order to easily locate media queries, it is recommended that you keep the media queries at the root of the declaration instead of nesting them inside each selector.
Don't:
.bad {
&__area {
// Code
@media (min-width: 568px) {
// Code
}
}
&__section {
// Code
@media (min-width: 568px) {
// Code
}
}
}
Do:
.good {
&__area {
// Code
}
&__section {
// Code
}
@media (min-width: 568px) {
&__area {
// Code
}
&__section {
// Code
}
}
}
These are by no means an exhaustive list of best coding practices, but they certainly play a vital role in designing readable, scalable web apps. Is there any CSS guideline that you follow as your north star? Let me know in the comments!
Latest comments (52)
Awesome!
Great tips for beginers
Thanks, this is an excellent post!
Heres a few additional things that helped me:
1Avoid naming colour variables after the colour. Go for $primary, #secondary, $light, $dark, etc. Eg:
You never know when a company will change it's colour scheme, and you can re-use the same colour.scss file accross multiple projects.
Another handy thing I use is creating new variables at the top of sections .scss files. For example, if I have a footer.scss file, at the top I might have:
That way I don't accidentally miss changing colours.
This is a really good summary. The only one I'm regularly guilty of is nesting the media-queries. I always do it and then regret it later!!
I find number 8 to be a struggle all the time, but I think it comes down to how many nested classes your mind has the capacity to remember. Personally anything more than 2 nested classes results in me scrolling longer than actually reading and apprehending the code.
The rest - totally agree. Very informative post!
What's wrong with
background-color: #000;
??That one was not about colors, but using
.class
vs.#id
, which is debatable, as you might notice from the comments. I should've kept the color code consistent, sorry for the confusion. That said, the guideline prefers RGB values, and here's their full explainer on colors: github.com/we-make-websites/wmw-co...It makes sense, I never thought about the readability of rgb vs hex. Probably cause I've been using hex for years xD
Pretty good article, but you’re mistaken about #ids. Using #ids is invariably dramatically more performant than using .classes when the downstream CSS is processed in the browser. Whatever you might subjectively gain in style in SCSS (I’d argue against that, too) will not come even close to matching what you’ll lose objectively in CSS processing/rendering time.
Some nice tips here, most of them I agree with based on my experience.
Performance is an lesser known benefit when using the mobile first approach. The browser can just ignore the media queries which results in faster css processing as well as less processing.
Not sure if, with hierarchy, you meant to say html structure. I believe it's important to note for someone who may think this. I believe strongly we should not bind css classes to html hierarchy. Meaning if you do .teaser-content-title and then have to add another element between content and title, your css is inconsistent. I'm a proponent of using BEM and Atomic design which make the process of thinking about your classes much clearer.
Nesting with &__section is quite troublesome with regards to reading, searching, and refactoring the code. Some find it useful and like the brevity, but autocompletion in most IDEs solves this non-issue.
All good tips, but I have a different preference regarding the nested media queries definitions: I actually prefer nesting them separately inside each declaration. I find it easier to check what's happening and don't need to scroll much to find the changes for each media query.
Also, for better performance, it is a good practice to merge all media queries on processing the SCSS files, using something like github.com/SassNinja/postcss-combi..., for example
Great article! Thanks!
Great article! I'm curious what others would say, but I found it useful to use !important for utility classes such as
m-t-5 { margin-top: 5px !important; }
.Utility class with important is a place where important can indeed be used. The tricky bit is that in general you rarely would want to use utility class at all. At least that's the goal. It pretty much says "Design seems inconsistent, let's make our code inconsistent too".
I’m curious on the last one about where to put media queries. I’ve used both ways but have found that I prefer the first way as it keeps everything together. The processor takes care of optimizing the code from what I’ve read so performance isn’t a reason as far as I understand. The second way, the preferred way in the article, ends up becoming distracting to navigate back and forth. What are the reasons to push the media queries to the bottom like that and break up information about the same class in two places? I did the preferred way first for a number of years and after I switched to the first (non-preferred) way it ended up working much better for maintainability for me.
This baffled me too. I’ve done both and ended up learning the “deeply nested” method ended up being far easier to comprehend in the long run, given the context was focused on the element being styled, not the media query. Particularly when reading the code of other developers’ code. For example, you may never realize (or may forget to check) for a particular element that there maybe yet another style being applied, maybe with a slightly different selector lower down in another media query.
I’m not sure if there are other technical considerations rather than just for code clarity and organization.
I agree with the sentiment of mobile first, its a good philosophy to follow. However, I've never seen the need to use min-width with desktop styles over max-width with mobile styles. At the end of the day, they accomplish the same thing and are almost identical, albeit a mirrored version of each other. As long as you keep your html structured in a way that will be possible to style for both, I think you're good.
However, I definitely wouldn't mix and match, especially not in the same stylesheet. That's just a headache waiting to happen.
I learned to avoid nesting like this the hard way... this can make searching for certain classes with "cmd+f" extremely difficult, and I've sometimes spent way too long pulling out my hair looking for certain selectors:
To make my code more searchable but at the expense of "less beautiful code" I've been doing this more often (sometimes I do break my rule though):
Thanks for your nice posting
Look forward to your next post