Whenever I start a new project, I get that good feeling. This is a fresh start, a new beginning. I'll get a chance to do things better than last time. I'll be able to use that new methodology I just learned. Everything will be great. I start out so organised and so determined to keep things that way. It doesn't last.
Despite my best efforts, that organisational harmony soon gets away from me. All developers have experienced this, and nowhere is it harder to keep things organised than with our CSS and UI components. The nature of CSS and the way we use it sets us up for failure. Whenever we need to make a change, it's hard to know exactly what impact it will have, so in desperation we resort to adding new code instead of refactoring. No other language is as challenging to maintain in this way. I used to think it would take several months before I'd lose control of the situation. Now I've lowered my estimate to two weeks. As soon as you can no longer hold all of your working concepts in your head at once, you're doomed.
We've all developed tricks to help ease the problem. Good file organisation and selector naming is a start. A modular pattern like SMACSS can do nothing but help. A preprocessor abstracts away some of the duplication. Our real problem, though, is not being able to see the forest for the trees. Readability isn't enough. We need to be able to understand what we're working with.
Pattern libraries can help us with this. But what exactly is a pattern library? Most people immediately think of a style guide, and that's not far off, but a pattern library has some important differences. Whereas a style guide informs us about how things should look, a pattern library is really a tool for developers to maintain their living web components. It is as much about code as it is about visuals. A pattern library is a single place where you can develop, test, organise, view, and share all your styles and components. So what can such a library do for you?
- Prevent duplication. By developing for a pattern library instead of a specific feature on a specific page, you write code and create assets that are inherently reusable. By writing more reusable code, you can greatly improve upon performance, reduce development time, and lower your maintenance burden.
- Streamline testing. By writing your HTML and CSS in a controlled environment, you're creating much more test-friendly conditions. You can test your code without the idiosyncrasies of a more complicated container. You can get each component right for its own sake, then drop it where it needs to go with confidence. It also creates a much simpler place to do cross-browser or automated testing. You can run the pattern library on its own without having to worry about the complexities of loading fully functional pages.
- Improve documentation. It is not specifically the goal of a pattern library to act as detailed documentation, but it is a natural consequence of having one. A pattern library lets you develop and test your work in one place, so you end up with something that serves as an ongoing reference for you and your team.
- Facilitate sharing. A pattern library is a great tool for communicating with the team as a whole. A rasterised PSD is a good starting point, but it has limits. Once you have all that design worked out into real, living HTML that has to survive in a fickle, changing browser environment, it gives everyone a more accurate idea of what those design assets are really going to be like. This is also a useful way to work collaboratively with a designer. You can build out concepts quickly, let the designer see them working in a browser, and make rapid adjustments, without having to wait for the whole site to be built.
- Show the big picture. This is the most important benefit of all. Being able to see your assets all at once simply changes the way you work, and even the way you think. Without a pattern library, while there is nothing to prevent you from scouring your CSS and HTML for something similar whenever you need to add a new button, in practice, this is very difficult. You may think of your new button as a 'call to action', but how do you search for that? Maybe the equivalent asset was previously called 'primary', or 'cta', or even 'orange'. Being able to see everything in one place makes it clear exactly what you have to work with.
The other advantages of pattern libraries are harder to quantify. I've found that the real power in using a library to organise your CSS and visual assets is in the subtle side effects. Being less likely to create duplicate assets is the gift that keeps on giving. It directly addresses the problem of constantly growing CSS.
You also end up with a much more consistent design and experience. By forcing yourself to use reusable components and think twice before adding something new, your product will feel more consistent to users, which, in turn, will make it easier to navigate.
You will also end up with better code. The pattern library code will be separate from highly specific feature code, and will end up being written in a much more modular, readable and maintainable fashion.
In the end, this all makes for happier developers. Without the stress of never knowing whether a change to your CSS is doing more harm than good, and with clearer, more maintainable code to work on, the development process is much more enjoyable.
Creating your own libraries
So how do you go about creating your own pattern library? First, build using OOCSS concepts. Start simple, with your atomic components, get them right, and then build greater complexity on top of them. Every step of the way, you should have a pattern that proves the component is working on its own.
Design your library for speed and efficiency of use. This is a tool to help developers write and maintain great code. Anything that creates friction for the people who will use it every day weakens its strength. If developers avoid it, it will fall out of date, and you end up back where you started. Similarly, favour simplicity and ease of navigation over documentation. If you can't see similar components all at once because there's a paragraph of text before each one describing it, the library will be a lot less useful in helping you stay consistent.
Finally, break everything up into separate units and files, and use a preprocessor to help share common variables. Since the code is broken up, you're going to need a strategy to merge it all back together and compress it. If your framework of choice doesn't already have a strategy for this, such as Rails' Asset Pipeline, use a tool like Grunt to simplify the process.
Ultimately, how you design and build your pattern library will vary from project to project, and from team to team. Larger projects will invariably have more components, and will need to spread them out over several pages, requiring more documentation; whereas on smaller projects, you can get away with a simpler approach. Use your own judgment. But most of all, kick back and enjoy your new lean, mean, awesomely maintainable CSS codebase.
Words: Reed Lauber