Skip to content

feat: handle backslash in @utility name#19626

Merged
RobinMalfait merged 7 commits intotailwindlabs:mainfrom
rozsazoltan:feat/handle-blackslash-in-utility-name
Feb 17, 2026
Merged

feat: handle backslash in @utility name#19626
RobinMalfait merged 7 commits intotailwindlabs:mainfrom
rozsazoltan:feat/handle-blackslash-in-utility-name

Conversation

@rozsazoltan
Copy link
Contributor

Resolves #19607

Summary

I believe there is no obstacle to simply ignoring backslashes in the name. This way, various validators - which are not aware of Tailwind CSS's specific syntax (which allows the / character to be used directly in utility names) - can still be bypassed using backslashes. For example, instead of @utility push-1/2, one could use @utility push-1\/2, while the end result would be identical.

Test plan

I took a previous utility test as a baseline and extended it with backslashes, and I expect the same result in the output as in the original test case:

@rozsazoltan rozsazoltan requested a review from a team as a code owner January 30, 2026 21:42
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 30, 2026

Walkthrough

This change adds support for escape sequences in @utility names by introducing an unescape operation during utility name parsing. The implementation imports an unescape function and applies it to utility names in the createCssUtility function, allowing names like p\ush-1\/2 to be unescaped to their actual runtime forms. A test case has been added to verify that utilities with escaped characters are properly parsed and their selectors are correctly combined in the compiled CSS output. The CHANGELOG documents this enhancement as improving compatibility with code formatters.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: handle backslash in @utility name' clearly summarizes the main change—adding support for escaped characters (backslashes) in utility names.
Description check ✅ Passed The description explains the solution (ignoring backslashes in names), provides test details with references, and is directly related to the changeset addressing escaped utility names.
Linked Issues check ✅ Passed The PR successfully implements the solution from #19607: unescaped names are now properly handled by stripping backslashes using the unescape function, allowing validators like Biome to work with escaped names while producing identical output.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the objective to handle escaped utility names—importing unescape utility, applying it in createCssUtility, adding a test case, and updating the changelog.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/tailwindcss/src/index.ts`:
- Around line 234-235: The current blanket removal of backslashes (node.params =
node.params.replace(/\\/g, '')) breaks CSS hex/char escapes; replace that line
to call the existing unescape helper (e.g., node.params = unescape(node.params))
so CSS escapes like \61 are decoded correctly while still producing literal
characters for sequences such as \/ and \%; add the unescape import if missing
and ensure you reference the unescape helper when normalizing node.params.

@RobinMalfait RobinMalfait enabled auto-merge (squash) February 17, 2026 21:07
Copy link
Member

@RobinMalfait RobinMalfait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@RobinMalfait RobinMalfait merged commit ed52d3e into tailwindlabs:main Feb 17, 2026
9 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/tailwindcss/src/utilities.ts (1)

5943-5947: Core change is correct — unescape is applied in the right place, before both validation and registration.

One thing worth noting: unescape handles CSS hex unicode escapes (e.g., \2F/, \000041A) in addition to simple character escapes (\//). The existing comment and the PR description only mention the simple case. Both branches still have to pass the downstream isValidStaticUtilityName/isValidFunctionalUtilityName gates, so no new characters are silently let through — but it may be worth extending the comment (or adding a test) to document that CSS hex escapes are also normalized, to avoid future confusion about the scope of this feature.

📝 Suggested comment clarification
- // Allow escaped characters in the name for compatibility with formatters and
- // other parsers, to ensure valid CSS syntax. E.g.: `@utility foo-1\/2`.
- //
- // Note: the actual utility will be `foo-1/2`
+ // Allow CSS escape sequences in the name for compatibility with formatters and
+ // other parsers that require valid CSS syntax. Both simple character escapes
+ // (e.g., `@utility foo-1\/2`) and CSS hex unicode escapes
+ // (e.g., `@utility foo-\2Fbar`) are normalized to their unescaped forms before
+ // validation and registration.
+ //
+ // Note: `@utility foo-1\/2` and `@utility foo-1/2` produce the same utility `foo-1/2`
  let name = unescape(node.params)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/tailwindcss/src/utilities.ts` around lines 5943 - 5947, Update the
comment above the unescape(node.params) call to note that unescape also
normalizes CSS hex unicode escapes (e.g. "\2F" → "/" and "\000041" → "A") in
addition to simple escapes like "\/"; mention that the normalized name is still
validated by isValidStaticUtilityName and isValidFunctionalUtilityName so no new
invalid characters bypass checks, and consider adding a unit test demonstrating
a hex-escaped input (via node.params) is correctly unescaped and validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/tailwindcss/src/utilities.ts`:
- Around line 5943-5947: Update the comment above the unescape(node.params) call
to note that unescape also normalizes CSS hex unicode escapes (e.g. "\2F" → "/"
and "\000041" → "A") in addition to simple escapes like "\/"; mention that the
normalized name is still validated by isValidStaticUtilityName and
isValidFunctionalUtilityName so no new invalid characters bypass checks, and
consider adding a unit test demonstrating a hex-escaped input (via node.params)
is correctly unescaped and validated.

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

Successfully merging this pull request may close these issues.

@utility doesn't allow for escaped utility names

2 participants

Comments