tailwind1-12 Exercise 1: Class Order, clsx and tailwind-merge =============================================================== setup: npm i clsx tailwind-merge (tested: clsx 2.1.1, tailwind-merge 3.7.0, for Tailwind v4) helper.mjs: import { clsx } from 'clsx'; import { twMerge } from 'tailwind-merge'; export const cn = (...inputs) => twMerge(clsx(inputs)); (1) Class order does not decide the winner. page.html compiled with Tailwind v4:
padding-top: #o1 32px #o2 32px background-color: #o3 oklch(0.637 0.237 25.331) #o4 oklch(0.637 0.237 25.331) (red-500 both times) (2) The five conflict examples: twMerge('px-2 py-1 p-3') "p-3" twMerge('bg-red-500 bg-blue-500') "bg-blue-500" twMerge('p-3 px-2') "p-3 px-2" twMerge('text-sm text-red-500 text-lg') "text-red-500 text-lg" twMerge('hover:bg-red-500 hover:bg-blue-500 bg-green-500') "hover:bg-blue-500 bg-green-500" (3) px-4 px-8: before merging, both classes reach the page and the stylesheet order decides, not their order in the attribute twMerge('px-4 px-8') -> "px-8" (run: the earlier conflicting class is removed) WHY THIS WORKS AS AN ANSWER --------------------------- The browser applies the rule that appears later in the generated stylesheet, and the position of a class in the class attribute is irrelevant: p-2 p-8 and p-8 p-2 both gave 32px, and the two bg orders both gave red-500. Relying on order is therefore unreliable when a component accepts classes from outside, so tailwind-merge resolves the conflict before it reaches the page, keeping the last of any group of classes that set the same property (p-3 replaces px-2 and py-1 that came before it, whereas a later px-2 does not remove an earlier p-3 because it is only part of it, so both stay). clsx only handles the conditional joining, and cn() combines the two.