Skip to content

Parse a custom property at the end of the input without a trailing ; - #20653

Merged
RobinMalfait merged 1 commit into
tailwindlabs:mainfrom
b84330808:fix-css-parser-eof-custom-property
Nov 2, 2026
Merged

RobinMalfait merged 1 commit into
tailwindlabs:mainfrom
b84330808:fix-css-parser-eof-custom-property

Conversation

@b84330808

Copy link
Copy Markdown
Contributor

Summary

When a custom property is the last thing in the CSS input and has no ; or } after it, the CSS parser loses part of it:

  • --foo: bar is parsed as --foo: ba. When the scan reaches the last character, it takes input.slice(start, j), which leaves out the character at j.
  • --foo: bar !important is parsed as the non-important --foo: bar !importan.
  • If the last character is consumed by another branch instead (a closing ), a string, a comment or an escape), the loop ends without filling the buffer and the parser emits an empty : ; declaration. This happens for --foo: var(--bar) or --foo: 'bar', for example.

The existing should parse a custom property with a missing ending ; test only passes because its input ends with a newline and indentation.

This can reach the build output through @import, when a file of custom properties without a trailing newline is imported inside a rule:

/* input.css */
:root {
  @import './vars.css';
}
/* vars.css, no trailing newline */
--brand: red;
--accent: blue

This builds to --accent: blu;. With --accent: var(--brand) it builds to : ;.

This PR drops the input.length - 1 === j check from the loop. When the loop reaches the end of the input without a ; or } ending the custom property, the rest of the input is used as its value. This matches how PostCSS parses the same input:

Input Before After (same as PostCSS)
--foo: bar --foo: ba --foo: bar
--foo: bar !important --foo: bar !importan --foo: bar !important
--foo: var(--x) : ; --foo: var(--x)
--foo: 'bar' : ; --foo: 'bar'
--a: 1; --b: 2 --a: 1; --b: ; --a: 1; --b: 2

Test plan

  • Added a test to css-parser.test.ts for a custom property at the end of the input with a plain value, !important, var(…), a string, a block, a comment, and after another declaration. Like the other tests in that file, it runs with both Unix and Windows line endings.
  • With the fix reverted, the new test fails ("value": "ba" instead of "bar"). With the fix, it passes.
  • pnpm exec vitest run in packages/tailwindcss: 44 files, 5164 tests passed, 1 skipped.
  • pnpm exec vitest run --project @tailwindcss/node (it uses this parser to rewrite url(…)s in imported files): 8 passed.
  • Compared the parsed declarations with postcss.parse for the inputs in the table above. They now match.
  • pnpm exec prettier --check on the changed files passes.

I used Claude Code to write this change.

When a custom property was the last thing in the input and had no `;` or
`}` after it, the parser took `input.slice(start, j)` where `j` was the
index of the last character, so that character was dropped:
`--foo: bar` became `--foo: ba` and `--foo: bar !important` became the
non-important `--foo: bar !importan`.

If the last character was consumed by another branch instead (a closing
`)`, a string, a comment or an escape), the loop ended without ever
filling the buffer and the parser emitted an empty `: ;` declaration,
e.g. for `--foo: var(--bar)`.

This is reachable through `@import`: a file of custom properties that is
imported inside a rule (e.g. `:root { @import './vars.css'; }`) and has
no trailing newline ends up as `--accent: blu;` or `: ;` in the output.

Now, when the scan reaches the end of the input, the rest of the input
is used as the custom property, the same way PostCSS parses it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@b84330808
b84330808 requested a review from a team as a code owner November 2, 2026 04:19
@greptile-apps

greptile-apps Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] This PR appears safe to merge.

Reviews (1) · Last reviewed commit: "Parse a custom property at the end of th..." · Reviewed by Greptile

@coderabbitai

coderabbitai Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e8d1a439-47b1-43d2-9332-a445d73c7b96
Commits

Reviewing files that changed from the base of the PR and between e4543af and 8bdf211.

Files selected for processing: 3
  • .changelog/custom-property-at-end-of-input.md
  • packages/tailwindcss/src/css-parser.test.ts
  • packages/tailwindcss/src/css-parser.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The parser now buffers custom-property text through EOF when no semicolon or unmatched closing brace ends the scan. Tests cover plain, important, function, quoted, brace, and comment values, plus a preceding declaration. A changelog entry records the fix.

