Naming UI components in OOCSS – CSS Wizardry


Written by on CSS Wizardry.

Table of Contents
  1. Using Sass’ @extend
    1. Featured case study: NHS
  2. data-* attributes

One of the biggest—if not most common—complaints about OOCSS is its use of
‘insemantic classes’. Unfortunately, the idea that classes are semantic (in the
HTML sense of the term) is something of a fallacy; classes aren’t understood by
machines, they’re simply read and/or matched—machines cannot glean any meaning
from something whose content is entirely subjective.

If you are still on the fence about semantic classes, I would recommend
reading Nicolas Gallagher’s excellent article,
About HTML semantics and front-end architecture.
In it, he discusses what we mean when we talk about semantics, and how HTML
semantics differs from developer semantics. The short version is that we
should write classes that are useful for developers; classes that are highly
reusable, that don’t couple themselves to specific types of content, and classes
that describe the styling’s function rather than the content’s function.
Traditionally we would refer to these as insemantic classes, but Nicolas does a
great job of debunking that. Having a solid grasp of (and, ideally, being in
agreement with) his article will really make this one make more sense.

tl;dr Keep using agnostic, abstract, OOCSS classes in your markup, but add
any desired meaning to your HTML via a data-ui-component attribute, e.g.:
.


One of the best things about OOCSS, and ‘insemantic’ classes, is that we have
many design patterns tied to highly reusable names—we have very recyclable CSS
that we can apply over and over again, keeping our codebase small, neat, and
consistent.

One of the cited downsides of OOCSS is that these classes don’t tell you
anything about the content. Nicolas explains why this isn’t that important
(basically classes shouldn’t describe content when content describes
itself
), but when you have a series of objects and abstractions that come
together to form one complex UI component, it is often advantageous to be able
to refer to that component by a unique name.

I firmly believe that classes should not describe content, because it
inhibits their reusability, and that there is no such thing as an insemantic
class, but I don’t see any harm in having the best of both worlds. To this
end, I came up with something of a solution: highly abstracted, reusable
classes, along with a method of giving distinct names to particular UI
components. Let’s take an example…

Imagine we have some abstractions:

  • The media object
    which places some text next to an image.
  • The bare-list object which removes the indents and bullets from a list.
  • The UI-list object which takes the indents and bullets off of a list,
    gives the list items some padding, and places a small border between each list
    item.

We combine these three abstractions to have a UI-list; each list item in the
UI-list contains a media object; each media object contains a picture of a user
and their bio; each bio contains a bare-list of their Twitter and website URLs.
Three individual UI objects which combine to create a list of users and their
bio information:

Take a look on jsFiddle

Of course, the beauty of these classes is that they could be rearranged in any
order or combination to make another complex UI component that is entirely
different. But, when a client wants to duplicate a piece of content, they won’t
ask you to copy the UI-list and media object and bare-list component,
they’ll probably ask you to duplicate the user-list. When you ask a
software engineer to write a loop to populate that list, you’ll probably also
want to refer to it as a user-list to them. What we need is a way of
assigning useful names to these composites for when we have discussions about
them; there is no harm in having meaningful names as long as they don’t impact
our ability to reuse things.

Table of Contents

Using Sass’ @extend

One method, obviously, would be to wrap all these classes up into one unique one
using Sass’ @extend directive, but there are problems with @extend that both
Oliver J Ash
and I have already covered:
chiefly, that @extend is very greedy, and can cause serious bloat if you’re
not careful.

Featured case study: NHS

How I helped the NHS rapidly build a brand new product.

Read case study…

The other downside to wrapping these objects up into a more meaningful class is
that you have to pop open your Sass file(s), think up a brand new name,
potentially create a new partial, and add some more code to replicate
functionality that already existed free of charge. You have to do this every
time you want to reuse that object/abstraction anywhere new. This is just
increasing the amount of CSS you output for no real, tangible gains.

data-* attributes

This desire to give UI components meaningful names is one that has been around
for a long time, and one that I frequently get asked about in workshops, etc. I
recently began to give it a little more thought, and it hit me: data attributes
are the perfect candidate. This, from
MDN:

HTML5 is designed with extensibility for data that should be in the HTML, but
not visible. data-* attributes allow us to store extra information on
standard, semantic HTML elements without polluting the class name.

We can now attach our meaningful names via a data-ui-component attribute, for
example:

Take a look on jsFiddle

When this list gets repurposed as something else, we can keep using the same,
agnostic, decoupled classes but we can also give it a name that describes how
and where that component might get used:

Reusable classes and meaningful names!

Take a look on jsFiddle

Now we can use as many nicely abstracted, agnostic classes as we like, but still
neatly give useful names to complex UI composites:

It’s the best of both worlds: you can still keep your CSS super-lean,
abstracted, recyclable, and reusable, but you can also give specific chunks of
markup meaningful names which can be used in discussions (e.g. referring to the
articles-list rather than any given UI-list).

Another really handy thing that this allows us to do—when in a debugging mode—is
to quickly view any parts of a site that we deem components (the kinds of thing
that you’d have in your pattern library or UI toolkit):

[data-ui-component] {
    outline: 5px solid yellow;
}

This will quickly put an outline around any explicitly named parts of the UI.

It’s important to note that although we can style HTML via its data-*
attributes, we probably shouldn’t. data-* attributes are meant for holding
data in markup, not for selecting on. This, from the HTML Living
Standard
(emphasis mine):

Custom data attributes are intended to store custom data private to the page
or application, for which there are no more appropriate attributes or
elements
.

I’ve been using this on a client project recently, and it’s proved very useful
in encapsulating and discussing UI components, whilst also allowing me to keep
my CSS as abstracted and OO as usual. My client doesn’t need to know—or even
care—that the share with friends component is actually a combination of a
.box, .media, and .btn object, they just need to refer to is at the same
thing everyone else does—the share with friends component!

I would strongly recommend trying it out.




Share this content:

I am a passionate blogger with extensive experience in web design. As a seasoned YouTube SEO expert, I have helped numerous creators optimize their content for maximum visibility.

Leave a Comment