No description
Find a file
Jordan Pittman 5e2a160d8b
Drop exact duplicate declarations from output CSS within a style rule (#18809)
Fixes #18178

When someone writes a utility like `after:content-['foo']` it'll produce
duplicate `content: var(--tw-content)` declarations. I thought about
special casing these but we already have an optimization pass where we
perform a full walk of the AST, flattening some rules (with the `&`
selector), analyzing declarations, etc… We can utilize that existing
spot in core to analyze and remove duplicate declarations within rules
across the AST.

The implementation does this by keeping track of declarations within a
style rule and keeps the last one for any *exact duplicate* which is a
tuple of `(property, value, important)`. This does require some
additional loops but preseving the *last* declaration is important for
correctness with regards to CSS nesting.

For example take this nested CSS:
```css
.foo {
  color: red;
  & .bar {
    color: green;
  }
  color: red;
}
```

It expands to this:
```css
.foo {
  color: red;
}
.foo.bar {
  color: green;
}
.foo {
  color: red;
}
```

If you remove the *last* rule then a `<div class="foo bar">…</div>` will
have green text when its supposed to be red. Since that would affect
behavior we have to always preserve the last declaration for a given
property.

We could go further and eliminate multiple declarations for the same
property *but* this presents a problem: every property and value must be
understood and combined with browser targets to understand whether or
not that property may act as a "fallback" or whether definitely
overwrites its previous value in all cases. This is a much more
complicated task that is much more suited to something light Lighting
CSS.
2025-08-29 11:01:56 -04:00
.github Create FUNDING.yml 2025-07-02 13:22:16 -04:00
crates Prepare v4.1.12 release (#18728) 2025-08-14 14:35:49 +02:00
integrations Migrate supports theme keys (#18817) 2025-08-28 14:50:48 +00:00
packages Drop exact duplicate declarations from output CSS within a style rule (#18809) 2025-08-29 11:01:56 -04:00
patches Upgrade lightningcss to 1.30.1 (#18037) 2025-05-15 13:16:02 +02:00
playgrounds Update eslint 9.32.0 → 9.33.0 (minor) (#18779) 2025-08-22 12:47:01 -04:00
scripts Add experimental @tailwindcss/oxide-wasm32-wasi (#17558) 2025-04-11 17:19:55 +02:00
.gitignore Fix slow unit test (#17465) 2025-03-31 15:26:01 +02:00
.npmrc introduce v4 codebase 2024-03-05 14:29:15 +01:00
.prettierignore Hoist oxide/crates to just crates (#13333) 2024-03-23 09:00:48 -04:00
Cargo.lock Fix HAML extraction with embedded Ruby (#17846) 2025-05-05 10:26:17 -04:00
Cargo.toml Hoist oxide/crates to just crates (#13333) 2024-03-23 09:00:48 -04:00
CHANGELOG.md Drop exact duplicate declarations from output CSS within a style rule (#18809) 2025-08-29 11:01:56 -04:00
LICENSE Add README, LICENSE, and CONTRIBUTING (#13088) 2024-03-05 14:45:39 -05:00
package.json Update @playwright/test 1.54.2 → 1.55.0 (minor) (#18823) 2025-08-29 16:16:39 +02:00
pnpm-lock.yaml Update magic-string 0.30.17 → 0.30.18 (minor) (#18821) 2025-08-29 14:22:19 +00:00
pnpm-workspace.yaml feat: add Vite 7 support to the @tailwindcss/vite plugin (#18384) 2025-06-24 12:31:17 -04:00
README.md Update README.md (#18434) 2025-07-02 16:40:30 -04:00
rust-toolchain.toml Improve Oxide candidate extractor [0] (#16306) 2025-03-05 11:55:24 +01:00
turbo.json Fix segmentation fault when loading @tailwindcss/oxide in a Worker thread (#17276) 2025-03-18 16:28:20 -04:00
vitest.workspace.ts introduce v4 codebase 2024-03-05 14:29:15 +01:00

Tailwind CSS

A utility-first CSS framework for rapidly building custom user interfaces.

Build Status Total Downloads Latest Release License


Documentation

For full documentation, visit tailwindcss.com.

Community

For help, discussion about best practices, or feature ideas:

Discuss Tailwind CSS on GitHub

Contributing

If you're interested in contributing to Tailwind CSS, please read our contributing docs before submitting a pull request.