Merge Risk: Minimal · up to 8bdf2

Custom-property values retain their final character at EOF. No merge-blocking risk was identified.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary parser fix: handling a custom property at end-of-input without a trailing semicolon.
Description check Passed The description directly explains the parser bug, the fix, affected cases, tests, and validation results. It is fully related to the changeset.
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.
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@RobinMalfait
RobinMalfait enabled auto-merge (squash) November 2, 2026 10:25

@RobinMalfait RobinMalfait left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the PR! Nice find, and thanks for the clear comparison with PostCSS and the tests for each case.

Sent by an AI assistant on behalf of @RobinMalfait.

@RobinMalfait
RobinMalfait merged commit 2570e00 into tailwindlabs:main Nov 2, 2026
12 checks passed
RobinMalfait added a commit that referenced this pull request Nov 2, 2026
When a custom property has an unclosed bracket at the end of the input,
e.g. `--foo: [bar`, the rest of the input is part of the custom property.
After the rebase onto `main`, this commit only adds the test, because
#20653 made the same
parser change.

Before that change, the parser emitted an empty declaration and went
back to the second `-`. With the leftover declaration of the previous
commits, the `-foo: [bar` that is left then became a declaration too.
This test makes sure that the two changes work together.
RobinMalfait added a commit that referenced this pull request Nov 2, 2026
## Summary

This PR keeps a regular declaration that has no `;` at the end of the CSS input, e.g. `color: red` or `--a: 1;\ncolor: red`. Before, the parser only handled a leftover at-rule after the main loop, so it silently dropped the declaration. PostCSS keeps it (`postcss.parse('color: red')` gives a `decl`), and a top-level declaration that ends with `;` is already kept.

The fix parses the leftover `buffer` as a declaration too, and adds it to the current parent, or to the root. A leftover that is not a declaration (e.g. `foo`) is still ignored, as before, so input that parses today does not start to throw. An unclosed block (e.g. `.foo { color: red`) still throws `Missing closing }`.

A leftover with unbalanced parentheses (e.g. `color: rgb(1, 2`) is not kept, because it is incomplete.

A test also covers a custom property with an unclosed bracket at the end of the input, e.g. `--foo: [bar`. #20653 makes the rest of the input part of the custom property. Without it, the leftover `-foo: [bar` would become a declaration with this PR.

A user can only reach the bare declaration case through an `@import` inside a rule, e.g. `:root { @import './partial.css'; }`, where the partial ends with a bare declaration. That is not valid CSS, but `substituteAtImports` inlines it, because it walks the whole AST. Thus the value of this fix is small, and the change stays small.

Related: #20653 (merged) fixed the same problem for custom properties. This PR is rebased on top of it.

## Test plan

