Blog Details
MD Rasedul Islam
21 Oct 2024
5 min read
In modern web development, especially when using Tailwind CSS, managing dynamic class names can get tricky. The cn
utility is here to solve that problem! It’s a helper function that simplifies the way you apply CSS classes conditionally and dynamically.
With the cn utility, you can combine class names and merge conflicting classes. This makes your component styles easier to manage—all in one neat package.
Simply put, the cn
function helps you easily handle conditional styling, making your code much cleaner and more readable.
When building React apps or any modern web app, you often need to use different styles based on certain conditions. Without a utility like cn
, your JSX could end up cluttered with long and confusing strings of class names. This not only makes the code harder to maintain but also increases the risk of errors.
cn
Imagine you are creating a button that changes its background color. The color depends on whether the button is primary or disabled. Without cn
, you might end up with something like this:
<button className={`${isPrimary ? 'bg-blue-500' : 'bg-gray-500'} ${isDisabled ? 'opacity-50 cursor-not-allowed' : ''}`}>
Button
</button>
This works, but it’s messy. The logic is all packed into the className
string, making it harder to understand and maintain as your project grows.
cn
With cn
, the same functionality becomes easier to read and maintain:
<button className={cn('px-4 py-2 rounded', isPrimary ? 'bg-blue-500 text-white' : 'bg-gray-500 text-black', isDisabled && 'opacity-50 cursor-not-allowed')}>
Button
</button>
Now the logic is cleaner and separated, making it much easier to follow. The cn function takes care of conditional logic for you. This makes your JSX cleaner and helps you avoid repeating inline logic.
There are several scenarios where the cn
utility is incredibly helpful:
Managing Dynamic Classes: When you need to apply classes based on component props or state, cn is here to help. This is helpful when you want to change styles like background colors, font sizes, or layouts. You can do this based on certain conditions, such as a button being active or disabled.
Handling Tailwind CSS Conflicts: Tailwind CSS encourages the use of utility classes. However, sometimes two classes can conflict, like bg-red-500 and bg-blue-500. The cn function helps fix this by merging Tailwind classes smartly.
Making Code More Readable: Writing complex logic inside className
attributes makes the code less readable. Using cn
allows you to manage this cleanly, separating logic from class names.
Working on Large Projects: When you work on big applications with many parts, using cn helps keep your classes organized. This makes it less likely to have errors.
Using cn
keeps your JSX clean and easy to read. The className
attribute won’t be cluttered with complicated strings and conditional logic. You will spend less time figuring out which classes go with each component. Your teammates, or your future self, will appreciate the clarity.
Here’s a simple example showing how cn
keeps things neat:
Without cn
:
<div className={`${isActive ? 'bg-green-500' : 'bg-red-500'} ${hasError ? 'border-red-500' : ''} ${isDisabled ? 'opacity-50' : ''}`}>
Content
</div>
With cn
:
<div className={cn(
'p-4',
isActive ? 'bg-green-500' : 'bg-red-500',
hasError && 'border-red-500',
isDisabled && 'opacity-50'
)}>
Content
</div>
You can see how much more readable and organized the cn
version is.
Tailwind CSS provides many utility classes that can sometimes conflict. For example, using both bg-red-500 and bg-blue-500 in the same component will apply the last class. This can be confusing and may cause bugs.
Without twMerge
:
<div className="bg-red-500 bg-blue-500">
This will have only one background color (blue), but it's not clear.
</div>
With twMerge
and cn
:
<div className={cn('bg-red-500', 'bg-blue-500')}>
Only the last class will be applied, which is `bg-blue-500`, avoiding the conflict.
</div>
The twMerge
function in cn
ensures that conflicting Tailwind CSS classes are handled properly, leaving only the last one applied.
When building components, you want them to be reusable and flexible. With cn
, you can easily apply different styles based on the props passed to the component, without having to repeat yourself.
For example, let’s say you have a Card
component that can have different styles depending on whether it’s highlighted or not:
const Card = ({ isHighlighted }) => {
return (
<div className={cn('p-4 border rounded', isHighlighted ? 'bg-yellow-100' : 'bg-white')}>
This is a {isHighlighted ? 'Highlighted' : 'Normal'} Card
</div>
);
};
In this example, cn
makes it easy to manage dynamic styles based on the isHighlighted
prop, keeping the code concise and reusable.
The cn
function can handle different types of inputs, such as strings, arrays, or objects. This flexibility makes it adaptable to many scenarios.
"bg-blue-500"
.cn
will join them.For example:
<div className={cn('p-4', { 'bg-blue-500': isPrimary, 'bg-gray-500': !isPrimary })}>
Dynamic Background
</div>
This gives you the flexibility to manage conditional logic in a clean, readable way.
The cn utility is a helpful tool. It makes managing dynamic class names easier, especially in Tailwind CSS projects. It helps you write cleaner, more maintainable code by:
If you use React and Tailwind CSS, adding cn to your tools will improve your code quality. It will also make your development experience better.
Don’t worry, we don’t spam!