One of the main concerns for Developers evaluating or starting with a utility-first approach to styling is maintainability due to the number and duplication of classes.
For example, with this component, as I duplicate it to add more links, I also duplicate the classes applied to the link - making it harder to maintain:
There are some solutions to this, which you can also see in an example Astro project at https://github.com/opdavies/reducing-utility-class-duplication.
Extracting a variable of class names
The simplest way to remove the duplication is to create a variable that holds the class names which can be reused. For example, Astro allows variables to be created within the frontmatter section and used within the template. Creating variables can be done in other templating engines too.
Instead of extracting a variable, you could also extract a CSS component. With Tailwind, the @apply directive within a stylesheet will create a reusable CSS component:
The link class can be added to any link items, and whilst the approach works, I prefer to use template-based solutions and keep the classes within the HTML markup.
Loops and maps
Templating engines will have a way to loop over a list of items. This can be used to remove the duplication and only have a single list of classes whilst keeping the benefits of keeping them in the HTML code.
This can now be used anywhere within this project and could be combined with the loop approach, passing the appropriate value to the name prop.
Summary
All of these approaches remove duplication, either using features provided by Tailwind CSS or a templating engine, to make the code more maintainable.
I've shown Astro in these examples but the same can be done with PHP, Twig, Blade, Vue, React, etc.
The examples are public on GitHub at https://github.com/opdavies/reducing-utility-class-duplication/tree/main/src/pages.
- Oliver
Was this interesting?
About me
I'm an Acquia-certified Drupal Triple Expert with 17 years of experience, an open-source software maintainer and Drupal core contributor, public speaker, live streamer, and host of the Beyond Blocks podcast.