A Look at Different Sass Architectures
As the size and complexity of a project grows, you require some sort of logic to structure your Sass files. It helps to follow some agreed upon guidelines for creating files and folders when working in large teams and projects. Below is a review of some of the techniques in use today.
Bootstrap’s intention is to be a UI library for web developers to quickly get off the ground. It is logical for them to group all variables in a single file and keep all the mixin logic hidden. Their Sass architecture mimics this idea. Each component gets its own Sass file and there’s a
./_variables.scss file, which allows you to control all the variables involved with your project.
Bootstrap’s Sass architecture is unique in how it lays out its mixins. There’s a
./_mixins.scss file. This file imports all files from a
mixins folder, which contains a separate file for every mixin used. Although button styles are defined in
./_buttons.scss, the mixins used for it are imported from
./_mixins.scss. This, in turn, imports the button mixins from
mixins/_buttons.scss. Yo Dawg!
In addition to component-level mixins, the mixin folder also contains global mixins such as
mixins/_responsive-visibility.scss. Although bootstrap’s mixins are not overly complex, this architecture is better suited for a project where the mixins are really complex and require that they be broken down into smaller bits. Or in cases where you want to keep that logic hidden from visual styles of components. In conclusion, this architecture works best for Bootstrap but might not work for your sass project.
Here’s how the folder structure looks:
bootstrap/ |– bootstrap.scss # Manifest file |– _alerts.scss # Component file |– _buttons.scss # Component file |– _mixins.scss # Mixin file – imports all files from mixins folder |– ... # Etc.. |– mixins/ | |– _alerts.scss # Alert mixin | |– _buttons.scss # Button mixin | |– ... # Etc..
Foundation has a well thought out Sass architecture and it works beautifully for customizing, which is one of its biggest strengths. There’s a
settings.scss at root level, which allows you to override any variable used for building components. However, each component file contains variables specific to that component.
Foundation also abstracts functions used in the project in a separate
functions.scss file. This is good because these functions are framework specific and you should not be editing this file.
All global mixins such as border radius and transition effects are available in
components/_global.scss. They are logically structured as follows:
- Import - global mixins - Component specific variables (`$button-tny`, `$button-margin-bottom`) - Component specific mixins - Extends - (not the @extend but actual style definitions, where mixins are called)
All component-specific variables are defined as
!default, so that they can be overridden using the
_settings.scss. If you prefer to keep it simple, you can just change the variables in
_settings.scss and call it a day. If you feel more adventurous, you could play with component-specific variables and easily be able to change how your components look.
Since their components are built out of mixins and variables, it allows for maximum flexibility. A lot of sites built using Foundation don’t end up looking the same.
You can adopt foundation’s Sass architecture for most small to medium websites. It becomes very easy to get into the scope of any component and have all required variables, mixins, and extends within the same file.
Here’s how the folder structure looks:
foundation/ |– foundation.scss # Manifest file |– foundation | |– _functions.scss # Library specific functions | |– _settings.scss # Change variables for the entire project | |– components | | |– _buttons.scss # Component file (will import _globals.scss) | | |– _globals.scss # Global mixins | | |– _alerts.scss # Component file (will import _globals.scss)
Dale Sande, in his presentation “Clean out your Sass Junk-Drawer”, recommends a modular approach to organizing your Sass files. This comes in handy in enterprise-level projects where the number and visual complexity of modules can be pretty high. This approach helps retain all logic related to a module within its own folder, which allows sub-modules to extend and reuse styles in a scoped fashion. It can also be useful in small to medium projects, if you prefer separating presentation from Sass logic in your files.
One of the major advantages to following Dale Sande’s approach is the fact that it makes it easy to create a separate stylesheet for a particular module. Inside your project, you could load one base stylesheet that contains global styles and load another stylesheet specific to the module. This helps remove a lot of bloat from the code, improving performance and load speed.
Here’s the folder structure:
sass/ |– style.scss # Manifest |– modules/ | |– registration/ # Sub Module | | |– _extends.scss # Functional | | |– _functions.scss # Functional | | |– _mixin.scss # Functional | | |– _module_registration.scss # Imports functional partials and contains presentational | | |– _module_personalInfo.scss # Imports functional partials
Style prototypes, by Sam Richard, is a brilliant tool and set of guidelines for design in the browser using Sass and Compass. In this architecture, components are logically grouped under specific folders such as base, components, layouts (SMACSS) or atoms, molecules, and components (atomic design).
Further, each component gets its own set of partials:
_extends.scss and a manifest file (
This approach has a couple of disadvantages though:
- Compile time – More files require more time to get compiled
- It might require a lot of file switching when you build components initially. But once you are done, its a breeze to maintain or make changes.
The benefit here is the ability to work on a single portion of a module. It clearly demarcates configuration (variables), functional (mixins, extends), and presentational (component partials) portions used to design a component. Global configurations are kept separate from component/module level configuration.
This separation helps maintain sanity in medium to large projects, where you have multiple teams working on modules. It also becomes easier to create module specific stylesheets, when required.
Here’s the folder structure:
scss/ |– style.scss # Manifest |– partials/ | |– base/ | | |– _content.scss | | |– content | | | |– _variables.scss # Component specific variables | | | |– _extends.scss # Component specific extends | | | |– _mixins.scss # Component specific mixins | |– components/ | | |– _message.scss | | |– message | | | |– _variables.scss | | | |– _extends.scss | | | |– _mixins.scss | |– global/ | | |– _variables.scss | | |– _extends.scss | | |– _mixins.scss | | |– _functions.scss | |– layouts/ | | |– _article.scss | | |– article | | | |– _variables.scss | | | |– _extends.scss | | | |– _mixins.scss
I think Hugo does a great job of covering a SMACSS-based approach, which you can read about in his Sass architecture post, so I won’t discuss that here. There’s also a handy SMACSS starter kit by Mina Markham available.
In this article, we looked at different ways to structure your Sass files. To decide which method to use, you need to weigh your options between complexity, compile time, and personal preference.
This becomes tricky when working on teams. Make sure everyone feels comfortable with your approach and feel free to tweak methodologies to suit your specific circumstances.
I like the Style Prototypes architecture best because it suits the way I think. The important thing to note is
The deeper you nest, the longer it takes to compile.
Do let us know your project’s Sass architecture in the comments section.