June 2, 2024

Helpful Utility Function Every Tailwind Dev Should Use

  • Frontend Development
  • NextJS
  • React
  • Tailwind
  • Tips & Tricks
  • Tutorial

Tailwind is a framework that has become really popular among front-end developers because of its utility-first approach. You can integrate it into your project using the Tailwind CLI or as a PostCSS plugin. The cn function is a helpful utility that combats conflicting classes and handles conditional classes in your components with ease.

Note: If you install ShadCN/UI, the cn function comes by default.

Why We Need It

When creating your React components, you often have default styles that you need to override later when you use your component. Additionally, when using conditional classes, class conflicts often arise.

1// Default Styled Button
2<StyledButton className="bg-red text-center" ... />
3
4// Later, you want to override the style
5<StyledButton className="bg-green" ... />
6
7// The output now has conflicting classes
8// for the background color
9<StyledButton className="bg-red text-center bg-green" ... />

The Issue with Class Conflicts

In the example above, the StyledButton component has conflicting classes (bg-red and bg-green) for the background color.

How CSS Handles Conflicts

The order of classes in the class attribute doesn't affect which rules are applied. Instead, the rule that appears later in the CSS stylesheet takes precedence.

For instance:

1<!-- Example HTML -->
2<div class="bg-red bg-green">
3  This text will be green.
4</div>
1/* Example CSS */
2.bg-red {
3  background: red;
4}
5
6.bg-green {
7  background: green;
8}

In this example, even though bg-red is listed first in the class attribute, the text will be green because the bg-green rule comes later in the CSS.

It's important to handle class conflicts manually because the order in which Tailwind compiles the CSS is not always easy to predict, especially in large Projects. (How Tailwind handles the CSS compiling is somewhere in the documentation. Send me a message/mail if you know where 🙂). This ensures that your desired styles are applied correctly.

How We Can Fix This

With the cn utility function, we can address this issue. For the cn function, you will need the following NPM packages:

Install the packages with your favorite package manager:

1npm install tailwind-merge clsx

Let's Have a Look at the Function

The cn function is a simple wrapper that utilizes the clsx and twMerge functions. It looks as follows:

1// utils.ts
2
3import { type ClassValue, clsx } from "clsx";
4import { twMerge } from "tailwind-merge";
5
6export function cn(...inputs: ClassValue[]) {
7    return twMerge(clsx(inputs));
8}

How to Use It in Your Component

Now, with the new cn function, we can use it in our generic Button component:

1const StyledButton = ({ children, className }) => {
2  return (
3    <button className={cn("bg-red text-center", className)}>{children}</button>
4  );
5};
6
7// Again, we want to override the default style
8<StyledButton className="bg-green" ... />
9
10// The new output, now we don't have any conflicting
11// classes for the background color :)
12<StyledButton className="text-center bg-green" ... />

I hope this helps in your next project when you use Tailwind.

Cheers, David