a frontend designer
writing

Building and Maintaining a UI Library: Part I

This post was originally published on CSS Tricks on February 2, 2016. Technical details of the implementation was posted in Part 2 the following day. This is a slighly amended version of the original.

When I first started working on web projects, stylesheets were seen as a necessary evil. It was neither a real language to be taken seriously by a computer-science minded engineer nor simple enough for a designer to fully own and understand. With few best practices, organization of the CSS was always ad hoc—“type styles in this section, colors in that section”—and every company did it differently. But as web applications, and the teams building them, grew larger and more complex it became harder to manage ballooning codebases while maintaining consistency across teams and projects.

  • Button Variations
    Form Elements
    1. This is a note for this input.
    Table Example
    Experiment Numbers Status
    Experiment name one 258
    Experiment name two that runs longer 19
    Experiment name three 400
    Experiment name four 568
    Experiment name five 25
  • Dropdowns and Pop Examples
    • This is for text that runs longer than a poptip and can be positioned in any of 9 locations around the trigger. This can include any HTML, images, etc., but shouldn't run too long.

    Accordion
    • Item One

      Make kind bring, that his yielding third two very given give winged, hath evening multiply whales them spirit without subdue. Man open it bring seas us stars a. Moved herb green likeness.

      Moved also. Their dominion fly void life had, all she'd. Man face multiply together open thing let evening appear two forth seasons Male very waters don't thing upon blessed which.

      Signs let yielding it abundantly cattle heaven day. Image second. Given is. Third seed beast. Living Together had you're bring unto in, rule rule may all they're appear second she'd for they're. Fruitful behold. Divide won't unto also.

      Make kind bring, that his yielding third two very given give winged, hath evening multiply whales them spirit without subdue. Man open it bring seas us stars a. Moved herb green likeness.

    • Item Two

      Doesn't winged living she'd likeness abundantly, years seasons light i were make sea great green our tree isn't bearing replenish, every made tree man you're.

    • Item Three

      Over you're abundantly land, over is. Evening to won't us gathering also kind let creepeth for saw behold. Bearing signs moveth deep man i open doesn't said won't shall. There night tree seasons shall i, likeness.

    Progress Bar
    60%
    1%
    Progress Steps
    • Step One
    • Step Two
    • Step Three
    • Step Four
    Loaders
Examples of the UI components in OUI. You can also view the complete documentation.

Among the first popular CSS frameworks that emerged to address this problem is Bootstrap. Many similar frameworks have followed but the purpose has always been the same: instead of writing CSS from scratch on a project by project basis, start with a styled set of the most common components—grids, buttons, form elements, breadcrumbs—that are cross-browser compatible and easily combined into larger interfaces.

At Optimizely we wrote and actively maintain our own Sass framework called OUI (pronounced like the French word for “yes”) based on the work of innumerable members of the web community including Mark Otto, Jonathan Snooks, Nicole Sullivan, and Harry Roberts and the philosophies of scalable, object-oriented CSS and HTML espoused by BEM and SMACSS.

Meet Louis, the official mascot of OUI.

The ongoing goals for OUI are to provide code that is...

In this post I’ll discuss the practical steps and the partnerships with engineers and designers it took to build it along with some problems we encountered along the way and, in Part II, my colleague Daniel O’Connor and fellow UI Engineer will describe the technical details of how we test, version, and integrate it into projects.

Phase 1: Get Your Designers On Board

Arguably the most important phase of creating a UI library is establishing close collaboration with your design team. Designing with a framework often requires a workflow shift away from pixel-perfect mocks and can lead to what might seem like a loss of design freedom. Fortunately there’s a way to address this: audit your site and present your findings.

Devote a day or two to taking screenshots of your site. Scour every nook and cranny for all instances of buttons, forms, tables, font sizes, colors, tags, icons, etc., and group them together. What you’ll likely surface will leave your designers aghast: buttons of all shapes and sizes, headings with little regularity, 27 shades of blue, and many other examples of good intentions gone bad. Putting your designers in charge of consolidating these inconsistencies will make them partners in the framework’s construction and allies in rallying others around the effort.

Phase 2: Own the Front end

