Avoiding Class Conflicts With tailwind-merge
Understand how Tailwind class specificity works and use tailwind-merge to ensure the last-applied variant wins without specificity bugs.
How Tailwind Class Conflicts Arise
Tailwind utility classes set individual CSS properties. When two classes target the same property — like p-4 and p-8, or text-blue-500 and text-red-500 — both end up in the element's class list. The browser resolves the conflict using CSS cascade order: whichever utility was generated later in Tailwind's stylesheet wins, regardless of the order in your HTML. This makes overriding parent component styles unpredictable without tailwind-merge.
<!-- Both p-4 and p-8 appear in the DOM -->
<div class="p-4 p-8">...</div>
<!-- Which padding is applied? Depends on Tailwind's
stylesheet order, not the class string order. -->
<!-- Same problem with text colors -->
<div class="text-gray-900 text-blue-500">...</div>
<!-- Will the text be gray or blue? You cannot be sure. -->What tailwind-merge Does
tailwind-merge is a runtime utility that analyzes a class string and removes conflicting Tailwind classes, keeping only the last class from each conflicting group. It has an internal map of which Tailwind utilities conflict with each other — understanding that p-4 and p-8 both set padding, or that font-bold and font-medium both set font-weight. The last class in the input string always wins.
import { twMerge } from 'tailwind-merge';
// Conflict resolution: last value wins
twMerge('p-4 p-8')
// Output: 'p-8'
twMerge('text-gray-900 text-blue-500')
// Output: 'text-blue-500'
twMerge('font-bold font-medium text-sm text-lg')
// Output: 'font-medium text-lg'
// Non-conflicting classes are kept
twMerge('flex items-center gap-4 p-4')
// Output: 'flex items-center gap-4 p-4'All lessons in this course
- Setting Up Tailwind in Next.js
- Conditional Classes in React
- Component Variants With CVA
- Avoiding Class Conflicts With tailwind-merge