Engineering 5 min

How to structure your Sass codebase

Written by Luis Serrano
Dec 16, 2019

Share

share to linkedInshare to Twittershare to Facebook
Link copied
to clipboard

We use Sass at Remote, especially the .scss syntax. Sass gives our team features that don’t exist yet in CSS, like nesting selectors, mixins, functions, variables (although CSS has now custom properties they have differences), which are great for productivity.

It’s a good opportunity, when starting a new project, to look for formatting, naming and architecture standards.

We’ve been using a pattern by Hugo Giraudel, the 7-1 Pattern in almost all of our previous projects and it’s being a good fit for all our needs. You can find more about it here.

Using this pattern you have all your sass partials in 7 different folders and a single file at root level that imports all folders. This is used to later compile everything to a single CSS stylesheet.

plain
1base/
2components/
3layout/
4pages/
5themes/
6abstracts/
7vendors/
8main.scss

This has been our go-to architecture and we’re following almost all recommendations. However, there are some nuances that we felt the need to overcome and so we created our own approach to this architecture so that it could fit codebases of all sizes.

main.scss with all the imports

We didn’t like the idea of having a file importing every sass file on the project because we would get a big CSS file with all our code being used on every page and having a lot of unnecessary CSS being loaded.

Our solution:

There are only two folders that we need to import on any page, the abstracts and the base folder.

For these folders, we’ve created a _global.scss file where we’re importing all files inside.

plain
1/abstracts
2 _functions.scss
3 _variables.scss
4 _mixins.scss
5 _global.scss
6/base
7 _general.scss
8 _fonts.scss
9 _global.scss

On each _global we’re importing:

plain
1// abstracts/_global.scss
2@import 'variables';
3@import 'functions';
4@import 'mixins';
5
6// base/_global.scss
7@import '../abstracts/global';
8@import 'general';
9@import 'fonts';

Since we need the files in the abstracts folder in any scss file to be able to use the mixins, variables or functions, we can save some time and import the _global.scss in the abstracts folder in the _global.scss of the base folder. Without this, we would have to import abstracts _global on every single page.

We’re using webpack to generate multi entries and outputs to create a specific CSS file for each page and importing only what it needs. You can find more info on how to use webpack with Sass here. With this solution, we can create a sign-in.scss file in the page folder that will import all the defaults and specific components to be rendered on the page.

plain
1// sign-in.scss
2// scss/ is an alias
3
4@import 'scss/base/global';
5@import 'scss/layout/header';
6@import 'scss/layout/form';
7@import 'scss/components/buttons';
8@import 'scss/components/auth';
9@import 'scss/components/loaders';

Using fewer folders

We’ve started following the folder structure that the 7-1 pattern suggests, but on all projects that we’ve worked with, none of them had the need for all the folders.

So, if you take an approach of using only what you need, independently if it’s a small or big codebase it only impacts the number of files.

plain
1/abstracts
2 _functions.scss
3 _global.scss
4 _mixins.scss
5 _variables.scss
6/base
7 _fonts.scss
8 _general.scss
9 _global.scss
10 _typography.scss
11/components
12 _header.scss
13 _form.scss
14 _buttons.scss
15 ...
16/vendor
17 _bootstrap.scss
18 _normalize.scss
19/pages
20 auth.scss
21 homepage.scss
22 ...

Abstracts

The /abstracts folder contains all the sass helpers you can create to help you out on your project. This is all about sass tools, variables, mixins, functions, placeholders, etc.

We’re using the _global.scss to import all files so we don’t bloat other files with these imports.

Base

The /base folder contains all the boilerplate of the project. It’s where we set the default styles, import custom fonts, set the default style for the headings, paragraphs, hyperlinks.

Components

Following the component-based approach of Javascript frameworks like React, we treat everything a component. These are independent, reusable pieces of the UI and you can think of components like a navbar, a header or a button.

That’s why instead of using a layout folder for elements like a Footer or a Header, we create pages that are composed by components.

Vendor

The /vendor folder contains all the third party files that the application needs. It can be a reset CSS file, bootstrap, anything you could think of.

If these files should be included in any page of the website, we import in /base/general.scss.

Pages

The /pages folder should contain the specific styles for each page with the filename being the name of the page. In our use case, we use webpack to create specific CSS files for each page and import all the default styles and the components that I need for each page. You can find more information on how we do this here.

This approach allows us to import only the code that the page needs and reduce the size of the file.

An example could be something like this:

plain
1// billing.scss
2@import 'scss/base/global';
3@import 'scss/components/header';
4@import 'scss/components/footer';
5@import 'scss/components/form';
6
7.billing {
8 max-width: 640px;
9 margin-top: pixelToRem(90px);
10
11 &-section {
12 margin-bottom: pixelToRem(60px);
13
14 p {
15 margin-top: pixelToRem(5px);
16 }
17 }
18}

If you’re not using something like webpack to bundle and convert your javascript and sass/less files and you have a main.scss where you import everything, this approach allows you having a _global.scss file per folder importing all the other files and import these globals to your main file.

plain
1// main.scss
2@import 'scss/abstracts/global';
3@import 'scss/base/global';
4@import 'scss/components/global';
5@import 'scss/pages/global';
6@import 'scss/vendor/global';

Summary

We hope you find this article helpful, as the 7-1 pattern was very useful to us. With the structural foundation for our SASS codebase and with a few tweaks here and there we got to a point where we’re finally happy with its productivity and organization.

We’d love to hear what you think about this and how we could further improve this approach!

Start hiring with Remote, the new standard in global HR

Create an account with G2's top-ranked multi-country payroll software and start onboarding your first employees in minutes.

Get started now
Remote is the G2 top-ranked multi-country payroll software

Subscribe to receive the latest
Remote blog posts and updates in your inbox.