Best Practices for TailwindCSS in React
DRY Class Names for Elements
Prefer to create separate components which have uniform styles throughout the application instead of rewriting the same class names at multiple places or creating a new class name which includes all the tailwind class names using @apply
directive.
Doing so would offer us the flexibility of updating our styles with minimal efforts, as we have to update the class names at a single place only.
Suppose we have a h1
tag which will be used at multiple places. We have two approaches to achieve it:
- Create a component
H1Heading
with TailwindCSS classes applied to it and reuse this component wherever required.
- Create a class in our CSS file which includes all the tailwind class names for the particular element and use the class name wherever required.
Maintain Organized Style Guides using Design Tokens
About
Design tokens are a way to store and manage your design variables, such as colour palette, spacing scale, typography scale, or breakpoints. With design tokens, you can create consistent and reusable styles that are easy to update and maintain.
You can create the design tokens in the tailwind.config.js
file. This is a good way to centralize your design tokens and make them available to all of your Tailwind CSS classes.
Suppose our application follows a particular design system, we can add these guidelines to our tailwind configuration:
Avoid Arbitrary Values
Imagine our web application follows some colour scheme where we have #7743DB
as our theme colour and #0D0D0D
as our background colour.
We can add these colours to our tailwind configuration and refer to them using class names, such as bg-background
text-theme
instead of using arbitrary values at multiple places, i.e. bg-[#0D0D0D]
or text-[#7743DB]
.
Now, if we want to change our application’s color scheme, we just need to update our tailwind configuration instead of renaming the arbitrary class names at multiple places.
Avoid Dynamically Generated Class Names
You all might have encountered this issue while working with dynamic classes that whenever we apply some dynamic class name based on state or some condition, the class name appears in elements panel on the browser, but its corresponding CSS does not.
This is because Tailwind scans your source code for classes using regular expressions to extract every string that could possibly be a class name. Hence, any broken class name string such as border-[${borderColor}]
would not be recognized by tailwind at build time, and it would not be included in the output CSS file of tailwind.
Suppose, we have to change the border color of our element based on the color code passed in props. There are two ways to it:
- Defining a separate class name for each state value. This is only applicable if you know all the expected values of the
borderColor
at build time.
TIP
clsx
is utility package for constructingclassName
strings conditionally.
- If we do not know all the expected value of
borderColor
at build time, it is better to pass the border color in the style attribute of the element to support unknown values.
Create Utility to Read Tailwind Configuration
In web applications, rarely a situation arises where you need to read some CSS design token value in JavaScript, but when it does, we generally hardcode the CSS design token value in our code while working with tailwind. This is not a good practice as in future if you changed your design token value in your tailwind configuration, your code might still refer to the older value which can cause unwanted behavior.
Hence, we can build a custom utility function to read the tailwind configuration in our code:
Defining Tailwind Plugins to Register New CSS Styles
Tailwind provides us with plugins to register new styles to inject into the user’s stylesheet using JavaScript instead of writing custom CSS styling in stylesheets.
I find this approach better, as writing custom CSS classes means you’re essentially rewriting CSS and waving goodbye to Tailwind’s organized workflow and simple maintenance.
Suppose we want to create a .btn
class which has several styles attached to it. This is how we can achieve it:
Tailwind supports registering complex styles as well, along with user provided values. You can go through the tailwind official documentation for plugin (link) to know more about it.