Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSS based functional @utility with same name results in missing classes #16948

Open
RobinMalfait opened this issue Mar 4, 2025 · 7 comments
Open

Comments

@RobinMalfait
Copy link
Member

When defining custom functional @utility with the same name for different purposes results in unwanted behavior.

If you want to use the same name, similar to how we can use text-red-500 and text-2xl then the order matters and only the first one "wins" right now.

@utility foo-* {
  color: --value(--color- *);
}

@utility foo-* {
  font-size: --spacing(--value(number));
}

In this case, foo-red-500 will work, but foo-123 will not.

Play: https://play.tailwindcss.com/1VmWKocy9O?file=css

If you swap the order, then foo-123 will win, but foo-red-500 won't result in anything.

@utility foo-* {
  font-size: --spacing(--value(number));
}

@utility foo-* {
  color: --value(--color- *);
}

Play: https://play.tailwindcss.com/71oBj8xrI1?file=css


The expected behavior is that both work.

@kevster7000
Copy link

kevster7000 commented Mar 6, 2025

Defining both properties in the same utility works

@utility foo-* {
    font-size: --spacing(--value(number));
    color: --value(--color- *);
}

@RobinMalfait
Copy link
Member Author

Yep you are correct! And that's also what we do internally for core plugins, but I think there is still something nice about separating them.

Play with combination: https://play.tailwindcss.com/OUN74Zyn9S?file=css

@CarterStevens1
Copy link

I think im having this issue too but in a similar fashion, when i have a utility class with the same name but with extra letters appended - e.g btn-primary + btn-primaryAlt
The btn-primaryAlt will be get removed when running the minify script

@mtthsnc
Copy link

mtthsnc commented Mar 10, 2025

Adding to this issue to highlight similar issue where generated custom classes override each other if sharing same class prefix with a setup of

:root {
  ...
  --color-base-600: hsl(0, 0%, 42%);
  ...
}

@theme {
  --color-sub-600: var(--color-base-600);
  --text-title-h1: 3.5rem;
  --text-title-h1--line-height: 4rem;
  --text-title-h1--letter-spacing: -0.01em;
  --text-title-h1--font-weight: 600;
}

Ideally, I would want to be able to set both text-title-h1 and text-sub-600 classes on an element i.e. on a radix dialog title element

const DialogTitle = React.forwardRef<
  React.ComponentRef<typeof DialogPrimitive.Title>,
  React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...rest }, forwardedRef) => {
  return (
    <DialogPrimitive.Title
      ref={forwardedRef}
      className={cn("text-title-h1 text-sub-600", className)}
      {...rest}
    />
  );
});
DialogTitle.displayName = "DialogTitle";

However, upon render only text-sub-600 is applied and if I swap the order of classes text-title-h1 is applied. Following theme documentation as outlined here.

To fix the issue I had to utilise @layer utilities and define classes without --text prefix i.e. --text-title-h1 became

@layer utiltiies {
  .title-h1 {
    font-size: var(--text-title-h1);
    line-height: var(--text-title-h1--line-height);
    letter-spacing: var(--text-title-h1--letter-spacing);
    font-weight: var(--text-title-h1--font-weight);
  }
}

On second thought the utilities approach seems more correct, however, the new documentation can be misleading for defining new font sizes and colors especially given that applying custom color and font size will only apply the last defined class on an element.

@yash-k-s-7span
Copy link

yash-k-s-7span commented Mar 18, 2025

@mtthsnc I am not applying the style in Radix dialog but could you check the link https://play.tailwindcss.com/oDMwWmaBEH?file=css

@yash-k-s-7span
Copy link

yash-k-s-7span commented Mar 18, 2025

@RobinMalfait While using utility classes are single-purpose classes that apply specific styles, and you can combine them to create complex designs, allowing you to build responsive and consistent user interfaces efficiently. but you cannot use the same name to define the same utility either combine the styles or use a different name for defining the utility.

@mtthsnc
Copy link

mtthsnc commented Mar 18, 2025

@yash-k-s-7span thank you for providing an example. I eventually backtracked this this to tailwind-merge being the issue as it would remove duplicate prefix classes i.e. if multiple text-* classes were applied it would always favour the last applied class. So this was not an issue with tailwindcss but with tailwind-merge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants