We can't install SCSS and expect a web project to just magically fix itself, unfortunately. With all the designs I’ve built from scratch in HTML and SCSS, I’ve come to realize that structure is the underlying concept that makes projects easy to maintain, provides clarity, and ultimately keeps me from losing it. Ha-ha!
Okay, since I'm a designer, this structure is based off of Atomic Design. If you aren’t familiar with it, it’s basically having smaller components be combined with other smaller components to build bigger ones until you’ve built the pages of the website.
However, note that I’ve changed some of the terminologies because I'm weirded out by saying molecules and organisms in my projects. I prefer to use more accessible terms for people who are not necessarily designers and coders but are possibly concerned about bits and pieces in the user interface.
High level folders and files
It’s important to note that the main folders need to sort out neatly in the hierarchy to make browsing files a breeze. The folders are arranged from the non-tangibles to tangible elements of the website.
/abstracts /atoms /blocks /components /frames /pages css.scss
At least in my case, this arrangement makes pointing to a particular location more obvious. And as a UX designer, I can't stress this enough. I once worked on a project where all partials were stored in a single directory so we ended up constantly navigating a long list of unsorted files. Fun!
Abstracts
Abstracts contain rules and functions that govern the styles but are not visually tangible all by themselves. Rules and properties like text alignment, layers, and positioning shared among the more tangible elements are considered abstracts.
/abstracts ∟ /mixins ∟ _alignment.scss ∟ _animation.scss ∟ _appearance.scss ∟ _layers.scss ∟ _layout.scss ∟ _positions.scss ∟ _sizes.scss
Atoms
Atoms represent the smallest tangible elements in the website like colors, fonts, and icons. They are visually rendered in the page but need other atoms to make them look right.
/atoms ∟ /colors ∟ /icons ∟ /images ∟ /typography ∟ _fonts.scss ∟ _sizes.scss ∟ _styles.scss
Blocks
Blocks are a combination of one or more atoms that visually render elements in the page. Buttons, which could be a combination of text, color, and icon, are considered to be a part of this group— the building blocks of the website.
/blocks ∟ _buttons.scss ∟ _cards.scss ∟ _labels.scss
Components
Components are the more prominent features of the website which can stand on their own and be reused in different pages.
/components ∟ _article.scss ∟ _feed.scss ∟ _footer.scss
Frames
Frames contain the bigger layouts that hold components into place. These include the main-aside combos, grids, sections, and wrappers.
/frames ∟ _columns.scss ∟ _grids.scss ∟ _sections.scss ∟ _wrappers.scss
Pages
Page-specific styles are made in this directory. These could contain either supplementary styles or overriding styles.
/pages ∟ _about-us.scss ∟ _products.scss
If you feel like this is something you can use from now on, the next step is pretty much breaking down your design into this hierarchy. Conflicts are expected to arise especially if Atomic Design wasn't observed in the design phase.
By adhering to this, you might be knowingly and unknowingly encouraging rules and guidelines which could improve consistency and quality.
For example, you could set a margin rule for a component being used in different parts of the website. Because the space around that component could be unpredictable, and you might not want to target that component every time just to apply a bottom margin, you could implement utility classes as a rule.
So instead of overriding properties like:
.component { margin-bottom: 15px;}
.container > .component { margin-bottom: 25px; }
.container2 > .component { margin-bottom: 45px; }
You could just do something like:
.component { // no margins specified }
.mb-sml { margin-bottom: 15px; }
.mb-med { margin-bottom: 25px; }
Then in HTML:
<div class=“component mb-sml”></div>
<div class=“component mb-med”></div>
Still, I would say that it will take you a couple of tries and a deep understanding of what you’re working on before you could finalize these rules. After all, there's usually more than one way of doing things. Don’t forget to document your code thru comments so that it’s easier to make tweaks and minimize the learning curve for the newcomers.
The project base is available on GitHub with a little styling for you to explore and use. Feel free to build on it and let me know your thoughts in the comments so we can all make the CSS process better for everyone.
xavierpdaniel / scss-project
A standard SCSS project structure
Moving into Vue.js
The main difference I have right now as I’m learning Vue.js is that I move the SCSS component partials to each their own Vue components.
I also have to generate a base.scss in the SCSS folder which I then import into those components to serve as abstracts.
/src ∟ /assets ∟ /components ∟ /scss ∟ /abstracts ∟ /atoms ∟ /blocks ∟ base.scss
So in the Vue component:
<template></template>
<script></script>
<style lang=“scss”>
@import “../scss/base”;
.component{
//some properties
}
</style>
Aaand that's it. I hope you find this useful. I'll catch you guys on the next one!
Top comments (5)
Nice article, it helps having a concret example here.
Just wondering, what are your thoughts about having something like an
index.scss
in each high level folders rather than importing everything in the global stylesheet ?Thanks Ant Lio!
Your suggestion could also work especially if you have a lot more SCSS partials to work with. It’s relative to the scale of your project.
As for me, it’s enough to have it all imported in the global scss file since I can still easily view the partials from the side panel of my editor.
Good point, thanks!
I like this structure. I will try adopting it on my next project. Thanks for sharing.
No problem. Happy styling!