tailwind-merge icon indicating copy to clipboard operation
tailwind-merge copied to clipboard

Fix arbitrary variables of `font-family` and `font-weight` groups being merged incorrectly

Open dcastil opened this issue 8 months ago • 3 comments

How does one resolve the conflict between font-family and font-weight with arbitrary values?

EX: twMerge('font-(family-name:--custom-family) font-(--custom-weight)') -> returns: font-(--custom-weight) expected: font-(family-name:--custom-family) font-(--custom-weight) twMerge('font-(--custom-weight) font-(family-name:--custom-family)') -> returns font-(family-name:--custom-family) expected: font-(--custom-weight) font-(family-name:--custom-family)

Originally posted by @bguggie in https://github.com/dcastil/tailwind-merge/discussions/584

Just checked and you're right, this is a bug, I'll fix it.

This one is not easy to resolve due to how tailwind-merge works internally and it will take some time for me to find a way to fix it. As a workaround you can use the important modifier on one of the classes to make sure the both stay in the output, e.g. font-(family-name:--custom-family) font-(--custom-weight)!.

https://github.com/dcastil/tailwind-merge/discussions/584#discussioncomment-13398886

dcastil avatar Jun 07 '25 19:06 dcastil

The problem:

  • font-weight group which is defined first is using isArbitraryVariable as a catch-all, preventing any subsequent groups from matching arbitrary variables
  • font-family group which is defined second is using isArbitraryValue as a catch-all, preventing any subsequent groups form matching arbitrary values

No matter which group is defined first, it will prevent the other from matching either arbitrary variables or arbitrary values.

dcastil avatar Jun 07 '25 19:06 dcastil

Possible solution: Add optional priority number property to validator functions which will be used to insert validators in classMap.

https://github.com/dcastil/tailwind-merge/blob/47155f0ebe17188991c8cafc9fe2ae034b18265c/src/lib/class-group-utils.ts#L145-L148

Instead of pushing to the validators array, I search for an index based on the priority and splice the element into it.

dcastil avatar Jun 07 '25 19:06 dcastil

This would be a breaking change for users of tailwind-merge's validators since their execution order might change. I can only do this in a new major version.

dcastil avatar Jun 15 '25 10:06 dcastil