Taxonomy for Utility classes

Utility classes are growing in popularity and with so many use cases this seems the right moment to try a categorisation.

For this experiment, we’ll take into consideration some of the most popular utility class frameworks as per August 2024, which are:

What is a utility class anyway?

Strange enough, despite the mole of code available on the internet, I found very little formal definition about of what is or what makes a utility class; even most of the frameworks mentioned above avoid giving a clear-cut definition.

Where do we start to get a definition then?

One possible way would be checking people expectations on utilities and simply asking ourselves, “is that true or is that a myth?”.

So, what are these expectations?

Mainly we have:

  • that each utility is unique and solves a specific problem,
  • that the name of the class states what it does,
  • that during a project utilities are not changed or overridden,
  • that you can combine as many utilities as you need

Then, we have two special things to investigate about utilities.

First, the whole matter of where we use utilities which is pretty much anywhere.

This is quite different from other methodologies like BEM, where a class lives with its own piece of content.

For example, when you style an article, you have classes like article, article_title and article_body.

These classes, similar to utilities, may be problem specific or immutable but you’d be using them exclusively when you have an article, nowhere else. In a way, these classes lives and dies with the content they are attached with.

Instead, with a utility like px-3 you don’t really know where it’s going to be used; it could be in an article, in a footer or in a carousel.

Utilities are special in this regard because the class is written from the beginning with the idea of being reused and recycled.
There is no content attachment.

Second, the matter of utilities names which tend to state what the class does.

While many believe utility names are derived only from CSS properties, this is an incomplete picture.

In fact, there are many cases in which they get named after things like layouts, a11y or ergonomics; some examples are the ratio and container classes, which are used to enforce a whole layout, or again, the sr-only class used to have screen reader text to enhance a11y, or even the stretched-link class which is used to extend the clickable space of an element and improve ergonomics.

Utility classes are purpose-specific, immutable, composable and content-agnostic classes where their names state their purpose.

In summary, the properties we can expect from the utility classes are:

  • composable
    the class is designed to be combined and re-used with multiple other utility classes

  • purpose-specific
    the class solve a specific problem

  • immutable
    the class is defined once and once only, never override

  • content-agnostic
    the class can be used on any type of content

  • self-descriptive
    the class name states the functionality you can expect applying the class

Categories

Now that we know what to expect from a utility, we can look into the categories.

For this excercise we’ll use the browser as reference with at one end the primitive elements which are CSS and HTML, while on the other end we’ll have the complete website with brand, colors and layouts.

CSS Properties Category

Let’s start from the most intuitive and popular utility classes category, that is the CSS Properties Category.

These are the utility classes meant to control a specific aspect of CSS.

To be clear, this is in relation to all the CSS capabilities available in the browser, not only a specific CSS property.

As such, in the anatomy of the class name of these utilities you may find a CSS property name or a property values, or a pseudo class (:hover, :active), or a pseudo elements (::after, ::before), combinators (+, >), a media-queries, an attributes and so on.

// CSS Properties Category Examples

.mb-1px            
[property name]-[property value]

.top-xl-1rem       
[property name]-[media-query]-[property value]

.hover:fill-sm-red 
[pseudo class]:[property name]-[media-query]-[property value]

HTML Tags Category

Let’s explore now what I believe to be the most controversial category, that is the HTML Tags Category.

The utilities that belong to this category are the ones meant to enforce a visual aspect of a HTML tag.

The simplest example is when you want to make an h3 look like an h2 or when you have a link and you want it like a button.

Because the controversy let’s check the definition against this category.

Assuming a hypothetical h1 class, is this class storing a specific solution of a problem? Yes, it does. It makes appear an element as an h1. And does it change? No, it doesn’t. And does it combine well with other utilities? Yes, it does, in fact, you can have an h1 py-3 text-secondary. And is it content-agnostic? Yes, it is, because you can use an h1 class on a h3 or a div.

If this is not controversial enough, i’ll add that as part of the HTML elements within a browser we have form elements as well, like button and input, and they too deserve to have their own utility classes within this category.

I know what you may think, “aren’t forms proper components, similar to an accordion or a menu?”. While it would be tempting to answer yes to this question, I make you notice that there’s no such a thing as an <accoridion> tag out of the box within the browser but instead, forms are in by default and the browsers style them.

But what about the content-agnostic rule? You can have cases in which you’re creating a visual form item out of a div or a link and you want these items to look like an input or a button.

As such, these classes comply with the content-agnostic rule as well.

If we follow this line of thought then classes like btn, form-control, input-select are all fair utilities.

// HTML Tags Category Examples

.h1            
[header h1]

.list-unstyled
[ul or ol]

.btn
[button]

.form-control
[input]

Extra on forms

Why are forms special and deserve their utilities? Why are they different from a component eg. accordion or a carousel?

  1. HTML has specific tag and behaviours included
  2. Browser supports and styles them already
  3. Adhere to composability
  4. Adhere to purpose-specific
  5. Adhere to immutability
  6. Adhere to content-agnostic
  7. Adhere to self-descriptive

Domain Specific Category

The last utility category we’ll examine is the Domain Specific Category.

The classes that belong to this category are the ones specialized to control a domain.

What is a domain you may ask?

The domains are all the context you may face when you’re building your UI, some examples are: animations, a11y, icons, text management, content, layouts and theming.

So, if we take animations as an example, what does it mean that is a domain?

It means that there is a set of utilities meant to control exclusively some aspects of animations like type and timing. An example is the animate.css project, which is exactly a set of utilities specialized in animations.

Now, the reason behind the blur word domain (as per DDD) is because these classes arise from specific challenges in business needs.

For example, if you need some sort of multi-theming for your project then you’re totally fine having your specialized set of utilities to tune some aspect of the themes.

// Domain Specific Category Examples

[animations]
.fade
.animate__animated.animate__bounce.animate__delay-2s            

[a11y]
.sr-only

[text management]
.text-ellipsis  
.truncate
.line-clamp-3 

[icons]
.icon.icon-pencil

[layouts]
.stretched-link
.row.col-12
.ratio.ratio-1x2
.hstack.gap-3 
.vstack.gap-3

[theming]
.theme-red .text-primary
.theme-blue .bg-secondary

Conclusion

We investigated the definition of utility class stating its own properties which are: composable, purpose-specific, immutable, content-agnostic and self-descriptive.

Then, we listed the three main utility categories which are the CSS Properties Category, the HTML Tags Category and the Domain Specific Category.

While the definition and the categories are still primitive, they should be enough to kick new cases exploration, unlock new sets of utilities and shift the focus from the Properties Category to the others which at the moment are the underdogs.

Also, It would be nice to see tooling expand to cover all the categories, not only the CSS one.

If you liked this article you may be interested in The 3 Types of CSS Utility Classes and CSS Utility classes: from blasphemy to hype.

Comments