In software development, there’s this set of principles called the SOLID principles. As with most things in computer science, it’s yet another acronym in which each letter stands for the following:
- Single-Responsibility
- Open/Closed
- Liskov Substitution
- Interface Segregation
- Dependency Inversion
Though these ideas are geared towards software engineering and object-oriented design, there’s one principle that I think is relevant to front-end web development (well, actually a few but I digress for now).
Specifically, I think the idea of the single-responsibility principle is applicable to CSS – namely, within the popular LESS and Sass preprocessors.
CSS Single Responsibility
According to Wikipedia:
The single responsibility principle states that every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.
Doesn’t sound very applicable to stylesheets with all of this talk about classes and encapsulation does it?
Bear with me.
A Brief History of CSS
When CSS first hit the scene, it was pretty awesome – I mean, we finally had a way to separate the style of the markup from the markup of the data. The thing was, developers usually piled all of their CSS into a single file.
As the web became more complex, developers began to create separate files for each of their pages in order to isolate some of the unneeded files. After that, the CSS then introduced `@import` which made it possible to create separate files and then import those separate files into a single file.
So, as you can see, from early on we’ve been working to try to make CSS more modular – well, for lack of a better term.
Then preprocessors came along that allowed us to introduce nested rules, mixins, variables, and so on – it essentially extended CSS to include features that programming languages have had since they’ve been around.
And, of course, we still have the ability to separate files and import them into a single file when needed.
Now On To LESS, Sass, and More
So after that history lesson, we’re now actually at a point where we’ve got a lot of features in CSS, but we’re still faced with a set of challenges that have been around from the beginning.
Namely, how modular should our stylesheets be?
As this relates to the single-responsibility principle, I consider it something like this:
Each LESS/Sass file should be responsible for providing the set of styles for a single set of elements, page, template, or view.
For example, the structure of my LESS files often look like this:
/* Table of Contents * * - Color Palette * - Mixins * - Bootstrap Resets * - Elements * - Classes * - Body * - Navigation * - Social Icons * - Primary Content Wrapper * - Footer * - Media Queries *====================================*/ /* Color Palette *====================================*/ @white: #ffffff; @off-white: #fcfcfc; @black: #000000; @off-black: #050505; /* Mixins *====================================*/ .align_navigation() { } // align_navigation .collapse_lr_padding() { } // collapse_lr_padding .center_header() { } // center_header .rounded_image() { } // rounded_image .header_font() { } // header_font .post_title_font() { } // post_title /* Bootstrap Resets *====================================*/ .collapse { } // .nav-collapse .caret { } // .caret /* Elements *====================================*/ body { } // body a { } // a code { } // code h1, h2, h3, h4, h5, h6 { } // h1, h2, h3, h4, h5, h6 /* Classes *====================================*/ .alignleft { } // .alignleft .alignright { } // .alignright /* Header *====================================*/ #masthead { } // #masthead /* Navigation *====================================*/ #top-navigation-wrapper { } // #top-navigation-wrapper .navigation { } // .navigation /* Social Networks *====================================*/ #social-networks { } // #social-networks /* Primary Content Wrapper *====================================*/ #primary-wrapper { } // #primary-wrapper /* Sidebar *====================================*/ /* Footer *====================================*/ #footer-wrapper { } //#footer-wrapper /* Media Queries *====================================*/ /* Handheld */ @media (min-width: 320px) and (max-width: 568px) { } // handheld /* Tablet */ @media (min-width: 600px) and (max-width: 800px) { } // tablet
Obviously, this is just an example but it drives the point home: I separate sections of my code based on what they are responsible for styling.
This way, it makes it easy to locate and find the area of the styles with which I need to work, and it’s usually structured in such a way that it roughly matches my mark up.
The thing is, this gets really hairy to maintain over time, especially when you’re done with a single stylesheet.
To that end, I kind of consider a single stylesheet like a god-stylesheet (which is a nod to a god-class or a god-object, in object-oriented programming). In short, the stylesheet ends up knowing everything about the entire site when, in reality, maintenance would be much easier if we broken them out into separate files such as:
- `global.less` which would include variables and mixins
- `resets.less` which are used to reset the markup or reset elements based on the framework that’s being used
- `general.less` which would be the file in which all general elements (like `body`, `h1`, `p`, `span`, `a`, and so on are styled
- `header.less` which is obviously responsible for styling the header
- `footer.less` which is responsible for styling the footer
- …and so on
In short, the idea is to give each file a single responsibility.
Of course, this comes with its own set of gotchas just like everything else: From a development standpoint, it’s really convenient. Working on the header? Open `header.less`. Working on the sidebar? Open `sidebar.less`.
But we still have the problem of combining and minifying the files.
I know that there are some purists out there that will claim that we need to only serve up the styles that are applicable to a given page, but I’m more of the mindset that keeping things separated – that is, giving CSS single responsibility – in development is fine, but we should aim to serve up one minified version of the stylesheet.
That way, developers and designers are able to maintain their files logically, consistently, and easily, and we’re able to serve up a single file that results in a single request and that the browser and the caching system can store.
At least, that’s my take on it for now. But if you’ve got other opinions and better practices, I’m all for ’em.
This is exactly how I use the partials feature of sass. Each component lives in a partial, like _header.scss and _sidebar.scss, which then gets compiled into one gigantic css file, minified.
Forgive me for my ignorance, but I thought there would be something similar with less?
Oh, there is! I wasn’t so much trying to make a case for what CSS preprocessors use them and which don’t (that’s my bad); instead, I was saying that I think it’s a good idea to keep the presentation styles logically separated such that they maintain a single responsibility.
I’ve actually been doing this for a while now and it helps a bunch. This is usually what my style.sass file looks like:
@import ‘compass’
@import ‘compass/reset’
@import ‘susy’
@import ‘breakpoint’
@import ‘font’
@import ‘variables’
@import ‘base’
@import ‘header’
@import ‘footer’
@import ‘pages’
@import ‘post-types’
@import ‘widgets’
@import ‘woocommerce’
@import ‘mobile’
Everything has it’s place! It’s worked well so far. The only trouble I’ve had is differentiation between what goes in post-types vs pages, as that line is often blurred. The conclusion I’ve come to is the page (layout) styles go in page.sass and the styles for the post type itself goes into post-types.sass
Yeah – I think there are always going to be small nuances that need to be handled.
For example, you’re talkinga bout pages, but then there are also individual post formats. Should there be individual files for each format?
Personally, I think yes, but I can understand the rationale about keeping it in a general `posts` file.
Even still, even a post format is a type of post, then perhaps the argument is stronger that each post format deserves it’s own style.
Eh, another post for another time :).
Of course. For the sake of conversation, id probably say separate it if it were a larger project, otherwise no for a smaller one. Keep it simple. BUT that then begs the question why do something if you’re not going to do it always and consistently? Hrmmmm
When it comes to programming, there are very few things that we always do, you know? Instead, we end up doing things for a while until some incremental improvement comes along, and then we adopt that.
This even varies among programming languages, or even platforms for that matter.
Many people who see WordPress’ coding standards hate ’em because they don’t follow 1:1 with many of the PHP coding standards.
Are you familiar with SMACSS by Jonathan Snook? There are some good concepts on how to achieve CSS modularity but a lot of it also depends on the project and development style.
Do take a look anyways: http://smacss.com/
This is one of the things I love about preprocessors such as Sass and build systems such as Grunt – I can split up code as much as I want with no implications in production.