TIL Thursday: More Best Practices for Using Sass

You may remember a previous article about Sass best practices. For new and even experienced designers and developers, it can be difficult to know what guidelines you should follow.

As before, I've asked Senior Developer at NetSuite, Hayley Easton, for advice on what we should be doing when we're styling our sites.

Don't Style Tags or IDs

Barring a couple of exceptions (which we'll get to after) you should always assign a class to a tag and don't style the tag itself (p, small, h3 etc.). Likewise, don't style IDs (#my-id) — you should reserve those for use in JavaScript.

If you come across any that don't adhere to these guidelines, replace all the element type and ID selectors with class attributes in the HTML template and put the class selectors in your Sass. Here's an example:

/* Don't do this */
a.item-details-size-chart-link {
...
}

.look-item-cell {
p {
...
}
}

/* Do this instead */

.item-details-size-chart-link { // removed unnecessary element tag
...
}

.look-item-cell-description { // class placed on p tag in HTML
...
}

Exceptions

So as we said, there are two exceptions:

  1. When you're styling something and you're not able to edit the HTML. This probably won't come up very often but it might if you're dealing with functionality that pulls in a third-party page.
  2. For repeating elements where all elements look the same. The best example of this are list elements (e.g., li, th, etc). In this case, put a class on the containing element and then nest the element in the selector. For example:

.my-list-class {
li {
...
}
}

Reference Parent Selectors with &

A feature you may not know about in Sass is the ampersand. Using & in your stylesheet tells Sass to pull in the entire parent selector wherever you've used it.

/* Don't do this */
.my-class {
@extend .col-sm-3;
@extend .col-xs-6;
margin-bottom: $sc-medium-margin;
}
.my-class:nth-child(4n+1) {
clear: left;
}

/* Do this instead */

.my-class {
@extend .col-sm-3;
@extend .col-xs-6;
margin-bottom: $sc-medium-margin;
&:nth-child(4n+1) {
clear: left;
}
}

While you may just think that this just seems like a neat way of saving time and space, it can actually be used powerfully at the end of a selector too. Take the following example:

/* Don't do this */

.my-class {
margin: $sc-medium-margin;
color: $sc-color-primary;
}

.my-other-class .my-class {
padding: $sc-medium-padding;
background: $sc-color-background-list;
}

/* Do this instead */

.my-class {
margin: $sc-medium-margin;
color: $sc-color-primary;
.my-other-class & {
padding: $sc-medium-padding;
background: $sc-color-background-list;
}
}

This is a simple example, and you can read more about this sort of thing on The Sass Way. However, Hayley also recommends, for the more advanced, reading Joel Oliveira's blog post on this feature where he talks how it becomes 'killer' if your site has dynamically added classes.

But Don't Overdo Nesting

I just spent an entire section on how you can do clever nesting, so now I'm going to spend one emphasising the benefits of keep it in check.

The modular approach is good, but you can take it too far. Complex nesting can be very clever but it makes reading and maintaining it very difficult. Take the following code:

ul.menubar {
list-style: none;
> li {
display: inline-block;
> ul {
padding: 10px 0;
> li > a {
color: black;
}
}
}
}

While this valid code, it takes some time to figure out what exactly is going on. As you can see, too, it ignores some of the early guidance, namely not referencing element tags. So, for example, we could rewrite it this:

.menubar {
list-style:none;
& li {
display: inline-block;
}
}

.nested-menu {
padding: $sc-based-padding 0;
}

.nested-menu-item-link {
color: black;
}

Admittedly, one could even not bother using a class on the anchor tags if, like the list items, if it has a common parent. But you should get the idea. The point is, if you're using classes appropriately then you'll avoid this problem. Just remember that while complexity can be clever, it comes at the cost of simplicity.

Hayley pointed me to an article on SitePoint which goes through the pitfalls of selector nesting.

Consistent Style

There are a number of little suggestions that we can make that can improve the quality of your code.

Declare Variables at the Top or in a New File

We include a number variables by default in the BaseSassStyles module. If you find yourself using a particular value often, then use a variable instead.

However, you should put them in a place that makes them easy to find and gives context to others who are reading your styling. If you only have a couple, then just put them at the top of the Sass file — it makes them easy to find.

Comma-Separate Selectors onto New Lines

You may recall in earlier article we talked about how we chose the 'long syntax' style for our define statements in our module JavaScript. For Sass, we recommend a similar style. The difference between a period and a comma is not always immediately discernible; by breaking the selectors across new lines, you make it far more readable. For example:

.my-class,
.my-other-class {
padding: $sc-padding-medium;
}

Consistent Indentation and Spacing

We don't recommend either two or four spaces for the indentation of your properties. All we say is that whatever you pick, use it consistently.

Summary

These guidelines are designed to help ensure that your Sass is high quality. One of the key themes throughout these is simplicity. Having quality code that is consistent, simple and easy to read will make working with it (whether it is you or a colleague) a lot easier.

Further Reading