cult3

How to structure your Sass for large web applications

Dec 02, 2013

Table of contents:

  1. How to think about Sass
  2. How to structure your Sass architecture
  3. Conclusion

In my opinion, preprocessors like Sass and LESS are one of the best things to ever happen to front-end development. The ability to split your code into separate modules, use mixins, variables and keep everything organised in a logical structure is such a huge blessing.

I think it is totally unimaginable that you could write vanilla CSS for a large web application in 2013. Front-end development has evolved so much over the last couple of years. With rapid iteration and ever changing opportunities and constraints, there’s no way you could write plain old CSS and have it perform just as well.

I’ve written previously about getting started with Sass, setting up an Asset Pipeline in Laravel 4 or setting up Sass with Grunt, however I haven’t really covered how you should use Sass in your project.

I’ve seen a couple of projects recently where the developers weren’t really getting the full potential out of Sass because they hadn’t really stepped away from the old world of writing CSS. This is a shame because you can make your life and your code so much better if you organise your Sass correctly.

In this post I’m going to walk you through how I think about my Sass organisation, how I set up my directory structure and how I write my Sass to be maintainable and flexible going forward.

If you are new to Sass or even if you’ve dabbled in the past, hopefully this post will set you on the right track to getting the most from your front-end development.

How to think about Sass

I think one of the big things that hold developers back from getting the most out of Sass is the old mentality of writing CSS. You shouldn’t think of Sass as just CSS split up into separate files, you should think of it more as an opportunity to use all of the good design patterns that you know from programming.

Split everything into modules

The first thing to do is to split everything down into small modules of code. Even if the module is only a couple of lines long it still deserves to be in it’s own file. If something can be compartmentalised then it should because there is no impact on performance in doing so.

By splitting everything down into it’s smallest atomised form you will know exactly where to find something when you need to change it. By enforcing this separation you take a big step towards writing Sass that is much more maintainable when you inevitably come to make alterations.

Build from components up

The second big mindset change when writing Sass is to build from your atomised components up. By this I mean, take your individual components and combine them to get the result you want.

For example, traditionally you might have written something along these lines:

.sidebar .button .call-to-action {
}

Instead of writing your Sass from the outside in, you should write it from the component level up. So in the example above you would use the following classes instead:

.sidebar {
}
.button {
}
.call-to-action {
}

Why is this so important? Well what happens when you need a call to action button in the header rather than the sidebar? By compartmentalising your components you can reuse the individual styles to build up widgets that are not dependent on the specific initial intention. This prevents a lot of code duplication and allows you to write much more maintainable code.

How to structure your Sass architecture

So how does this theory play out in the real world? Well the following is how I set up my Sass file structure in the large web application projects I work on. I find this structure to work really well, especially in projects that are moving fast and have many developers working on them.

As ever, if you would prefer to change something about my set up, or you feel like there is a better way to handle something then please feel free to make your own adjustments. I’m not saying this is the perfect structure, but it works pretty well for me.

Setting up the structure

So the first thing to do is to create a Sass directory to hold all of your Sass files together. I’m going to call my directory scss but feel free to name it whatever you want.

Next, create a file called style.scss. This is simply going to be a Sass file that imports all of our modules into one file. This file should just be a list of Sass imports because if you start dumping Sass into this file you are on a slippery slope to unmanageable code.

Finally you should create folders for each type of Sass file we’re going to be working with. In my projects this is modules, mixins, style, partials and vendor.

Mixins

Sass mixins are functions that can accept arguments and return values. You should think of a mixin as a little nugget of code that will prevent you from repeating the same Sass over and over again.

For example, you might have the following mixin to automatically create the border radius syntax:

@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
  -ms-border-radius: $radius;
  -o-border-radius: $radius;
  border-radius: $radius;
}

.box {
  @include border-radius(10px);
}

As you can see, using a mixin allows you to define the output once and then use it throughout the your codebase. The mixin can also accept an argument so you can reuse this mixin not matter what type of border radius you want.

So in your mixin folder you should keep all these little nuggets of reusable code as separate files.

However with that being said, in the majority of the projects I work on I usually end up just using Compass or Bourbon instead. There’s really no point in reinventing the wheel and the code in these two libraries are going to be much better than the code that I write to solve the same problem. So in my mixin directory I usually only ever have project specific mixins.

Modules

Your modules directory is going to be where you keep all of your atomised reusable chunks of code that will form the foundation of your style structure. As I mentioned above, I like to keep these files really specific and small rather than over bloat them with too much responsibility.

I tend to use my modules folder to bootstrap the foundation of the style of elements, rather than apply specific styles. For example, if I want to make all buttons have the same amount of padding, border radius and default styles I will keep that code in the modules directory, but for style specific code I will keep that in the style directory. I think having a separation of foundational style and aesthetic style is important in bigger web application projects.

So examples of stuff I usually keep in this directory are, as I mentioned, foundation style of buttons, input boxes, list styles, form elements, typography, etc, etc.

Style

The style directory is where I keep all of the specific style variations of elements. I tend to think of this directory as the aesthetic layer of elements, rather than the foundational elements of just getting the thing to behave correctly.

For example I will have a buttons file in this directory that has classes for the specific types of buttons that I want in my application. These styles will simply extend the button foundation that I have in my modules directory.

Again, you don’t have to make this separation if you don’t want to. However, I think having a “disposable” aesthetic layer is really important once you begin to work with many other developers and the front-end code is rapidly changing under many concurrent iterations.

Partials

Your partials are the main chunks of your layout and will use the foundation elements from your modules directory to build up the components into layout specific elements. Your partials directory will hold separate files for your header, footer, sidebar or however you end up splitting your view files. Normally I end up mapping my view files to specific Sass partials, but if it makes sense to build up the components in your project in a way that does not directly map to your view partials then that’s fine too.

Vendor

When I’m working on a big web application I will nearly always use the same tools that I’ve used in previous projects because I like to work with a familiar canvas. Traditionally I’ve put Normalize in this folder to keep third party code separate from my code. However, recently I’ve started using Bower to pull in third party code for me.

I think it is still worth having a vendor directory to keep any third party code that you might need to use that is not available through Bower.

Conclusion

This is going to sound really nerdy, but I really love building up the front-end architecture of a project. Perhaps it’s my love of keeping things neat, tidy and organised, but I really love how the combination of Sass and Grunt allow me to organise all of my front-end code in this way.

In my opinion, it has never been a better time to be a front-end developer. I’m by no means a front-end specialist, however the tools that are available today make it so much easier to write and maintain front-end code for large web applications.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.