Decide with your engineering team who “owns” the visual front end. Because your framework’s CSS and HTML are tied together we’ve found it’s important to have a smaller group, familiar with the framework’s patterns, responsible for delivering code to often thankful engineers who no longer have to wrestle with uncooperative z-indexes.

At Optimizely it’s our UI Engineers, who are officially part of the design team, that fill this role. With this tighter control we’ve dramatically cut the new CSS we have to write, our code is cleaner and more consistent, and we experience far fewer bugs. Over time the responsibility for writing HTML and CSS can widen as engineers understand how to use the library effectively and as the framework matures.

Phase 3: Identify Your Components

Bootstrap contains just about everything you’d need to build most sites. But maybe you don’t want breadcrumbs or perhaps you can use newer CSS properties because of your browser support. Either way we recommend referencing existing frameworks and creating a list of only the components required to cover your use cases. By building it yourself you’ll more easily identify potential trouble spots and will learn a ton in the process.

OUI was built with only the components and variables we decided were universal. Each Optimizely project that uses OUI adds any custom CSS code on top of it, only in that project’s repository. This allows each project to meet its unique design needs while keeping OUI lean and untouched. If different projects introduce similar components we have the option to “graduate” them into OUI, though this has rarely happened. In Part II we’ll describe our integration and versioning system in more detail.

Phase 4: Organize & Build

CSS preprocessors have been a boon for organizing code by supporting partial files containing only what’s needed for a given component. But it’s still a challenge to decide how to name things and where to put them. With OUI we currently use the following structure:

In the Sass we don’t use IDs, selector depth is kept to a minimum, and the source order helps us keep specificity low. You can take a closer look at the OUI repository.

Phase 5: Document & Evangelize

All this work won’t help streamline your code if nobody knows about it or how to use it. Here are a few suggestions that have helped OUI gain traction at Optimizely.

  1. Pick a code name. Like any good engineering project, your framework should have an internal code name. It’s probably not something you usually do with CSS projects but, hey, this one is important! If it’s short enough you can use it as a prefix for namespacing classes.

  2. Provide good documentation. As anyone who has ever tried it knows, writing and more importantly maintaining good documentation with code samples, usage guidelines, and a changelog, is not easy. Incomplete or out-of-date documentation will only frustrate your developers and can undermine trust in the project. To combat this, nominate owners and have clear expectations about what to document and how to keep it accessible and current.

    This is an on-going challenge for us, but we’re inching closer. Unhappy with existing solutions, Daniel O’Connor has been leading the effort to build a robust living style guide script, called ScribeSass, that parses comments and code in Sass source files and renders code samples and examples. We’ll be releasing that as an open source project soon.

  3. Evangelize. With your pithy code name and documentation in place, start spreading the word. Give tech talks using real examples that demonstrate the speed and consistency benefits of reusing existing styles and patterns. If you have the budget for it, make stickers, t-shirts, or posters. Each month collect statistics on the size, rules, and specificity of your CSS and the number of bugs and time your team spent fixing them and share the results. We saw drops across the board.

Lessons Learned

Like any web project we made lots of mistakes, fixes and additions along the way. Here are a few of the challenges we faced, adjustments we made, and issues we continue to confront.

Results So Far

Though the following comparison isn’t quite “apples to apples”, these CSS statistics* come from two similarly visually complex products at Optimizely. The first is an older application built prior to OUI and the second used OUI exclusively.

Pre OUI OUI Change
Gzip Size 101KB 33KB -68%
Stylesheet Size 618KB 193KB -69%
Rules 3259 1757 -46%
Selectors 5183 2407 -54%
Identifiers 21375 4009 -81%
Declarations 9356 4429 -53%
Specificity Per Selector 87 15 -83%
Top Selector Specificity 641 50 -92%
ID Selectors 3135 0 -100%

* Most values generated using Parker, a "stylesheet analysis tool".

Summary

Managing a framework at your company, either by forking an existing one or writing your own, can be daunting. But for design and engineering teams concerned about maintaining consistency between projects, the benefits are too numerous to ignore. By relying on predefined patterns you’ll get uniformity in visuals and in code, faster HTML builds, fewer bugs, less CSS bloat, and it allows product designers to spend less time on specifications and more time on the bigger challenges of user experience and information architecture.