Sjardo Front-end stuff.

Dangers of SASS nesting

When I got into SASS, I really enjoyed all the new possibilities it gave me. Breaking up the code in little bites, useful functions that do a lot of work for me, the use of variables and lots of other things. In the end, it taught me to be a better developer. There are also some dangers that I didn’t think of when using all the features SASS gave me.

SASS is very powerful and gives you the ability to make your code much more readable. For me, the best example of this is Nesting. Nesting of SASS makes it easier for you to “continue” writing styling for elements without constantly having to re-write the parent elements of the current element your styling.

Below i created a little bit of plain CSS that we all know.

.content {
	background: #000;
}

.content p {
	margin-bottom: 20px;
}

Easy to write, easy to read. Still we had to write .content twice, which is a waste of our time. With Nesting elements, we no longer have to do this.

.content {
	background: #000;
	p {
		margin-bottom: 20px;
	}
}

As you can see. The code is smaller, we only write .content once and it’s intuitive. The P element stands inside the .content. This makes the P a child of the .content. After compiling, it’s still the same as the regular CSS we wrote. With the knowledge that the CSS output works, it’s very easy to do this over and over again and dive into a very specific styled element. This is where it got dangerous for me.

Making it this easy to nest all the elements ,I ended up with elements which had styling that was too specifically declared, I just looked up a more specific way I could target that item. This way I was able to almost always style the item that I would like to style. And if i really needed, a important! was used. Just to be sure.

Below a very common piece of code I used to write:

body {
  &.home,
  &.contact{
     #page {
        #white {
           color: white;
        }
        .content {
           background: black;
           width: 1000px;
           strong {
              color: orange;
              &.notice {
                 color: green;
              }
           }
        }
        &.special-page {
           .content {
              p {
                 margin-bottom: 20px;
                 strong {
                    color: purple;
                 }
              }
           }
        }
     }
  }
}

You probably agree that it’s OK from a readability aspect. We got our self a body with the class home or contact,   an element with the ID page. In an page, we have a .content with some styling. In the .content you can find a strong element that could have a specific class to make it green.

It’ piece of code that got me thinking, starting from &.special-page. This means we have a body with the ID home or contact. It could also contain a .special-page class. In that area we have, once again, a .content, with p element. In that P element we got the strong that has a new color. You see how deep we are getting? Now check the output.

body#home #page .content,
body#contact #page .content {
   background: black;
   width: 1000px;
}

body#home #page .content strong,
body#contact #page .content strong {
   color: orange;
}

body#home #page .content strong.notice,
body#contact #page .content strong.notice {
   color: green;
}

body#home #page.small .content p,
body#contact #page.small .content p {
   margin-bottom: 20px;
}

body#home #page.small .content p strong,
body#contact #page.small .content p strong {
   color: purple;
}

This looks bloated. It is bloated. And why did this happen? That’s for two reasons. First, I’m by nature a very lazy person. I don’t like to refactor my own code to make it easier or future proof. I just want result and go to the next thing. If I had to add some styling, I just implemented the new styling on the right spot. Yes, it can fix things quick, but that also gives a lot of extra code in the output that I don’t really want. Let’s say, I want the .special-page have a 600px width. I just place it on the correct line like this: width: 600px;. In the output, it will give me lots of new bits:

body.home #page.special-page,
body.contact #page.special-page {
    width: 600px;
}

It might be what we need, but it’s way too much code for something only the .special-page should have.

This takes me to the second point. I never cared about others. I have the privilege that I always have high-speed internet. I never thought about page speed, as i’m always on a 4g or high-speed internet connection. Everything is “fast” for me. So why should I care about a little bit of useless CSS in my stylesheet?

After starting working at Yoast, one of the things I learned is that page speed is something to care about. The faster the page, the best foundation you got to serve great content. I’m on the theming bit of the yoast.com website, that means that besides writing good code, i need to keep my code as small as possible so people with a mediocre or even a bad connection can experience fast page loads.

After working on a couple of pages,I noticed a lot of the above example on pages I created. A massive load of parents and nested elements just to make sure I got a good looking site. The CSS file was way too massive for the simple styling I wanted to achieve.

This made me decided to do something about it. I checked the output to find optimizations. And I found them. A lot, and even easy to fix. How? I asked myself what I would do if I had to build the whole page / site again. This is the point where I had to apply more structure to my SCSS.

Divide page-styling and partial-styling.

The first step I took was making sure I was styling a unique elements for a page or a part that can be used in different places. A unique element for a dedicated page can be targeted high up the tree (for instance, an ID on the body) and a pretty direct path to the element: body#home .content {}.

If I had to style a component, something I see as a reusable piece of HTML with a specific purpose that can be anywhere (like a header image or a sidebar), I made sure it had a container element with a specific ID. For example, #header-image{}. All the other elements that are used around the site that can be inserted on multiple places and are not a partial on its own (like the H1, p, a, etc) were placed inside their own SCSS file (you can split that one up too, if that’s something you would like ).

This way you have to think for yourself that if you edit a partial, you edit the partial all over the site. If you add CSS to your page files, you know you’re doing specific styling for an element. If you’re doing some specific styling. Target high, get straight to the point. Small bits of CSS. That’s all we need right?

My directory now looks something like this:

  • Variables
  • Utilities (global settings like the h1)
  • Partials
    • Header-image.scss
    • Content.scss
    • Footer.scss
    • Aside.scss
    • Article.scss
  • Pages
    • Home.scss
    • Contact.scss
    • Single-blog.scss
    • archive-blog.scss

When applying the first refactoring to Yoast.com, we did a 30% decrease in CSS file size. The next step is to work on BEM-ifying the CSS. This way we have even better CSS, less code and an easier way of maintaining our css-system.