I defined the following variables on the global.css
file
@layer base {
:root {
--light-white: rgb(255, 255, 224);
--light-red: rgb(241, 2, 4);
}
}
the following classes on the tailwind.config.ts
file
const config: Config = {
content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
theme: {
extend: {
colors: {
"light-white": "var(--light-white)",
"light-red": "var(--light-red)",
},
borderWidth: {
lg: "50px",
"lg-long": "85px",
},
},
},
plugins: [],
};
and the following variants for a div
component
import { cva } from "class-variance-authority";
const customVariants = cva("size-0", {
variants: {
size: {
lg: `border-t-lg
border-l-lg-long
border-b-lg`,
},
color: {
red: `border-t-white
border-l-light-red
border-b-white`,
},
},
});
import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
<div className={cn(customVariants({ color, size }))} />
When applying the variants to my component, the color
classes override the size
classes
Output:
<div class="size-0 border-t-white border-l-light-red border-b-white"></div>
If I swap the color
and size
definition positions, the size
classes override the color
classes
const customVariants = cva("size-0", {
variants: {
color: {
red: `border-t-white
border-l-light-red
border-b-white`,
},
size: {
lg: `border-t-lg
border-l-lg-long
border-b-lg`,
},
},
});
Output:
<div class="size-0 border-t-lg border-l-lg-long border-b-lg"></div>
It works if I apply the tailwind classes directly to the div
<div className="size-0 border-t-lg border-l-lg-long border-b-lg border-t-white border-l-light-red border-b-white" />
It also works if I remove the custom borderWidth
classes (border-t-lg
, border-l-lg-long
and border-b-lg
) from size
variant
const flagVariants = cva("size-0", {
variants: {
color: {
red: `border-t-white
border-l-light-red
border-b-white`,
},
size: {
lg: `border-t-[50px]
border-l-[85px]
border-b-[50px]`,
},
},
});
Output:
<div class="size-0 border-t-white border-l-light-red border-b-white border-t-[50px] border-l-[85px] border-b-[50px]"></div>
It seems when using class-variance-authority
and custom classes tailwind thinks the border color/width
are the same property, it overrides some clases and does not apply both.
In this code snippet you can see how the component should look like.
*, ::before, ::after {
box-sizing: border-box;
border-width: 0;
border-style: solid;
}
.bg {
background-color: black;
min-height: 200px;
min-width: 200px;
display: grid;
place-items: center;
}
.size-0 {
width: 0px;
height: 0px;
}
.border-t-white {
border-top-color: white;
}
.border-l-light-red {
border-left-color: red;
}
.border-b-white {
border-bottom-color: white;
}
.border-t-lg {
border-top-width: 50px;
}
.border-l-lg-long {
border-left-width: 85px;
}
.border-b-lg {
border-bottom-width: 50px;
}
<div class="bg">
<div class="size-0 border-t-lg border-l-lg-long border-b-lg border-t-white border-l-light-red border-b-white" ></div>
</div>
How can I fix this? Thanks in advance.
You'd need to configure tailwind-merge
to account for your custom Tailwind value keys. You'd use extendTailwindMerge()
instead of twMerge()
, so that you can pass your custom Tailwind theme
keys to the appropriate class groups. This then lets tailwind-merge
know which keys conflict with each other and which do not.
// import { extendTailwindMerge } from 'tailwind-merge';
const customTwMerge = extendTailwindMerge({
extend: {
theme: {
colors: ['light-white', 'light-red'],
borderWidth: ['lg', 'lg-long'],
},
},
});
function cn(...inputs) {
return customTwMerge(clsx(inputs));
}
const customVariants = cva("size-0", {
variants: {
size: {
lg: `border-t-lg
border-l-lg-long
border-b-lg`,
},
color: {
red: `border-t-white
border-l-light-red
border-b-white`,
},
},
});
console.log(cn(customVariants({ color: 'red', size: 'lg' })));
<script>window.exports = {}</script>
<script src="https://unpkg.com/tailwind-merge@2.5.4/dist/bundle-cjs.js"></script>
<script>window.tailwindMerge = window.exports; window.exports = {}</script>
<script src="https://cdn.jsdelivr.net/npm/clsx@2.1.1/dist/clsx.min.js" integrity="sha256-IyETGWkWvmZiU9FWXnbmkk2C5DCbuHfw5EwHxzwy5mU=" crossorigin="anonymous"></script>
<script>
window.require = () => window.clsx;
window.exports = {}
</script>
<script src="https://unpkg.com/class-variance-authority@0.7.0/dist/index.js"></script>