The Options for Programmatically Documenting CSS

I strongly believe that the documentation should be kept as close to the code as possible. Based on my experience, that's the only option that works well in the long term. External documents, notes, and wikis all eventually get outdated, forgotten, and lost.

Documentation is a topic that always bugs me. Working on poorly documented codebase is a ticking bomb. It makes the onboarding process a tedious experience. Another way to think of bad documentation is that it helps foster a low truck factor (that is, "the number of people on your team who have to be hit by a truck before the project is in serious trouble").

Recently I was on-boarded into a project with more than 1,500 pages of documentation written in… Microsoft Word. It was outdated and unorganized. A real disaster. There must be a better way!

I've talked about this documentation issue before. I scratched the surface not long ago here on CSS-Tricks in my article What Does a Well-Documented CSS Codebase Look Like? Now, let's drill down into the options for programmatically documenting code. Specifically CSS.

Similar to JSDoc, in the CSS world there are a couple of ways to describe your components right in the source code as /* comments */. Once code is described through comments like this, a living style guide for the project could be generated. I hope I've stressed enough the word living since I believe that's the key for successful maintenance. Based on what I've experienced, there are a number of benefits to documenting code in this way that you experience immediately:

  • The team starts using a common vocabulary, reducing communication issues and misunderstandings significantly.
  • The current state of your components visual UI is always present.
  • Helps transform front-end codebases into well-described pattern libraries with minimal effort.
  • Helpful as a development playground.

It's sometimes argued that a development approach focused on documentation is quite time-consuming. I am not going to disagree with that. One should always strive for a balance between building functionality and writing docs. As an example, in the team I'm currently on, we use an agile approach to building stuff and there are blocks of time in each sprint dedicated to completing missing docs.

Of course, there are times when working software trumps comprehensive documentation. That's completely fine, as long as the people responsible are aware and have a plan how the project will be maintained in the long run.

Now let's take a look at the most popular documentation options in CSS:

Knyle Style Sheets (KSS)

KSS is a documentation specification and style guide format. It attempts to provide a methodology for writing maintainable, documented CSS within a team. Most developers in my network use it due to its popularity, expressiveness, and simplicity.

The KSS format is human-readable and machine-parsable. Therefore, it is intended to help automate the creation of a living style guide.

Similar to JSDoc, in KSS, CSS components are described right in the source code as comments. Each KSS documentation block consists of three parts: a description of what the element does or looks like, a list of modifier classes or pseudo-classes and how they modify the element, and a reference to the element's position in the style guide. Here's how it looks:

// Primary Button
//
// Use this class for the primary call to action button.
// Typically you'll want to use either a `<button>` or an `<a>` element.
//
// Markup:
// <button class="btn btn--primary">Click Me</button>
// <a href="#" class="btn btn--primary">Click Me</a>
//
// Styleguide Components.Buttons.Primary
.btn--primary {
    padding: 10px 20px;
    text-transform: uppercase;
    font-weight: bold;
    bacgkround-color: yellow;
}

Benjamin Robertson describes in details his experience with kss-node, which is a Node.js implementation of KSS. Additionally, there are a bunch of generators that use the KSS notation to generate style guides from stylesheets. A popular option worth mentioning is the SC5 Style Generator. Moreover, their documenting syntax is extended with options to introduce wrapper markup, ignore parts of the stylesheet from being processed, and other nice-to-have enhancements.

Other sometimes useful (but in my opinion mostly fancy) things are:

  • With the designer tool you can edit Sass, Less or PostCSS variables directly via the web interface.
  • There is a live preview of the styles on every device.

Who knows, they might be beneficial for some use-cases. Here's an interactive demo of SC5.

GitHub's style guide (Primer) is KSS generated.

Unlike the JavaScript world, where JSDoc is king, there are still a bunch of tools that don't use the KSS conventions. Therefore, let's explore two alternatives I know of, ranked based on popularity, recent updates and my subjective opinion.

MDCSS

If you're searching for a simple, concise solution, mdcss could be the answer. Here's an interactive demo. To add a section of documentation, write a CSS comment that starts with three dashes ---, like so:

/*---
title:   Primary Button
section: Buttons
---

Use this class for the primary call to action button.
Typically you'll want to use either a `<button>` or an `<a>` element

```example:html
<button class="btn btn--primary">Click</button>
<a href="#" class="btn btn--primary">Click Me</a>
```
*/
.btn--primary {
    text-transform: uppercase;
    font-weight: bold;
    background-color: yellow;
}

The contents of a section of documentation are parsed by Markdown and turned into HTML, which is quite nice! Additionally, the contents of a section may be automatically imported from another file, which is quite useful for more detailed explanations:

/*---
title:  Buttons
import: buttons.md
---*/

Each documentation object may contain a bunch of properties like title (of the current section), unique name, context, and a few others.

Some other tools that have been on my radar, with very similar functionalities are:

Nucleus

Nucleus is a living style guide generator for Atomic Design based components. Nucleus reads the information from DocBlock annotations.

Atomic Design is a guideline to write modular styles, projecting different levels of complexity on a (bio-) chemical scale. This results in low selector specificity and allows you to compose complex entities out of simple elements. If you're not fairly familiar with Atomic Design, the learning curve may look a bit overwhelming in the beginning. The entities for Nucleus include:

  • Nuclides: not directly useable on their own styles (mixins, settings, variables).
  • Atoms: single-class element or selector rules (buttons, links, headlines, inputs…).
  • Molecules: one or more nested rules, but each of them is not more than an Atom
  • Structures: the most complex types, may consist of multiple molecules or other Structures.
  • … and a few more.

The button example we use throughout this article here stands for an Atom - a very basic element of the stylesheet (single-class element or selector). To mark it as an Atom, we need to annotate it with the @atom tag, followed by the name of the component:

/**
 * @atom Button
 * @section Navigation > Buttons
 * @modifiers
 *  .btn--primary - Use this class for the primary call to action button.
 * @markup
 *  <button class="btn">Click me</button>
 *  <button class="btn btn--primary">Click me</button>
 *  <a href="#" class="btn btn--primary">Click Me</a>
 */
.btn--primary {
    text-transform: uppercase;
    font-weight: bold;
    bacgkround-color: yellow;
}

Here's an interactive demo.

Conclusion

There is yet to be a clear winner in terms of a tool or a common syntax definition for programmatically documenting CSS.

On the one hand, it seems like KSS leads the group, so I'd say it's worth considering it for a long-term project. My gut feel is that it will last for a long time. On the other hand, different syntax options and tools like Nucleus and MDCSS look promising too. I would encourage you to try them on short-term projects.

It's important to note that all tools presented in this article might do the job well and seem scalable enough. So try them out and pick whatever makes the most sense to your team.

I'd appreciate it if you would share in comments below if you know or have experience with any of these or other tools worth knowing about!