CSS Architecture

I’m attempting to compile a comprehensive list of how developers and front-end engineers structure their CSS using the SMACSS (Scalable and Modular Architecture for CSS) approach.

What is SMACSS?

SMACSS stands for Scalable and Modular Architecture for CSS, and is more a style guide than a CSS framework. On a high level SMACSS aims at changing the way we are turning designs into code. Instead of working in a page mentality where you try to turn a single page design into code, SMACSS aims to identify repeating visual patterns. Those patterns are then supposed to be coded into flexible/re-usable modules, wich should be independent as possible from the individual page context. This is not a revolutionary point-of-view for a programmer, but in the web design world this is indeed a newer way of thinking.”

“The basic concept of SMACSS is to divide styles into 5 categories: base, layout, modules, states and theme. Each category comes with a set of usage rules and naming conventions. The main reason of this categorization is that rulesets should only ever inherit and add to previous ones, never undo.” – Bram Smulders

According to Ben Frain, (Enduring CSS: writing style sheets for rapidly changing, long-lived projects) “it’s a common pattern to split up files in a project by technology type”.

my-project/
- html/
- js/
- sass/
- css/

He continues to say, “I therefore favour a situation whereby rather than organise by technology type, files are organised and grouped by visual component. So, instead of this:”

html/
- shopping-cart-template.html
- callouts-template.html
- products-template.html

js/
- shopping-cart-template.js
- callouts-template.js
- products-template.js

css/
- shopping-cart-template.css
- callouts-template.css
- products-template.css

“We aim for something like this:”

shopping-cart-template/
- shopping-cart.html
- shopping-cart.css
- shopping-cart.js

callouts-template/
- callouts.html
- callouts.js
- callouts.css

products-template/
- products.html
- products.js
- products.css

According to Bram Smulders, (How I improved my workflow with SMACSS & Sass) “in Sass you can easily chop your stylesheet into partials by using the @import rule. This allows us to easily organize and maintain our files similar like this:”

- theme.scss

	- theme/_base.scss
		- theme/base/_reset.scss
		- theme/base/_headings.scss

	- theme/_layout.scss
		- theme/layout/_masthead.scss
		- theme/layout/_main.scss
		- theme/layout/_footer.scss

	- theme/_modules.scss
		- theme/modules/_search.scss
		- theme/modules/_gallery.scss

	- theme/_state.scss
		- theme/state/_mediaqueries.scss

Jonathan Path and Laurent Sutterlity, created Sass + SMACSS which combines Sass with SMACCS.

And here’s an example of the folder structure:

On a very similar approach is Mina Markham’s Sassy starter – HTML / SCSS (SMACSS) and this is an example of the project’s file structure.

+ scss/
 |
 | + base/         # reset, typography, site-wide
 |  |-- _index.scss    # imports for all base styles
 |  |-- _base.scss    # base styles
 |  |-- _normalize.scss  # normalize v3.0.1
 |
 | + layout/        # major components, e.g., header, footer etc.
 |  |-- _index.scss    # imports for all layout styles
 |
 | + modules/       # minor components, e.g., buttons, widgets etc.
 |  |-- _index.scss    # imports for all modules
 |
 | + states/        # js-based classes, alternative states e.g., success or error state
 |  |-- _index.scss    # imports for all state styles
 |  |-- _states.scss   # state rules
 |  |-- _print.scss    # print styles
 |  |-- _touch.scss    # touch styles
 |
 | + themes/        # (optional) separate theme files
 |  |-- beccapurple.scss # rename to appropriate theme name
 |
 | + utilities/      # non-CSS outputs (i.e. mixins, variables) & non-modules
 |  |-- _index.scss    # imports for all mixins + global project variables
 |  |-- _fonts.scss    # @font-face mixins
 |  |-- _functions.scss  # ems to rems conversion, etc.
 |  |-- _global.scss   # global variables
 |  |-- _helpers.scss   # placeholder helper classes
 |  |-- _mixins.scss   # media queries, CSS3, etc.
 |  |-- _lib.scss     # imports for third party styles
 |  |-- + lib/      # third party styles
 |    | _pesticide.scss # CSS pesticide
 |    | ...
 |
 |  + ie.scss       # IE specific Sass file
 |  + styles.scss     # primary Sass file
 |  + _shame.scss     # because hacks happen
 |
 + .htaccess        # Apache server configs
 + config.rb        # Compass configuration file
 + crossdomain.xml     # cross-domain requests
 + docs/          # SassDoc generated documentation
 + deploy.rb        # Capistrano configuration file
 + Gruntfile.js      # Grunt configuration & tasks
 + package.json      # Grunt metadata & dependencies
 

