Skip to content

Canonicalization: limit arbitrary to bare values conversion#20130

Merged
RobinMalfait merged 4 commits into
mainfrom
fix/limit-bare-value-canonicalizations
May 29, 2026
Merged

Canonicalization: limit arbitrary to bare values conversion#20130
RobinMalfait merged 4 commits into
mainfrom
fix/limit-bare-value-canonicalizations

Conversation

@RobinMalfait
Copy link
Copy Markdown
Member

This PR improves the canonicalization process by limiting the bare values to a certain amount.

Before this PR, whenever we have an arbitrary value, e.g. left-[6px], then we prefer to use a bare value instead e.g. left-1.5. In most cases, this makes sense.

However, there are places where this doesn't really make sense (https://x.com/kettanaito/status/2059987396050268589)

  • left-[99999px]left-24999.75

The hard part is to figure out why this feels wrong. The .75 could feel wrong, but in the left-[6px]left-1.5, the .5 makes sense.
If we reduce that big number to left-[99996px]left-24999, then there is no floating point but it still feels wrong.

One possibility I can think of is to analyze the incoming value and see if we find certain patterns. All repeating numbers, fun numbers like 1337, common numbers most programmers know such as 720px, 1280px, etc.

But instead of that, I think it's more reasonable to limit the bare value such that the px based value doesn't exceed a big number. We can improve the logic if there are other cases that don't really make sense.

The biggest value we have in our default theme is --breakpoint-2xl: 96rem, which is equivalent to 1536px.

So I think any bare value that results in a value <= 1536px should probably be fine.

In this case, left-[99999px] would stay as left-[99999px], but left-[6px] is still converted to left-1.5.

Note: this is only happening for arbitrary values being converted to bare values if they use the --spacing variable internally.

Values such as z-[99999999999] will still be converted to z-99999999999, since the intent is still clear.

Test plan

  1. Added new tests for these limitations
  2. Other existing tests still pass

@RobinMalfait RobinMalfait requested a review from a team as a code owner May 29, 2026 16:16
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 444a95eb-8255-4933-bc84-b0c8a4013409

📥 Commits

Reviewing files that changed from the base of the PR and between 9869e0a and 6696fa5.

📒 Files selected for processing (1)
  • CHANGELOG.md

Walkthrough

This change adds MAX_BARE_VALUE_IN_PX (1536) and an isReasonableBareValue helper that resolves spacing multipliers (including rem folding) and rejects conversions whose computed pixel/rem magnitude exceeds the limit. The guard is applied to both spacing-derived bare-value replacement paths. Tests were added to ensure large arbitrary values like left-[5000px], left-[-5000px], calc(...) variants, and z-[9999999] remain as arbitrary candidates rather than being converted.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly describes the main change: limiting arbitrary-to-bare-values conversion in canonicalization, which matches the core purpose of the PR.
Description check ✅ Passed The description is well-related to the changeset, explaining the motivation (preventing unintuitive conversions of very large arbitrary values), the implementation approach (limiting based on 1536px threshold from default theme), and the testing approach.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


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

Copy link
Copy Markdown
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/canonicalize-candidates.ts (1)

1100-1101: ⚡ Quick win

Use absolute pixel magnitude in the reasonableness check.

The guard is intended to cap magnitude, but current comparison uses signed pixels. Using Math.abs(...) makes the helper semantics match the intent and prevents edge-case regressions if a negative multiplier reaches this helper.

Suggested patch
-  let bareValueInPixels = value * spacingValue
-  return bareValueInPixels <= MAX_BARE_VALUE_IN_PX
+  let bareValueInPixels = Math.abs(value * spacingValue)
+  return bareValueInPixels <= MAX_BARE_VALUE_IN_PX
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/tailwindcss/src/canonicalize-candidates.ts` around lines 1100 -
1101, The magnitude check currently compares signed bareValueInPixels which
allows negative values to bypass the cap; update the guard in
canonicalize-candidates.ts (the computation using bareValueInPixels = value *
spacingValue and the return that compares against MAX_BARE_VALUE_IN_PX) to use
the absolute pixel magnitude (e.g., compare Math.abs(bareValueInPixels) <=
MAX_BARE_VALUE_IN_PX) so negative multipliers are correctly clamped.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/tailwindcss/src/canonicalize-candidates.ts`:
- Around line 1100-1101: The magnitude check currently compares signed
bareValueInPixels which allows negative values to bypass the cap; update the
guard in canonicalize-candidates.ts (the computation using bareValueInPixels =
value * spacingValue and the return that compares against MAX_BARE_VALUE_IN_PX)
to use the absolute pixel magnitude (e.g., compare Math.abs(bareValueInPixels)
<= MAX_BARE_VALUE_IN_PX) so negative multipliers are correctly clamped.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 99ca0375-e99b-45c6-8e6e-36e0a842e067

📥 Commits

Reviewing files that changed from the base of the PR and between d4f24c5 and 9f1be71.

📒 Files selected for processing (2)
  • packages/tailwindcss/src/canonicalize-candidates.test.ts
  • packages/tailwindcss/src/canonicalize-candidates.ts

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 29, 2026

Confidence Score: 5/5

Safe to merge — the change narrows an existing conversion path without affecting any other canonicalization logic.

The new isReasonableBareValue guard is logically correct for both the 'px' and 'rem' spacing-unit branches, boundary tests confirm at-limit and over-limit behaviour, and non-spacing utilities (e.g. z-index) are explicitly verified to be unaffected. No regressions are expected.

No files require special attention.

Reviews (3): Last reviewed commit: "update changelog" | Re-trigger Greptile

Comment thread packages/tailwindcss/src/canonicalize-candidates.ts Outdated
@RobinMalfait RobinMalfait merged commit 6b43b64 into main May 29, 2026
7 checks passed
@RobinMalfait RobinMalfait deleted the fix/limit-bare-value-canonicalizations branch May 29, 2026 19:31
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.

1 participant