This commit is contained in:
Ben Maurer 2026-09-26 08:50:30 -04:00 • committed by GitHub
commit 80d39dd6ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 62 additions and 2 deletions

View file

@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Add `@tailwindcss/turbopack` package to run Tailwind CSS with Next.js ([20367](https://github.com/tailwindlabs/tailwindcss/pull/20367))
- Add a `colorMixPolyfill` option to `@tailwindcss/postcss` so projects whose browser targets all support `color-mix()` can drop the duplicated `@supports` fallback declarations
### Fixed

View file

@ -88,6 +88,25 @@ export default {
}
```
### Enabling or disabling the `color-mix(…)` polyfill
For browsers without `color-mix()` support (Safari < 16.2), the plugin emits every `color-mix(…)` declaration twice: a plain fallback declaration, plus the original gated behind `@supports (color: color-mix(in lab, red, red))`. This is enabled by default.
If every browser you support has `color-mix()`, you can set `colorMixPolyfill` to `false` to drop the duplicated declarations from the output:
```js
import tailwindcss from '@tailwindcss/postcss'
export default {
plugins: [
tailwindcss({
// Disable the `color-mix(…)` fallbacks
colorMixPolyfill: false,
}),
],
}
```
### Enabling or disabling `url(…)` rewriting
Our PostCSS plugin can rewrite `url(…)`s for you since it also handles `@import` (no `postcss-import` is needed). This feature is enabled by default.

View file

@ -98,6 +98,33 @@ test('output is optimized by Lightning CSS', async () => {
`)
})
test('`color-mix(…)` fallbacks can be disabled', async () => {
let input = css`
@reference 'tailwindcss/theme.css';
.foo {
@apply text-red-500/50;
}
`
// On by default: a `color-mix(…)` declaration is emitted twice — a plain
// fallback, plus the original behind an `@supports` gate.
let withPolyfill = await postcss([
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
]).process(input, { from: inputCssFilePath() })
expect(withPolyfill.css).toContain('@supports (color: color-mix(in lab, red, red))')
// Disabled: the declaration ships once, and nothing else changes.
let withoutPolyfill = await postcss([
tailwindcss({
base: `${__dirname}/fixtures/example-project`,
colorMixPolyfill: false,
optimize: { minify: false },
}),
]).process(input, { from: inputCssFilePath() })
expect(withoutPolyfill.css).toContain('color-mix(')
expect(withoutPolyfill.css).not.toContain('@supports')
})
test('@apply can be used without emitting the theme in the CSS file', async () => {
let processor = postcss([
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),

View file

@ -31,7 +31,7 @@ interface CacheEntry {
const cache = new QuickLRU<string, CacheEntry>({ maxSize: 50 })
function getContextFromCache(postcss: Postcss, inputFile: string, opts: PluginOptions): CacheEntry {
let key = `${inputFile}:${opts.base ?? ''}:${JSON.stringify(opts.optimize)}`
let key = `${inputFile}:${opts.base ?? ''}:${JSON.stringify(opts.optimize)}:${opts.colorMixPolyfill ?? true}`
if (cache.has(key)) return cache.get(key)!
let entry = {
mtimes: new Map<string, number>(),
@ -68,12 +68,23 @@ export type PluginOptions = {
* Defaults to `true`.
*/
transformAssetUrls?: boolean
/**
* Emit `color-mix(…)` fallbacks for browsers without `color-mix()` support
* (Safari < 16.2): a plain fallback declaration, plus a copy of the original
* declaration gated behind `@supports (color: color-mix(in lab, red, red))`.
*
* Defaults to `true`. Set this to `false` when every browser you support has
* `color-mix()`, which removes the duplicated declarations from the output.
*/
colorMixPolyfill?: boolean
}
function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
let base = opts.base ?? process.cwd()
let optimize = opts.optimize ?? process.env.NODE_ENV === 'production'
let shouldRewriteUrls = opts.transformAssetUrls ?? true
let colorMixPolyfill = opts.colorMixPolyfill ?? true
return {
postcssPlugin: '@tailwindcss/postcss',
@ -144,7 +155,9 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
// In CSS Module files, we have to disable the `@property` polyfill since these will
// emit global `*` rules which are considered to be non-pure and will cause builds
// to fail.
polyfills: isCSSModuleFile ? Polyfills.All ^ Polyfills.AtProperty : Polyfills.All,
polyfills:
(isCSSModuleFile ? Polyfills.All ^ Polyfills.AtProperty : Polyfills.All) &
(colorMixPolyfill ? Polyfills.All : ~Polyfills.ColorMix),
})
DEBUG && I.end('Create compiler')