According to Hugo Giraudel, (Architecture for a Sass Project), he likes to structure his Sass files as:

sass/ 
| 
|– base/ 
|   |– _reset.scss       # Reset/normalize 
|   |– _typography.scss  # Typography rules 
|   ...                  # Etc… 
| 
|– components/ 
|   |– _buttons.scss     # Buttons 
|   |– _carousel.scss    # Carousel 
|   |– _cover.scss       # Cover 
|   |– _dropdown.scss    # Dropdown 
|   |– _navigation.scss  # Navigation 
|   ...                  # Etc… 
| 
|– helpers/ 
|   |– _variables.scss   # Sass Variables 
|   |– _functions.scss   # Sass Functions 
|   |– _mixins.scss      # Sass Mixins 
|   |– _helpers.scss     # Class & placeholders helpers 
|   ...                  # Etc… 
| 
|– layout/ 
|   |– _grid.scss        # Grid system 
|   |– _header.scss      # Header 
|   |– _footer.scss      # Footer 
|   |– _sidebar.scss     # Sidebar 
|   |– _forms.scss       # Forms 
|   ...                  # Etc… 
| 
|– pages/ 
|   |– _home.scss        # Home specific styles 
|   |– _contact.scss     # Contact specific styles 
|   ...                  # Etc… 
| 
|– themes/ 
|   |– _theme.scss       # Default theme 
|   |– _admin.scss       # Admin theme 
|   ...                  # Etc… 
| 
|– vendors/ 
|   |– _bootstrap.scss   # Bootstrap 
|   |– _jquery-ui.scss   # jQuery UI 
|   ...                  # Etc… 
| 
| 
`– main.scss             # primary Sass file

According to Cathy Dutton, (8 Tips to Help You Get the Best out of Sass) “getting your site structure correct from the beginning is vital for any new Sass project. Using partials allows you to break the CSS up into smaller more manageable blocks of code that are easier to maintain and develop.”

“Partial files are created using an underscore and are not output as separate CSS files. Each partial should be imported using a master Sass file (global.scss) in the root of the Sass folder.”

vendor/
base/
|
|-- _variables.scss
|-- _mixins.scss
|-- _placeholders.scss
 
framework/
modules/
global.scss

According to John W. Long, (How to structure a Sass project) “one of the most useful features of Sass is being able to separate your stylesheets into separate files. You can then use the @import directive to include the source of your individual files into one master stylesheet.”

“But how should you structure your Sass projects? Is there a standard way of separating out your CSS files?”

“I like to layout my Sass projects like this:”

stylesheets/
|
|-- modules/              # Common modules
|   |-- _all.scss         # Include to get all modules
|   |-- _utility.scss     # Module name
|   |-- _colors.scss      # Etc...
|   ...
|
|-- partials/             # Partials
|   |-- _base.sass        # imports for all mixins + global project variables
|   |-- _buttons.scss     # buttons
|   |-- _figures.scss     # figures
|   |-- _grids.scss       # grids
|   |-- _typography.scss  # typography
|   |-- _reset.scss       # reset
|   ...
|
|-- vendor/               # CSS or Sass from other projects
|   |-- _colorpicker.scss
|   |-- _jquery.ui.core.scss
|   ...
|
`-- main.scss            # primary Sass file

“This allows me to keep my primary Sass file extremely clean:”

// Modules and Variables
@import "partials/base";

// Partials
@import "partials/reset";
@import "partials/typography";
@import "partials/buttons";
@import "partials/figures";
@import "partials/grids";
// ...

// Third-party
@import "vendor/colorpicker";
@import "vendor/jquery.ui.core";

How do you structure your CSS/Sass files?

Based on the findings, it looks like incorporating Sass/Scss files into your folder set up is the best way to start your project. Of course, assuming that you’re using Sass (and if you haven’t starting using Sass, why not?!)

There are plenty of resources to get your projects set up the right way but of course, everyone has different ways of approaching a file structure. So no matter how small or large your site will be, I hope these examples can help you look at CSS architecture differently for your next project.

References

Further Reading