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
?
- HTML has specific tag and behaviours included
- Browser supports and styles them already
- Adhere to composability
- Adhere to purpose-specific
- Adhere to immutability
- Adhere to content-agnostic
- 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.
Links
- Let’s Define Exactly What Atomic CSS is
- Atomizer classes
- CSS utility classes: Your library of extendable styles
- The 3 Types of CSS Utility Classes
- immutable-css-cli
- animate.css