A code design pattern isn’t right just because it works for one developer. But when from developer to developer, project to project, as in our case, it works, one can declare it right.
In computer-speak, architecture can refer to the “manner in which components of a system are organized and integrated.” (Merriam-Webster, App) What manner have we chosen to organize CSS? Why? How has this worked for us?
To answer those questions, I’ve chosen to break this session into the following topics for discussion:
- Our architecture for CSS
- What principles led to our architecture
- What pain have we solved?
Our Architecture for CSS
Whereas you’d be doing yourself and your users a favor, as far as performance and user experience are concerned, if you could serve the browser only one CSS file for your entire project, how would you achieve that when you must break your code into several components, thus several files?
Tools. And our build tool of choice is Sass, which we compile with Gulp. We let Gulp use its plugins to compile all the many Sass files into one master file, convert it to CSS, minify the CSS, and hand it over for real-world use.
Here’s our structure:
1 2 3 4 5 6 7 8 9 10 11 12 dev/ |... |--sass/ |--layouts/ |--modules/ |--pages/ |--_base.sass |--_mixins.sass |--_utilities.sass |--_variables.sass |--style.sass |...
Here’s how all parts are called into the mother
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // // Main Stylesheet // @package dvx // @author Kabolobari Benakole <email@example.com> // @version 1.0.0 // // Imports @import "variables" @import "mixins" @import "base" @import "layouts/dir" @import "modules/dir" @import "pages/dir" @import "utilities"
I hope you can deduce from looking at that structure closely that we have, really, 5 parts (or topics) of Sass for this pattern. These are, in order as they should cascade,
1 2 3 4 5 base layouts modules pages utilities
I say “parts” because, first of all, everything can fit into a file itself. But the reason for folders for some parts is so you can further modularize, because such part as should be a folder has its individual modules or “chunks”.
Now, why have we so broken it down this way?
What principles led to our architecture?
There are 3 principles or questions I always ask for every line of CSS. It’s these 3 questions that helped me modularize CSS or Sass into this architecture I’m sharing here. Really, this architecture is the result of 4 years of writing and learning CSS and the following works:
- Scalable and Modular Architecture for CSS
- Scalable Modular Architecture for CSS (SMACSS)
- Thoughtful CSS Architecture
- Sass Guidelines
Now here are those 3 questions:
- Does this line of CSS serve one purpose? Yes, one purpose!
- Does this one purpose fit into a category?
- Has this Sass file reached 100 lines?
Once you’re able to answer any one of these three questions, you’ll immediately see where in your structure a particular line and then declaration block of CSS fits. Where a block fits will be any one of those 5 parts, and as you limit every file to fewer than a hundred lines, you’ll further see how you should have more modules, making your life easier.
Here is where style rules for bare HTML tags/elements will live, your default styles that’ll apply globally across your application. This should be a file and not a folder of files because you also want to keep it minimal, ensuring that you only override the browser’s basic styles as you got need to, only if you must.
Only if your typical
base file is exceeding 100 lines should you think of refactoring and breaking some components in there into there own separate file, wherein you can decide that they fit together.
Here is where you write all your styles having to do with structure or layout, no decorative elements are necessarily allowed here.
Depending on the size of your application, your
layout part may be a collection of files or just one file itself.
You want to be able to drag a particular layout block as in HTML from one section of your app to another without breaking anything if you have done layouting right.
Building this DevX Blog, my
layout part folder looks like so:
1 2 3 4 5 6 layouts/ |--_dir.sass |--footer.sass |--grid.sass |--header.sass |--sections.sass
As you might deduce,
_dir.sass is the directory that pulls every other layout file in and make the layout but one when Gulp puts it all together. Here’s what that file looks like for this setup:
1 2 3 4 5 6 7 8 9 10 11 12 13 // // Directory for all Layouts // @package dvx // @author Kabolobari Benakole <firstname.lastname@example.org> // @version 1.0.0 // // Imports @import "header" @import "footer" @import "grid" @import "sections"
So, once I figure my design is going to fit a discrete structural pattern, it’s time to give it its own file.
Nathan Rambeck defined “modules”, because he rather calls them “components, as “discrete, self-contained pieces of UI”. So, like a button, icon, even a slideshow, a component should be independent, “self-contained”, and can be moved from section to section, pages to pages of your application without any shake in structure.
Your modules should so independent, reusable.
Pages are my way of grouping CSS that I feel are too specific to a particular page of an application that it can’t fit anywhere else of our 5 parts.
So you may have a few style rules that are used for just the homepage of your app, which may override other style rules, but are only used for this homepage. Once so, you should create a file with a name like
homepage.sass and call it into your
Style rules that are called “utilities” are “single-purpose helpers” that do just one bit of tweaking or adjustment to a section or page of your application.
A typical example is a rule like so:
1 2 .d-blk display: block
Now you can drop on any element the class
d-blk and it’ll become a block-level element. That’s it, just one thing.
So with these 5 parts of base, layouts, modules, pages, and utilities we got the right architecture for CSS. And Sass and Gulp step in to make it possible. Really, with this architecture you can output even a 50,000-line CSS file which can be as ginormous as anything but lucky you you will never touch it!
Have we solved any pain with this?
What pain have we solved?
For me and the team, and, of course, for you, using this architecture to author your CSS, you
- Will write fewer CSS styles or rules
- Have no or only manageably few collisions of these rules
- Can move from project to project with your setup - sanity, right - and not break anything
- Got an awefully great maintainable codebase
- Can have any developer take over your project without needing you to explain a single thing.
Really, with an architecture like this, we got CSS feeling like engineering again.
So, I started by defending that this architecture for CSS is the right one. We have stuck with it on all our projects, just grabbing the entire folder and dumping it wholesale into another. I encourage you to try it for yourself and see that it works, giving you sanity authoring CSS.
In a subsequent session, I’ll take us through our style of naming, namespacing (when classes must be namespaced), and code organization.
So, while this session has exposed you to the right architecture, you still need these other things just mentioned to enjoy authoring semantic, sane, reusable, and manageable CSS with Sass and Gulp.