The Seven One Pattern
Organizing CSS is often an absolute nightmare for a backend developer. Let me guess, you just jumped onto a new project and got a request to fix a small layout bug in the UI. The container on the left hand side is now the full length of the page and you don’t know where to start fixing it. You see one megalithic CSS file, or some intern’s custom directory structure that turns the next three hours into the scavenger hunt from hell. This is why you hate CSS right?
What the F+++ is this?
The 7-1 pattern is just a way to organize your Sass files so you can find what you’re looking for. It also has the benefit of being flexible enough to resist the changes your client just requested out of left field.
It’s made of, you guessed it, seven directories and one main file.
This may seem like a lot, but every portion of a web app’s styling can find a clear and concise home in this structure.
Don’t believe me? The Sass Guidelines seem to think it’s a pretty good idea. But those only cover the basics. Let’s actually see what some of this code looks like.
Your base directory should contain the broadly applied CSS for your application.
- base elements
Starting here makes a bit of sense. In CSS, elements are the easiest selectors to override with classes and IDs. You can also think of them as the smallest building blocks for your UI. When we style our base, we are just setting up these building blocks to be used by other components.
Here is an example of what your base typography file may look like.
Utils is where our application wide variables, functions, and mixins should live. Think of it kind of like a helpers directory in an MVC application. This is where your colors and font sizes will primarily live. When updating a color in your codebase, that change should only need to happen in one place, instead of in a dozen CSS files.
This provides the framework for the rest of your styles and where you can abstract out common operations.
Now, we start to get into a bit of a fuzzy gray area. What defines one or the other within these three items is really up to you. The challenge comes down to figuring out purpose of what your styling and if it acts more like a layout piece, a component, or a page.
The important thing to take away, is that we want to scope our CSS rules into logical groupings for UI components. This should prevent the pain of unexpected changes occurring from updating your styles. Any errors should be confined to the widget or page in question, and that alone.
An isolated piece of UI; Buttons, Date Pickers, etc. Components may make use of sub components. IE; date pickers may contain buttons. We do, however, want to keep our components slim, and specific.
If a component needs to use a sub component, it should probably be confined to staying positioning or margins.
A layout component is a type of component that defines your site’s structure. Think headers, footers, content wrappers, forms, tables, etc. Layout components also slightly differ from regular components, as they are more likely to be custom to your web app. While a datepicker or a button may be used anywhere, chances are, your navbar styling is less portable and unique to your app.
Web pages with unique styling, like a login page, should be scoped to their own files. We isolate this out to keep “one time use” code away from our reusable components. It’s also way easier to find bugs for those special case pages, when they’re isolated into their own files.
Developer: “Hmmmm, the holiday advertisement page is broken. Maybe it’s in the pages/holiday-advertisement.scss file. Oh, I forgot to clear a float. Whoops”.
Your login page is a prime example.
We hope you never need this, but occasionally your site will require alternate themes. Luckily for us most of our code is finely broken down and we can just treat our themes as patches, updating styling where we need to. Just as our components override our base styling, our themes can sit on top as another layer.
If you must include third party CSS into your app, this is where it should go. You should probably keep it to just mixin libraries and grids, but it may also be necessary to include a datepicker’s CSS if you’re in a time crunch.
This is where your app’s styles come together, and will end up neatly packaged for your app, and where you should minify your CSS.
Every developer I have ever met has complained about CSS structure at some point in their career, bar none. If we want to make our lives easier as developers we adhere to design patterns. For modern languages, we often make use of MVC and Flux or hand responsibility off to a CMS. The 7-1 pattern is just one way of making our code recognizable and flexible.
The 7-1 Pattern works because it gives us a clear path of increasing specificity. We start with lowly base elements and slowly override styling as we introduce components, layouts, pages, and lastly themes. Everything else is given a separate home, either as a utility or a vendor.
Shame. Shame. Shame.
So, here is a little extra before we cap this all off. Every project has its time crunch inspired request. Sometimes specific browsers end up being incredibly difficult to work with for specific features. In these situations it may make sense to write less than ideal code to keep the project moving.
Let me introduce
The shame file is where we put our barrage of
asinine browser hacks, and code that defies all logic and reason. If you
were to show it to the developer next to you, they would throw crumpled up
paper at you.
I’m going to propose a few guidelines though, because it can be rather tempting to keep piling up the hacks. Think of it as the code of shame.
Code of Shame
- Shame code is terrible
- Shame code is temporary
- Do not let shame code see production
- If you are going to push to production, delete this file and fix the real problems
- Have a beer, watch tv, read a book, something, and forget the shame file ever existed