- New tests in `packages/tailwindcss/src/css-parser.test.ts` (Unix and Windows line endings) for `color: red`, `color: red\n`, `color: red !important`, `a: 1; b: 2` and `--a: 1;\ncolor: red`. They fail without the fix.
- New tests for `color: rgb(1, 2` (gives `[]`) and for `--foo: [bar` and `color: red; --foo: (bar` (keep the custom property, together with #20653).
- `pnpm exec vitest run` in `packages/tailwindcss`: all tests pass.
- `pnpm changelog check` passes.
@RobinMalfait

Copy link
Copy Markdown
Contributor

Thanks for this fix! While I reviewed it, I found a related bug: a regular (not custom property) declaration at the end of the input without a ; was dropped completely, e.g. color: red or --a: 1; color: red. #20655 fixes that, and it is merged now. It also adds a test for --foo: [bar, which depends on this PR: without it, the leftover -foo: [bar would have become a second declaration.

@RobinMalfait

Copy link
Copy Markdown
Contributor

Thinking about this more, I feel like this is an anti-pattern and people shouldn't do this at all:

/* input.css */
:root {
  @import './vars.css';
}

But it works today, which makes me wonder how many people rely on this... given that @import should be top-level.

dadezzz pushed a commit to dadezzz/events-cash-register that referenced this pull request Nov 6, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@tailwindcss/vite](https://tailwindcss.com) ([source](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite)) | [`4.3.3` → `4.3.4`](https://renovatebot.com/diffs/npm/@tailwindcss%2fvite/4.3.3/4.3.4) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@tailwindcss%2fvite/4.3.4?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@tailwindcss%2fvite/4.3.3/4.3.4?slim=true) |
| [tailwindcss](https://tailwindcss.com) ([source](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)) | [`4.3.3` → `4.3.4`](https://renovatebot.com/diffs/npm/tailwindcss/4.3.3/4.3.4) | ![age](https://developer.mend.io/api/mc/badges/age/npm/tailwindcss/4.3.4?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwindcss/4.3.3/4.3.4?slim=true) |

---

### Release Notes

<details>
<summary>tailwindlabs/tailwindcss (@&#8203;tailwindcss/vite)</summary>

### [`v4.3.4`](https://github.com/tailwindlabs/tailwindcss/blob/HEAD/CHANGELOG.md#434---2026-11-02)

[Compare Source](tailwindlabs/tailwindcss@v4.3.3...v4.3.4)

##### Added

- Add `@tailwindcss/turbopack`, a Turbopack loader for using Tailwind CSS with Next.js ([#&#8203;20367](tailwindlabs/tailwindcss#20367))

##### Fixed

- Ensure watch mode detects changes to symlinked `@source` files whose real paths aren't otherwise scanned ([#&#8203;20356](tailwindlabs/tailwindcss#20356))
- Ensure variants using `@scope` wrap generated utilities instead of nesting inside them ([#&#8203;20369](tailwindlabs/tailwindcss#20369))
- Ensure nested `@scope` rules preserve their scoping semantics when flattened ([#&#8203;20369](tailwindlabs/tailwindcss#20369))
- Preserve declarations directly inside `@scope` by wrapping them in `:where(:scope)` ([#&#8203;20369](tailwindlabs/tailwindcss#20369))
- Ensure generated utilities include a space in empty `var()` fallbacks (e.g. `var(--tw-blur,)` → `var(--tw-blur, )`) ([#&#8203;20373](tailwindlabs/tailwindcss#20373))
- Canonicalization: convert arbitrary breakpoint and container query variants to named equivalents (e.g. `max-[64rem]:flex` → `max-lg:flex`) ([#&#8203;20380](tailwindlabs/tailwindcss#20380))
- Prevent `@tailwindcss/vite` from crashing on every edit under Vite's experimental `bundledDev` mode ([#&#8203;20379](tailwindlabs/tailwindcss#20379))
- Ensure `@tailwindcss/oxide` falls back to WASM on platforms without native bindings ([#&#8203;20383](tailwindlabs/tailwindcss#20383))
- Extract class candidates from Ruby `%w` and `%W` literals using angle brackets or custom delimiters (e.g. `%w<flex>`, `%w|flex|`), including in Slim and Haml templates ([#&#8203;20387](tailwindlabs/tailwindcss#20387))
- Preserve whitespace in `--default(…)` values in functional `@utility` definitions (e.g. `--default(box alphabetic)` no longer becomes `boxalphabetic`) ([#&#8203;20392](tailwindlabs/tailwindcss#20392))
- Ensure automatic source detection respects negation-based `.gitignore` files (e.g. `/*` followed by `!/…` patterns) ([#&#8203;20397](tailwindlabs/tailwindcss#20397))
- Ensure root `theme('…')` namespace lookups in JavaScript plugins and config files return the full namespace object instead of the value of its `DEFAULT` key ([#&#8203;20399](tailwindlabs/tailwindcss#20399))
- Skip ignored directories when generating watch globs instead of walking their contents on every rebuild ([#&#8203;20408](tailwindlabs/tailwindcss#20408))
- Drop invalid UTF-8 candidates during class detection ([#&#8203;20389](tailwindlabs/tailwindcss#20389))
- Prevent `@tailwindcss/vite` from forcing full-page reloads for scanned files that Vite does not handle as modules (e.g. `.php` files) ([#&#8203;20414](tailwindlabs/tailwindcss#20414))
- Canonicalization: don't merge utilities that reference different theme variables set to CSS-wide keywords like `unset` ([#&#8203;20417](tailwindlabs/tailwindcss#20417))
- Don't generate utilities when a modifier is used that would otherwise be silently ignored (e.g. `rounded-sm/[5]`, `shadow-sm/foo`, `stroke-2/50`) ([#&#8203;20419](tailwindlabs/tailwindcss#20419))
- Preserve `and`, `or`, and `not` inside selectors in `supports-[…]` variants (e.g. `supports-[selector(a:not(.foo))]:flex`) ([#&#8203;20420](tailwindlabs/tailwindcss#20420))
- Don't warn about Angular's `::ng-deep` and `:host-context()` when optimizing CSS ([#&#8203;20434](tailwindlabs/tailwindcss#20434))
- Don't generate CSS for candidates containing an empty additional modifier (e.g. `bg-red-500/50/` and `group-hover/foo//bar:flex`) ([#&#8203;20466](tailwindlabs/tailwindcss#20466))
- Ensure `min-*`, `max-*`, and container query variants with decimal values are sorted numerically (e.g. `min-[40.25rem]` before `min-[40.5rem]`) ([#&#8203;20512](tailwindlabs/tailwindcss#20512))
- Ensure CSS comments ending with `\*/` are closed correctly instead of swallowing the CSS that follows (e.g. `/* C:\temp\*/`) ([#&#8203;20508](tailwindlabs/tailwindcss#20508))
- Improve style invalidation performance of `group-*` and `peer-*` variants ([#&#8203;20513](tailwindlabs/tailwindcss#20513))
- Ensure cached compilers release their `loadModule` and `loadStylesheet` callbacks after compilation ([#&#8203;20531](tailwindlabs/tailwindcss#20531))
- Canonicalization: preserve `&` when moving a pseudo-element into `*` or `**` (e.g. `[&_::before]:flex` → `**:[&::before]:flex`) ([#&#8203;20550](tailwindlabs/tailwindcss#20550))
- Ensure the `Set.prototype.intersection` polyfill in `canonicalizeCandidates(…)` returns the intersection instead of the first set on Node.js < 22 ([#&#8203;20562](tailwindlabs/tailwindcss#20562))
- Canonicalization: ensure inline `theme(…)` alphas with more than 2 decimals migrate to a percentage modifier with the same opacity (e.g. `theme(colors.red.500/.12345)` → `text-red-500/[12.345%]`, not `text-red-500/[12.345]`) ([#&#8203;20563](tailwindlabs/tailwindcss#20563))
- Canonicalization: preserve inline `theme(…)` alphas as an arbitrary percentage when a custom `--opacity-*` theme value would change the opacity (e.g. `theme(colors.red.500/50%)` → `text-red-500/[50%]` with `--opacity-50: 10%`) ([#&#8203;20563](tailwindlabs/tailwindcss#20563))
- Ensure the `@property` fallback isn't applied in Safari versions that no longer support `margin-trim: inline` ([#&#8203;20569](tailwindlabs/tailwindcss#20569))
- Treat viewport units like `dvmin` and `svi` and font-relative units like `cap` and `rex` as lengths in arbitrary values (e.g. `text-[10dvmin]` generates `font-size` instead of `color`) ([#&#8203;20516](tailwindlabs/tailwindcss#20516))
- Write plugin logs to stderr in `tailwindcss canonicalize` so they don't end up in the results on stdout ([#&#8203;20561](tailwindlabs/tailwindcss#20561))
- Extract class shorthands on later lines when Pug text, comments, or quoted attribute values contain unbalanced brackets, or a quote that doesn't start a string (e.g. `input(pattern=/"/.source)`) ([#&#8203;20547](tailwindlabs/tailwindcss#20547), [#&#8203;20572](tailwindlabs/tailwindcss#20572))
- Underline the correct occurrence of an unsupported data type in `--value(…)` warnings ([#&#8203;20554](tailwindlabs/tailwindcss#20554))
- Canonicalization: prefer an existing candidate when collapsing utilities over another utility with the same default theme value (e.g. `text-foreground text-primary` → `text-primary`, not `text-card-checked-border`) ([#&#8203;20540](tailwindlabs/tailwindcss#20540))
- Canonicalization: don't collapse utilities into a utility that uses another theme variable with the same default value (e.g. `mt-card mb-card` → `my-card`, not `my-4`) ([#&#8203;20574](tailwindlabs/tailwindcss#20574))
- Ensure `@tailwindcss/postcss` rewrites relative `url(…)`s of stylesheets that are inlined before it runs (e.g. `@import`s in Vite) in optimized builds ([#&#8203;20576](tailwindlabs/tailwindcss#20576))
- Drop nested rules that put a combinator after a pseudo-element when using pseudo-element variants (e.g. `selection:*` on a utility with a nested `& > *` rule) ([#&#8203;20575](tailwindlabs/tailwindcss#20575))
- Don't generate CSS for arbitrary values with unbalanced parentheses or brackets (e.g. `w-[calc(1px]` or `[--x:a[b]`) ([#&#8203;20577](tailwindlabs/tailwindcss#20577))
- Canonicalization: prevent `collapse: true` from taking exponentially longer when classes are linked through a utility that sets many properties (e.g. `sr-only`) ([#&#8203;20558](tailwindlabs/tailwindcss#20558))
- Ensure `&` is substituted inside `:-moz-any(…)` and `:-webkit-any(…)` in custom variants (e.g. `@custom-variant firefox (:-moz-any(&));`) ([#&#8203;20486](tailwindlabs/tailwindcss#20486))
- Ensure the standalone macOS binaries have a valid code signature, so macOS 27 no longer kills them at launch ([#&#8203;20578](tailwindlabs/tailwindcss#20578))
- Ensure `@tailwindcss/turbopack` and `@tailwindcss/webpack` rebuild when the input CSS changes (e.g. `next dev` with Turbopack no longer serves the CSS of the previous edit) ([#&#8203;20582](tailwindlabs/tailwindcss#20582))
- Canonicalization: don't drop a utility that sets a `--tw-*` variable when an unrelated property has the same value (e.g. `link mt-4` no longer becomes `mt-4` when `link` sets `margin-top: 16px` and `--tw-translate-x: 16px`) ([#&#8203;20593](tailwindlabs/tailwindcss#20593))
- Decode single-digit hexadecimal escapes in theme variable and `@utility` names as the CSS spec does (e.g. `@theme { --color-\0: red; }` no longer registers `--color-0`) ([#&#8203;20591](tailwindlabs/tailwindcss#20591))
- Don't treat `!important` inside strings, comments or `url()` in declaration values as the important flag (e.g. `content: "a !important b"`) ([#&#8203;20627](tailwindlabs/tailwindcss#20627))
- Parse a custom property at the end of the input when it has no trailing `;` (e.g. `--foo: bar` as the last declaration) ([#&#8203;20653](tailwindlabs/tailwindcss#20653))
- Keep a declaration without a `;` at the end of the CSS input (e.g. `color: red`) ([#&#8203;20655](tailwindlabs/tailwindcss#20655))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4yMTYuNCIsInVwZGF0ZWRJblZlciI6IjQ0LjIxNi40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
markharding pushed a commit to futo-org/Harbor that referenced this pull request Nov 10, 2026
This PR contains the following updates:

| Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [@tailwindcss/postcss](https://tailwindcss.com) ([source](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-postcss)) | [`4.3.3` → `4.3.5`](https://renovatebot.com/diffs/npm/@tailwindcss%2fpostcss/4.3.3/4.3.5) | ![age](https://developer.mend.io/api/mc/badges/age/npm/@tailwindcss%2fpostcss/4.3.5?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/@tailwindcss%2fpostcss/4.3.3/4.3.5?slim=true) |
| [tailwindcss](https://tailwindcss.com) ([source](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss)) | [`4.3.3` → `4.3.5`](https://renovatebot.com/diffs/npm/tailwindcss/4.3.3/4.3.5) | ![age](https://developer.mend.io/api/mc/badges/age/npm/tailwindcss/4.3.5?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/tailwindcss/4.3.3/4.3.5?slim=true) |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/2097) for more information.

---

### Release Notes

<details>
<summary>tailwindlabs/tailwindcss (@&#8203;tailwindcss/postcss)</summary>

### [`v4.3.5`](https://github.com/tailwindlabs/tailwindcss/blob/HEAD/CHANGELOG.md#435---2026-11-06)

[Compare Source](tailwindlabs/tailwindcss@v4.3.4...v4.3.5)

##### Fixed

- Canonicalization: improve performance in projects with many functional variant values (e.g. a `matchVariant` plugin with thousands of values) ([#&#8203;20663](tailwindlabs/tailwindcss#20663))
- Don't crash or create a fallback with the wrong color for a `color-mix(…)` without a color interpolation method (e.g. `color-mix(var(--color-red-500))` or `color-mix(currentcolor 50%, transparent)`) ([#&#8203;20658](tailwindlabs/tailwindcss#20658), [#&#8203;20666](tailwindlabs/tailwindcss#20666))
- Ensure `@tailwindcss/oxide-wasm32-wasi` loads instead of hanging forever (e.g. with `NAPI_RS_FORCE_WASI=error` or in WebContainers) ([#&#8203;20667](tailwindlabs/tailwindcss#20667))
- Remove `as: '*.css'` from the `@tailwindcss/turbopack` setup in its README, because it breaks CSS modules ([#&#8203;20660](tailwindlabs/tailwindcss#20660))
- Ignore `<!--` and `-->` between top-level rules in CSS instead of throwing or swallowing the next rule (e.g. `a { color: red } --> b { color: blue }`) ([#&#8203;20665](tailwindlabs/tailwindcss#20665))
- Ensure `@tailwindcss/oxide-wasm32-wasi` detects changed and new source files after the first scan (e.g. in WebContainers) ([#&#8203;20487](tailwindlabs/tailwindcss#20487))
- Prevent type errors with `skipLibCheck: false` caused by imports of unshipped modules in the `@tailwindcss/node` type declarations ([#&#8203;20632](tailwindlabs/tailwindcss#20632))

### [`v4.3.4`](https://github.com/tailwindlabs/tailwindcss/blob/HEAD/CHANGELOG.md#434---2026-11-02)

[Compare Source](tailwindlabs/tailwindcss@v4.3.3...v4.3.4)

##### Added

- Add `@tailwindcss/turbopack`, a Turbopack loader for using Tailwind CSS with Next.js ([#&#8203;20367](tailwindlabs/tailwindcss#20367))

##### Fixed

- Ensure watch mode detects changes to symlinked `@source` files whose real paths aren't otherwise scanned ([#&#8203;20356](tailwindlabs/tailwindcss#20356))
- Ensure variants using `@scope` wrap generated utilities instead of nesting inside them ([#&#8203;20369](tailwindlabs/tailwindcss#20369))
- Ensure nested `@scope` rules preserve their scoping semantics when flattened ([#&#8203;20369](tailwindlabs/tailwindcss#20369))
- Preserve declarations directly inside `@scope` by wrapping them in `:where(:scope)` ([#&#8203;20369](tailwindlabs/tailwindcss#20369))
- Ensure generated utilities include a space in empty `var()` fallbacks (e.g. `var(--tw-blur,)` → `var(--tw-blur, )`) ([#&#8203;20373](tailwindlabs/tailwindcss#20373))
- Canonicalization: convert arbitrary breakpoint and container query variants to named equivalents (e.g. `max-[64rem]:flex` → `max-lg:flex`) ([#&#8203;20380](tailwindlabs/tailwindcss#20380))
- Prevent `@tailwindcss/vite` from crashing on every edit under Vite's experimental `bundledDev` mode ([#&#8203;20379](tailwindlabs/tailwindcss#20379))
- Ensure `@tailwindcss/oxide` falls back to WASM on platforms without native bindings (`@tailwindcss/oxide-wasm32-wasi` now installs on all platforms, but only loads when no native binding is available) ([#&#8203;20383](tailwindlabs/tailwindcss#20383))
- Extract class candidates from Ruby `%w` and `%W` literals using angle brackets or custom delimiters (e.g. `%w<flex>`, `%w|flex|`), including in Slim and Haml templates ([#&#8203;20387](tailwindlabs/tailwindcss#20387))
- Preserve whitespace in `--default(…)` values in functional `@utility` definitions (e.g. `--default(box alphabetic)` no longer becomes `boxalphabetic`) ([#&#8203;20392](tailwindlabs/tailwindcss#20392))
- Ensure automatic source detection respects negation-based `.gitignore` files (e.g. `/*` followed by `!/…` patterns) ([#&#8203;20397](tailwindlabs/tailwindcss#20397))
- Ensure root `theme('…')` namespace lookups in JavaScript plugins and config files return the full namespace object instead of the value of its `DEFAULT` key ([#&#8203;20399](tailwindlabs/tailwindcss#20399))
- Skip ignored directories when generating watch globs instead of walking their contents on every rebuild ([#&#8203;20408](tailwindlabs/tailwindcss#20408))
- Drop invalid UTF-8 candidates during class detection ([#&#8203;20389](tailwindlabs/tailwindcss#20389))
- Prevent `@tailwindcss/vite` from forcing full-page reloads for scanned files that Vite does not handle as modules (e.g. `.php` files) ([#&#8203;20414](tailwindlabs/tailwindcss#20414))
- Canonicalization: don't merge utilities that reference different theme variables set to CSS-wide keywords like `unset` ([#&#8203;20417](tailwindlabs/tailwindcss#20417))
- Don't generate utilities when a modifier is used that would otherwise be silently ignored (e.g. `rounded-sm/[5]`, `shadow-sm/foo`, `stroke-2/50`) ([#&#8203;20419](tailwindlabs/tailwindcss#20419))
- Preserve `and`, `or`, and `not` inside selectors in `supports-[…]` variants (e.g. `supports-[selector(a:not(.foo))]:flex`) ([#&#8203;20420](tailwindlabs/tailwindcss#20420))
- Don't warn about Angular's `::ng-deep` and `:host-context()` when optimizing CSS ([#&#8203;20434](tailwindlabs/tailwindcss#20434))
- Don't generate CSS for candidates containing an empty additional modifier (e.g. `bg-red-500/50/` and `group-hover/foo//bar:flex`) ([#&#8203;20466](tailwindlabs/tailwindcss#20466))
- Ensure `min-*`, `max-*`, and container query variants with decimal values are sorted numerically (e.g. `min-[40.25rem]` before `min-[40.5rem]`) ([#&#8203;20512](tailwindlabs/tailwindcss#20512))
- Ensure CSS comments ending with `\*/` are closed correctly instead of swallowing the CSS that follows (e.g. `/* C:\temp\*/`) ([#&#8203;20508](tailwindlabs/tailwindcss#20508))
- Improve style invalidation performance of `group-*` and `peer-*` variants ([#&#8203;20513](tailwindlabs/tailwindcss#20513))
- Ensure cached compilers release their `loadModule` and `loadStylesheet` callbacks after compilation ([#&#8203;20531](tailwindlabs/tailwindcss#20531))
- Canonicalization: preserve `&` when moving a pseudo-element into `*` or `**` (e.g. `[&_::before]:flex` → `**:[&::before]:flex`) ([#&#8203;20550](tailwindlabs/tailwindcss#20550))
- Ensure the `Set.prototype.intersection` polyfill in `canonicalizeCandidates(…)` returns the intersection instead of the first set on Node.js < 22 ([#&#8203;20562](tailwindlabs/tailwindcss#20562))
- Canonicalization: ensure inline `theme(…)` alphas with more than 2 decimals migrate to a percentage modifier with the same opacity (e.g. `theme(colors.red.500/.12345)` → `text-red-500/[12.345%]`, not `text-red-500/[12.345]`) ([#&#8203;20563](tailwindlabs/tailwindcss#20563))
- Canonicalization: preserve inline `theme(…)` alphas as an arbitrary percentage when a custom `--opacity-*` theme value would change the opacity (e.g. `theme(colors.red.500/50%)` → `text-red-500/[50%]` with `--opacity-50: 10%`) ([#&#8203;20563](tailwindlabs/tailwindcss#20563))
- Ensure the `@property` fallback isn't applied in Safari versions that no longer support `margin-trim: inline` ([#&#8203;20569](tailwindlabs/tailwindcss#20569))
- Treat viewport units like `dvmin` and `svi` and font-relative units like `cap` and `rex` as lengths in arbitrary values (e.g. `text-[10dvmin]` generates `font-size` instead of `color`) ([#&#8203;20516](tailwindlabs/tailwindcss#20516))
- Write plugin logs to stderr in `tailwindcss canonicalize` so they don't end up in the results on stdout ([#&#8203;20561](tailwindlabs/tailwindcss#20561))
- Extract class shorthands on later lines when Pug text, comments, or quoted attribute values contain unbalanced brackets, or a quote that doesn't start a string (e.g. `input(pattern=/"/.source)`) ([#&#8203;20547](tailwindlabs/tailwindcss#20547), [#&#8203;20572](tailwindlabs/tailwindcss#20572))
- Underline the correct occurrence of an unsupported data type in `--value(…)` warnings ([#&#8203;20554](tailwindlabs/tailwindcss#20554))
- Canonicalization: prefer an existing candidate when collapsing utilities over another utility with the same default theme value (e.g. `text-foreground text-primary` → `text-primary`, not `text-card-checked-border`) ([#&#8203;20540](tailwindlabs/tailwindcss#20540))
- Canonicalization: don't collapse utilities into a utility that uses another theme variable with the same default value (e.g. `mt-card mb-card` → `my-card`, not `my-4`) ([#&#8203;20574](tailwindlabs/tailwindcss#20574))
- Ensure `@tailwindcss/postcss` rewrites relative `url(…)`s of stylesheets that are inlined before it runs (e.g. `@import`s in Vite) in optimized builds ([#&#8203;20576](tailwindlabs/tailwindcss#20576))
- Drop nested rules that put a combinator after a pseudo-element when using pseudo-element variants (e.g. `selection:*` on a utility with a nested `& > *` rule) ([#&#8203;20575](tailwindlabs/tailwindcss#20575))
- Don't generate CSS for arbitrary values with unbalanced parentheses or brackets (e.g. `w-[calc(1px]` or `[--x:a[b]`) ([#&#8203;20577](tailwindlabs/tailwindcss#20577))
- Canonicalization: prevent `collapse: true` from taking exponentially longer when classes are linked through a utility that sets many properties (e.g. `sr-only`) ([#&#8203;20558](tailwindlabs/tailwindcss#20558))
- Ensure `&` is substituted inside `:-moz-any(…)` and `:-webkit-any(…)` in custom variants (e.g. `@custom-variant firefox (:-moz-any(&));`) ([#&#8203;20486](tailwindlabs/tailwindcss#20486))
- Ensure the standalone macOS binaries have a valid code signature, so macOS 27 no longer kills them at launch ([#&#8203;20578](tailwindlabs/tailwindcss#20578))
- Ensure `@tailwindcss/turbopack` and `@tailwindcss/webpack` rebuild when the input CSS changes (e.g. `next dev` with Turbopack no longer serves the CSS of the previous edit) ([#&#8203;20582](tailwindlabs/tailwindcss#20582))
- Canonicalization: don't drop a utility that sets a `--tw-*` variable when an unrelated property has the same value (e.g. `link mt-4` no longer becomes `mt-4` when `link` sets `margin-top: 16px` and `--tw-translate-x: 16px`) ([#&#8203;20593](tailwindlabs/tailwindcss#20593))
- Decode single-digit hexadecimal escapes in theme variable and `@utility` names as the CSS spec does (e.g. `@theme { --color-\0: red; }` no longer registers `--color-0`) ([#&#8203;20591](tailwindlabs/tailwindcss#20591))
- Don't treat `!important` inside strings, comments or `url()` in declaration values as the important flag (e.g. `content: "a !important b"`) ([#&#8203;20627](tailwindlabs/tailwindcss#20627))
- Parse a custom property at the end of the input when it has no trailing `;` (e.g. `--foo: bar` as the last declaration) ([#&#8203;20653](tailwindlabs/tailwindcss#20653))
- Keep a declaration without a `;` at the end of the CSS input (e.g. `color: red`) ([#&#8203;20655](tailwindlabs/tailwindcss#20655))

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - "before 9am on tuesday"
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4yMDYuMiIsInVwZGF0ZWRJblZlciI6IjQ0LjIwNi4yIiwidGFyZ2V0QnJhbmNoIjoiZGV2ZWxvcCIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiLCJyZW5vdmF0ZSJdfQ==-->

Reviewed-on: https://code.futo.org/harbor/harbor/pulls/2257
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.

2 participants