How I failed to write a CSS framework, and why you probably shouldn’t write one either

Ten Bitcomb
KPCC Labs
Published in
7 min readNov 20, 2017
It’s complicated enough already.

In a product team far, far, away, a major site redesign has been put on the roadmap. Place yourself in my shoes and imagine…

“Let’s write a CSS framework…” you say, “… so we can unify our design and make it reusable!”

How hard can it be? It’s just CSS.

You begin by comparing existing CSS libraries and frameworks, investigating where they are headed and what the trends are in design. What new style properties can we take advantage of? BEM? BEMIT? OOCSS? SVG icons or pure CSS icons? Pixels or EMs/REMs? What do we name this thing? Fine, we can’t agree on a name. Let’s just name it Goobybob and call it a night.

Weeks have gone by with little to show for it besides your notes. If you’re lucky, you made a prototype, but you soon realize your prototype was built on a misunderstanding of how your chosen naming convention works. Definitely not kosher! Looks like you’ll have to spend another day reworking it.

Another week goes by and your team reaches a consensus to go full steam ahead with BEMIT, and column/row/gutter sizes are now locked in. Yes, we’ll use R/EMs for everything! It’s only logical.

This will be great! Every project can now import this library and, with a pinch of gold dust, magically appear uniform with your brand’s image. Even those with less experience can easily build production-ready webpages.

The Honeymoon Phase

Finally, it’s now time to write this bad-boy.

It’s lookin’ pretty good so far; you’ve got your colors all defined, buttons & links have snazzy hover-states, the fonts you chose are exceptional, and form elements look slick. It’s time to get started on the masthead and the footer, yet you have this feeling that you’re missing something that every other CSS framework includes.

Your framework is missing a grid system. You need one of those, right?

You look at Flexbox, and while that can do a lot for you down the road, it requires more CSS-writing and knowledge on the part of the developer than you’d prefer. CSS grid looks promising, but there’s not enough support and adding a shim seems icky.

Fractal Mistakes

Everyone knows Bootstrap and its grid system, and you could selectively include it in your framework, but Bootstrap 3 is soooo 2013! You know you can make it better and simpler, right? Better yet, you can use flex properties to make your grid system even more nimble (a word deprived of meaning when used by most developers).

After some serious effort writing a grid system, it’s time to come back to the larger objects you’ll be including in your pages. The masthead and footer designs are straight-forward enough, but what if some projects are going to need non-standard elements, varying element ordering, and custom positioning with subcomponents? You’ll have to build your masthead and your footer to be super-extensible without becoming wonky at any given page-width.

By the way, the masthead now needs to have its menu elements behave like a single sliding-drawer at tablet/mobile sizes, but you already designed the masthead in a way that doesn’t easily support this. Another upcoming project will need the masthead to have horizontal-sliding submenus. You wanted to write one masthead to rule them all, and you’ll be damned if you can’t make that happen.

Other work has cropped up, and nearly 2 months have gone by. You have something that seems halfway decent, but you neglected to write documentation. Writing documentation is no fun! Then you remember that you’re a programmer; you should be able to automate the documentation process.

“I know!”, you say, “The documentation could be written with Jekyll and automatically construct pages from simple Markdown files and will derive structure and naming from the directory structure.”

Excellent! Except that means you’ll now have to install both Ruby and Node.js w/Gulp to develop the framework. And the live-reload feature keeps double-triggering or doesn’t work under some circumstances. Better ditch that for a simple Gulp w/ BrowserSync solution.

It’s finally time to get this thing out the door. Now you can integrate it into your existing products to create a unified experience for your users.

Duct tape will fix it.

It turns out that each of your company’s projects have more disparate requirements than you or your team realized in the beginning. While they share many of the basics such as your colors, fonts, units, icons, etc., there are different layout challenges in each one that your new CSS library doesn’t completely address; yet you feel compelled to make your library work for every scenario.

Eww.

Things aren’t looking as pretty as you thought they would. Your grid system now has several different “modifier” class names in order to fit niche cases, and you’ve even included a different layout system that does things the grid system can’t do.

Inside the projects where you included your library, your elements reference several generic class names — it took you ages to read through your own documentation and figure out what class names you needed to get things to match the design mocks. There are many times where you still have to use “overrides” to get something to position or scale properly and at the correct media breakpoints. In essence, the styling has become significantly divided between two codebases.

You finally break down and use the evil !important flag you promised you’d avoid from the very start.

It’s become frustrating to have your live-preview reload all the time because you’re changing your markup in order to adjust your style. In the back of your head, you know this wouldn’t need to happen if you actually wrote CSS for projects instead of trying combinations of prefab class names.

You’re at your last straw on a brand new project. You wanted clean markup and stylesheets that were easy to comprehend and modify, but what you have is a mess. It begins to occur to you that you’re not building prototypes or MVPs, but well thought-out production ready products, yet you’ve been treating your products as if they were prototypes this whole time.

If you didn’t know what exactly it was you were building, a prebuilt CSS framework might do the trick to just get something up and running.

Why would you spend months doing the same work that countless others have already completed, and did a better job than what you came up with? You’re not developing faster — you’ve actually lost time. You’ve spent months writing something that doesn’t actually do anything.

To make matters worse, you end up being the only one to use this CSS framework, which means you’re the “guy” or “girl” who masterminded it… and any knowledge behind it is now your responsibility since nobody has time to learn a new thing.

“You know, this makes me an asset to my company! They can’t fire me because I’m the only one who understands how this thing works,” is a thought you entertain.

But you’re not evil, and it wouldn’t be worth it anyway to deal with your own Frankenstein monster. Before it’s too late, you spend a few nights picking apart your latest web project, removing every trace of your monstrosity.

Your markup is now very clean and easy to reason about, and there’s no question as to where the styling for a particular element belongs. You even decide to work on a few unfinished portions on a project in development and, to your shock, you finish your work in less than an hour. That’s because you were able to focus on the design at hand instead of wasting time remembering a long list of class names or making updates to the CSS framework.

The end.

Epilogue

The sad story you just read is my story.

As I’ve said, it sounds like a great idea on paper. Perhaps a better programmer than I could pull it off, or maybe a larger team could under the right circumstances. But unless you have an actual need for a custom CSS framework (you probably don’t), and you have an actual team or open-source community working on it, it’s a pretty lousy idea.

It turns out that just writing CSS isn’t actually that hard.

The amount of time saved not developing a separate codebase to support multiple applications, and keeping its documentation up to date, completely outweighs any extra time spent writing style properties on a case-by-case basis.

Every project has its nuances, and chances are that you will spend less effort updating the styles for each individual project than you would updating debugging a shared CSS framework.

What I’ve learned from dreaming as big as I did is that a CSS preprocessor like Sass really does go a long way, and the CSS of today is not the CSS of 2009. You’ll get a lot more out of a shared set of variables around color, fonts, and other basics, than to write something that tries to be everything for everyone.

--

--