--- layout: post title: "More Transparent UI Code with Namespaces" date: 2015-03-06 14:11:00 categories: Web Development meta: "Employing a suite of namespaces to make your UI code more readable and transparent" --- When we work at scale, we often find that we spend a large amount of our time reading, maintaining, and refactoring existing code, rather than writing and adding new features. This is the reason we focus so much on things like architectures, naming conventions, methodologies, preprocessors, scalability, etc.: because writing CSS is easy; looking after it is not. What we want is to be able to write code that is as transparent and self-documenting as possible. Transparency means that it is clear and obvious (to others) in its intent; self-documenting means that we don’t have to lose time to writing and reading lengthy, supplementary documentation. The need for this is particularly true when working with languages like HTML and CSS. Their declarative nature means there is no control flow to give clues as to the state or shape of the project, and the fact that the two languages are written separately but exist so closely often provides a large disconnect between some CSS’ source and where it is implemented. That is to say, we may see classes all throughout our markup, but that is only one very small part of the picture: somewhere else there is the corresponding CSS that completes the other half of the story. Cross-referencing these classes to ensure their proper treatment (reusing them elsewhere in the DOM, binding onto them to make modifications, deleting them to remove styling, etc.) requires a very diligent developer, and consumes a lot of time. How many times have you looked at a piece of HTML only to wonder which classes do what, which classes are related to each other (if at all), which classes are optional, which classes are recyclable, which classes can you delete, and so on? A lot of times, I’m willing to bet. Naming conventions like [BEM](/2013/01/mindbemding-getting-your-head-round-bem-syntax/) do a fantastic job to help communicate the roles and responsibilities of the classes we find in our HTML, and if you’re not yet using BEM then I urge you to stop reading this article right now and to start with that instead—this post will be levelling BEM up a notch. To quickly recap, BEM gives us two very useful suffixes—`__element` and `--modifier`—that we append onto our classes in order to tell us the role of certain bits of UI, for example: /** * The top-level ‘Block’ of a component. */ .modal {} /** * An ‘Element’ that is a part of the larger Block. */ .modal__title {} /** * A ‘Modifier’ of the Block. */ .modal--large {} In our CSS, this naming isn’t all that useful, but when we see it in out HTML we get a much better view of what’s going on:
do not bind onto this). * `js-`: Signify that this piece of the DOM has some behaviour acting upon it, and that JavaScript binds onto it to provide that behaviour. If you’re not a developer working with JavaScript, leave these well alone. * `qa-`: Signify that a QA or Test Engineering team is running an automated UI test which needs to find or bind onto these parts of the DOM. Like the JavaScript namespace, this basically just reserves hooks in the DOM for non-CSS purposes. Even from this short list alone, we can see just how much more information we can communicate to developers simply by placing a character or two at the front of our existing classes. It is probably worth noting at this point that these namespaces do not exist for encapsulation and sandboxing of styles, but for clarity and informative reasons. [Ben Frain](https://twitter.com/benfrain)’s [FUN](http://benfrain.com/fun-css-naming-convention-explained/) convention utilises namespacing as a means of soft encapsulation. ## Object Namespaces: `o-` Format: .o-object-name[
Now, it should be fairly clear here that what you should do is go and find the `.testimonial {}` ruleset in your CSS and add the padding there. However, using DevTools, you find that adding the padding to the `.media {}` ruleset has exactly the outcome you expected. Perfect! Let’s go and add that into the source CSS file. The issue here is that `.media` is an abstraction (it’s actually the poster child of Nicole Sullivan’s OOCSS) which, by definition, is a reusable and non-cosmetic design pattern that can underpin any number of different UI components. Sure, altering the padding of it in this instance gave us the desired results, but it also may have just unintentionally broken 20 other pieces of UI elsewhere. Because objects don’t belong to any one specific component, and can underpin several vastly different components, it is incredibly risky to ever modify one. This is why we should introduce a namespace, to let other developers know that this class forms an abstraction and that any changes here will be reflected in every object sitewide. The object itself does not necessarily have anything to do with the implementation-specific bit of the UI that you are trying to change. By adding a leading `o-` to the classes for our objects, we can tell other developers about their universal nature, and hopefully avoid ever having people binding onto them and breaking things. If you ever see a class that begins with `o-`, alarm bells should ring and you should know to stay well away from it.
* Objects are abstract. * They can be used in any number of places across the project—places you might not have even seen. * Avoid modifying their styles. * Be careful around anything with a leading `o-`. ## Component Namespaces: `c-` Format: .c-component-name[
This is a button;
This is the date picker; etc. Usually when we make changes to a Component’s ruleset, we will immediately see those changes happening every- (and only) where we’d expect. Unlike with Objects, changing the padding on the `.c-modal__content` should not affect anything else in the site other than the content area of our modal. Where Objects are implementation-agnostic, Components are implementation-specific. If we revisit the previous example, and introduce the Object and Components’ namespaces, we’d be left with this:
Now I can tell _purely_ from this HTML that any changes I make to the `.o-media` class may be felt throughout the entire site, but any changes I make to the `.c-testimonial` ruleset will only modify testimonials, and nothing else. * Components are implementation-specific bits of UI. * They are quite safe to modify. * Anything with a leading `c-` is a specific _thing_. ## Utility Namespaces: `u-` Format: .u-utility-name {} Example: .u-clearfix {} You will most likely be familiar with the Utility notation because of [SUIT](https://github.com/suitcss/utils). Utilities are complete [single responsibility](/2012/04/the-single-responsibility-principle-applied-to-css/) rules which have a very specific and targeted task. It is also quite common for these rules’ declarations to carry `!important` so as to guarantee they beat other less specific ones. They do one thing in a very heavy-handed and inelegant way. They are to be used as a last resort when no other CSS hooks are available, or to tackle completely unique circumstances, e.g. using `.u-text-center` to centrally align one piece of text once and once only. They are only one step away from inline styles, so should be used sparingly. Because of their heavy-handed approach, their global reusability, and their exceptional use-case, it is incredibly important that we signal Utilities to other developers. We do not want anyone trying to bind onto these in future selectors. Take the following example, which actually happened on a project I worked on. A number of months into a project, a developer wrote this bit of CSS: .footer .text-center { font-size: 75%; } Here we can see a problem: the `.text-center` class now has two responsibilities when it appears anywhere inside `.footer`. It now has side effects, which are something that Utilities should never, ever have. By using a namespace, we can introduce a simple and unbreakable rule: if it begins with `u-`, never reassign to it. Utilities should be defined once, and never need changing. Another problem that the Utility namespace solves is that it actually lets people know that there is a heavyweight rule being applied to the section of the DOM. It will help explain why certain things might be happening and hard to override. Take this example:
...
Ah, here’s a Utility, that must be what’s causing it.(This is actually a fairly good example of why we should use Utilities sparingly.)
...
Ah, right, the view probably looks the way it currently does because we have a theme invoked.Now, all of the namespaces we’ve looked at so far are mainly of use to us in our markup, but Theme namespaces are helpful in both our HTML and our CSS. Seeing, for example, `.t-light` in our markup tells us that the entire DOM has a current state applied to it, which is important to know whilst debugging. Seeing that class in our CSS also tells us a lot: it helps to sandbox and isolate any chunks of theme-related CSS inside namespaced rulesets: .c-btn { display: inline-block; padding: 1em; background-color: #333; color: #e4e4e4; .t-light & { background-color: #e4e4e4; color: #333; } } Here we can see that our buttons have a light grey text colour on top of a dark grey background, but when we invoke the `.t-light` theme, those colours invert. Here we are encapsulating the style information, which means that finding, debugging, and modifying Theme rules becomes much simpler. * Theme namespaces are very high-level. * They provide a context or scope for many other rules. * It’s useful to signal the current condition of the UI. ## Scope Namespaces: `s-` Format: .s-scope-name {} Example: .s-cms-content {} Scoped contexts in CSS solve a very specific and particular problem: please be entirely certain that you actually have this problem before employing Scopes, because they can be misused and end up leading to actively bad CSS. Oftentimes it can be useful to set up a brand new styling context for a particular section of your UI. A perfect example of this is areas of user-generated content, where some long-form/prose HTML has come from a CMS. The styling of this kind of content usually differs from the more app-like UI around it. You may have a class-heavy UI architecture to provide complex pieces of design like navigations, buttons, modals, etc., and inside all of this you may have a simple blog post which is populated via a CMS where the user writes plain text and cannot add any classes or complexity. For a really terse but effective example of Scoping styles, see [David Bushell](https://twitter.com/dbushell)’s [Scoping Typography CSS](http://dbushell.com/2012/04/18/scoping-typography-css/). You **might** want to style this free-form text differently from the rest of the surrounding UI, so you _might_ employ a scoping context. For example:
...
...
...
this **will** happen if you put that in there); having a type selector as a Key Selector creates very greedy selectors, which can match more of the DOM than you intend; and our specificity gets increased, meaning our Scope will override previously defined styles, and in turn the Scope itself becomes harder to override. There’s a really good example we can grab from the Sass above. When compiled, that code will give us this selector: `.s-cms-content a {}`. This selector is in charge of adding underlines to links, and is also of a higher specificity than a selector like `.c-btn {}`. This means that if we were to put a button inside of this Scope, it would get an underline—this is something we probably don’t want. This simple example outlines the potential for problems when working with Scopes, so tread carefully. Please make triple sure that that you need to employ a Scope before you start writing lots of nested selectors. If you are unsure, it may be best to err on the side of caution and leave Scopes out entirely. Warnings aside, the actual `s-` namespace becomes incredibly useful for signalling to developers that an entire area of the DOM is subject to one big caveat. Anything we see styled in here might have an extra layer of styling applied to it in a pretty opinionated and greedy manner. * Scopes are pretty rare: make triple sure you need them. * They rely entirely on nesting, so make sure people are aware of this. ## Stateful Namespaces: `is-`/`has-` Format: .[is|has]-state {} Example: .is-open {} .has-dropdown {} Stateful namespaces are lovely. They come from [SMACSS](https://smacss.com/book/type-state), and they tell us about short-lived or temporary states of the UI that need styling accordingly. When looking at a piece of interactive UI (e.g. a modal overlay) through developer tools, we’ll probably spend some time toggling things on and off. Being able to see classes like `.is-open` appear and disappear in the DOM is a highly readable and very obvious way of learning about state:
Does `.message--error` appear in the DOM?The problem with these tests looking out for style hooks is that simply refactoring your CSS to use a different name can cause a test to fail, even if the functionality is exactly the same. In a similar vein to our JS hooks, automated UI tests should not be reliant on CSS classes. To do so breaks our separation of concerns. What we need to do is have the QA team bind onto a suite of their own classes that we leave well alone. This means that if we start out with this: …and we refactor those nasty `.message` and `.error` classes, we should be left with something like this: We can make all of the CSS changes we like, as long we we ensure that the QA team’s hook stays in place. * Binding automated UI tests onto style hooks is too inexplicit—don’t do it. * Bind tests onto dedicated test classes. * Ensure that any UI refactoring doesn’t affect the QA team’s hooks. --- ## Handy Side Effects One amazing, incredibly useful, completely accidental, free-of-charge side effect of adding these namespaces comes when we use a text editor with class autocompletion:
* `[class*=" c-"]`: Find all class attributes that contain the string `c-`, e.g.: A more complete example: [class^="o-"], [class*=" o-"] { outline: 5px solid orange; } [class^="c-"], [class*=" c-"] { outline: 5px solid cyan; } [class^="u-"], [class*=" u-"] { outline: 5px solid violet; } [class^="_"], [class*=" _"] { outline: 5px solid red; } What this allows us to do is get a quick visual indication of the rough make-up of a page. Lots of red? Yikes! That means there are a lot of hacks. Lots of violet? That implies you’re using a lot of utilities: could you maybe refactor and tidy them up? It’s not bulletproof or failsafe, but it’s a really handy start in getting a high-level overview of the composition of your UIs. ### Finding Types in Our CSS If we want to find all types of namespace in our CSS files, we simply need to run a Grep, like so: $ git grep "\.t-" This will yield all Theme namespaces (the `\` is simply escaping the `.` so that it matches the `.` string, and not its regex meaning of anything) in our source CSS files. Naturally, swapping out the `t-` for `c-` would return all of our Component namespaces. --- ## Too Much to Type? If you’re not too keen on the idea of typing out `o-` and `c-` for every class—and particularly if you aren’t really interested in the autocomplete benefits we can gain—another format we could employ is `.object`, `.Component`. That is to say, naming any widespread Object classes with no namespace and a lowercase first letter, and naming our Component classes with no namespace and a capitalised first letter. This actually feels almost natural: because components are named, complete pieces of UI, it feels proper to give them title case. Take these examples:
Lowercase is a generic and global abstraction, title case is a named piece of specific UI. This would lose some other features we gained (namely autocompletion, regexing, and highlighting these pieces of UI visually) but will save you some keystrokes. The decision is yours. --- ## Learning the Namespaces Because each namespace tends to be the first letter of the type of class, we should find that learning the namespaces is actually very simple: `c-` means Component, `t-` means Theme, `o-` means Object. However, that isn’t to say we shouldn’t document our namespaces formally somewhere. The beauty of namespaces like these is that they’re completely rule based. There’s no room for interpretation, which means two things: 1. People have no excuse for not following them. 2. They can be presented as a cheat sheet. I would recommend creating a simple cheat sheet of your namespaces, printing it out on A3 paper, and hanging on the wall in front of your engineers. These rules are so straightforward that they can quite easily be distilled down and presented as a simple cheat sheet guide that anyone can follow. For reference, [here’s a particularly useful cheat sheet](http://www.viemu.com/a_vi_vim_graphical_cheat_sheet_tutorial.html) I referred to when I began to [learn Vim](/2014/06/vim-for-people-who-think-things-like-vim-are-weird-and-hard/). --- ## An Example Below is a very contrived and forced example to try and demonstrate the power of meaningful namespacing. Of course, this example suffers two key problems: 1. It is out of the context of an actual big project, so although it demonstrates what the namespaces are, it’s too small an example to _really_ show how powerful namespacing is. 2. You’ll be very new to the namespaces we’re using, so you won’t be able to ‘read’ this HTML as quickly as you will once you’ve memorised things a little better. So, what can we learn from this:
...