Optimize generated CSS output (#14873)

This PR improves the generated CSS by running it through Lightning CSS
twice.Right now Lightning CSS merges adjacent at-rules and at the end
flattens the nesting. This means that after the nesting is flattened,
the at-rules that are adjacent and could be merged together will not be
merged.

This PR improves our output by running Lightning CSS twice on the
generated CSS which will make sure to merge adjacent at-rules after the
nesting is flattened.

Note: in the diff output you'll notice that some properties are
duplicated. These need some fixes in Lightning CSS itself but they don't
break anything for us right now.

Related PR in Lightning CSS for the double `-webkit-backdrop-filter` can
be found here: https://github.com/parcel-bundler/lightningcss/pull/850

---------

Co-authored-by: Philipp Spiess <hello@philippspiess.com>
This commit is contained in:
Robin Malfait 2024-11-06 12:39:09 +01:00 committed by GitHub
parent d099f8bda6
commit c5b6df2a27
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 224 additions and 1365 deletions

View File

@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ensure instances of the same variant with different values are always sorted deterministically (e.g. `data-focus:flex` and `data-active:flex`) ([#14835](https://github.com/tailwindlabs/tailwindcss/pull/14835))
- Ensure `--inset-ring=*` and `--inset-shadow-*` variables are ignored by `inset-*` utilities ([#14855](https://github.com/tailwindlabs/tailwindcss/pull/14855))
- Ensure `url(…)` containing special characters such as `;` or `{}` end up in one declaration ([#14879](https://github.com/tailwindlabs/tailwindcss/pull/14879))
- Ensure adjacent rules are merged together after handling nesting when generating optimized CSS ([#14873](https://github.com/tailwindlabs/tailwindcss/pull/14873))
- _Upgrade (experimental)_: Install `@tailwindcss/postcss` next to `tailwindcss` ([#14830](https://github.com/tailwindlabs/tailwindcss/pull/14830))
- _Upgrade (experimental)_: Remove whitespace around `,` separator when print arbitrary values ([#14838](https://github.com/tailwindlabs/tailwindcss/pull/14838))

View File

@ -410,22 +410,28 @@ function optimizeCss(
input: string,
{ file = 'input.css', minify = false }: { file?: string; minify?: boolean } = {},
) {
return transform({
filename: file,
code: Buffer.from(input),
minify,
sourceMap: false,
drafts: {
customMedia: true,
},
nonStandard: {
deepSelectorCombinator: true,
},
include: Features.Nesting,
exclude: Features.LogicalProperties,
targets: {
safari: (16 << 16) | (4 << 8),
},
errorRecovery: true,
}).code.toString()
function optimize(code: Buffer | Uint8Array) {
return transform({
filename: file,
code,
minify,
sourceMap: false,
drafts: {
customMedia: true,
},
nonStandard: {
deepSelectorCombinator: true,
},
include: Features.Nesting,
exclude: Features.LogicalProperties,
targets: {
safari: (16 << 16) | (4 << 8),
},
errorRecovery: true,
}).code
}
// Running Lightning CSS twice to ensure that adjacent rules are merged after
// nesting is applied. This creates a more optimized output.
return optimize(optimize(Buffer.from(input))).toString()
}

View File

@ -421,6 +421,7 @@ exports[`\`@import 'tailwindcss'\` is replaced with the generated CSS 1`] = `
color: inherit;
-webkit-text-decoration: inherit;
-webkit-text-decoration: inherit;
-webkit-text-decoration: inherit;
text-decoration: inherit;
}

View File

@ -218,24 +218,30 @@ function optimizeCss(
input: string,
{ file = 'input.css', minify = false }: { file?: string; minify?: boolean } = {},
) {
return transform({
filename: file,
code: Buffer.from(input),
minify,
sourceMap: false,
drafts: {
customMedia: true,
},
nonStandard: {
deepSelectorCombinator: true,
},
include: Features.Nesting,
exclude: Features.LogicalProperties,
targets: {
safari: (16 << 16) | (4 << 8),
},
errorRecovery: true,
}).code.toString()
function optimize(code: Buffer | Uint8Array) {
return transform({
filename: file,
code,
minify,
sourceMap: false,
drafts: {
customMedia: true,
},
nonStandard: {
deepSelectorCombinator: true,
},
include: Features.Nesting,
exclude: Features.LogicalProperties,
targets: {
safari: (16 << 16) | (4 << 8),
},
errorRecovery: true,
}).code
}
// Running Lightning CSS twice to ensure that adjacent rules are merged after
// nesting is applied. This creates a more optimized output.
return optimize(optimize(Buffer.from(input))).toString()
}
export default Object.assign(tailwindcss, { postcss: true }) as PluginCreator<PluginOptions>

View File

@ -277,24 +277,30 @@ function optimizeCss(
input: string,
{ file = 'input.css', minify = false }: { file?: string; minify?: boolean } = {},
) {
return transform({
filename: file,
code: Buffer.from(input),
minify,
sourceMap: false,
drafts: {
customMedia: true,
},
nonStandard: {
deepSelectorCombinator: true,
},
include: Features.Nesting,
exclude: Features.LogicalProperties,
targets: {
safari: (16 << 16) | (4 << 8),
},
errorRecovery: true,
}).code.toString()
function optimize(code: Buffer | Uint8Array) {
return transform({
filename: file,
code,
minify,
sourceMap: false,
drafts: {
customMedia: true,
},
nonStandard: {
deepSelectorCombinator: true,
},
include: Features.Nesting,
exclude: Features.LogicalProperties,
targets: {
safari: (16 << 16) | (4 << 8),
},
errorRecovery: true,
}).code
}
// Running Lightning CSS twice to ensure that adjacent rules are merged after
// nesting is applied. This creates a more optimized output.
return optimize(optimize(Buffer.from(input))).toString()
}
function idToPath(id: string) {

View File

@ -1592,11 +1592,7 @@ describe('addVariant', () => {
.potato\\:flex:large-potato {
display: flex;
}
}
}
@media (width <= 400px) {
@supports (font: bold) {
.potato\\:underline:large-potato {
text-decoration-line: underline;
}
@ -1840,19 +1836,7 @@ describe('matchVariant', () => {
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
"@layer utilities {
.alphabet-d\\:underline[data-order="1"] {
text-decoration-line: underline;
}
.alphabet-a\\:underline[data-order="2"] {
text-decoration-line: underline;
}
.alphabet-c\\:underline[data-order="3"] {
text-decoration-line: underline;
}
.alphabet-b\\:underline[data-order="4"] {
.alphabet-d\\:underline[data-order="1"], .alphabet-a\\:underline[data-order="2"], .alphabet-c\\:underline[data-order="3"], .alphabet-b\\:underline[data-order="4"] {
text-decoration-line: underline;
}
}"
@ -2059,9 +2043,7 @@ describe('matchVariant', () => {
order: 3;
}
}
}
@media (width >= 100px) {
@media (width <= 300px) {
.testmin-\\[100px\\]\\:testmax-\\[300px\\]\\:order-4 {
order: 4;
@ -2116,11 +2098,7 @@ describe('matchVariant', () => {
text-decoration-line: underline;
}
}
}
}
@media (width >= 100px) {
@media (width <= 200px) {
.testmin-\\[100px\\]\\:testmax-\\[200px\\]\\:focus\\:underline:focus {
text-decoration-line: underline;
}
@ -2245,9 +2223,7 @@ describe('matchVariant', () => {
text-decoration-line: underline;
}
}
}
@media (width <= 400px) {
@media (width >= 200px) {
.testmax-\\[400px\\]\\:testmin-\\[200px\\]\\:underline {
text-decoration-line: underline;
@ -2261,9 +2237,7 @@ describe('matchVariant', () => {
text-decoration-line: underline;
}
}
}
@media (width <= 300px) {
@media (width >= 200px) {
.testmax-\\[300px\\]\\:testmin-\\[200px\\]\\:underline {
text-decoration-line: underline;
@ -2870,11 +2844,7 @@ describe('addUtilities()', () => {
expect(optimizeCss(compiled.build(['form-input', 'lg:form-textarea'])).trim())
.toMatchInlineSnapshot(`
".form-input {
background-color: red;
}
.form-input::placeholder {
".form-input, .form-input::placeholder {
background-color: red;
}
@ -3610,9 +3580,7 @@ describe('matchUtilities()', () => {
--foo: 12px;
display: flex;
}
}
@media (width >= 1024px) {
.lg\\:foo-bar {
--foo: bar;
display: flex;

View File

@ -511,9 +511,7 @@ describe('variant stacking', () => {
.before\\:hover\\:flex:before:hover {
display: flex;
}
}
@media (hover: hover) {
.hover\\:before\\:flex:hover:before {
content: var(--tw-content);
display: flex;
@ -914,32 +912,14 @@ describe('sorting', () => {
.peer-hover\\:flex:is(:where(.peer):hover ~ *) {
display: flex;
}
}
@media (hover: hover) {
@media (hover: hover) {
.group-hover\\:peer-hover\\:flex:is(:where(.group):hover *):is(:where(.peer):hover ~ *) {
.group-hover\\:peer-hover\\:flex:is(:where(.group):hover *):is(:where(.peer):hover ~ *), .peer-hover\\:group-hover\\:flex:is(:where(.peer):hover ~ *):is(:where(.group):hover *) {
display: flex;
}
}
}
@media (hover: hover) {
@media (hover: hover) {
.peer-hover\\:group-hover\\:flex:is(:where(.peer):hover ~ *):is(:where(.group):hover *) {
display: flex;
}
}
}
@media (hover: hover) {
.group-focus\\:peer-hover\\:flex:is(:where(.group):focus *):is(:where(.peer):hover ~ *) {
display: flex;
}
}
@media (hover: hover) {
.peer-hover\\:group-focus\\:flex:is(:where(.peer):hover ~ *):is(:where(.group):focus *) {
.group-focus\\:peer-hover\\:flex:is(:where(.group):focus *):is(:where(.peer):hover ~ *), .peer-hover\\:group-focus\\:flex:is(:where(.peer):hover ~ *):is(:where(.group):focus *) {
display: flex;
}
}
@ -949,22 +929,12 @@ describe('sorting', () => {
}
@media (hover: hover) {
.group-hover\\:peer-focus\\:flex:is(:where(.group):hover *):is(:where(.peer):focus ~ *) {
.group-hover\\:peer-focus\\:flex:is(:where(.group):hover *):is(:where(.peer):focus ~ *), .peer-focus\\:group-hover\\:flex:is(:where(.peer):focus ~ *):is(:where(.group):hover *) {
display: flex;
}
}
@media (hover: hover) {
.peer-focus\\:group-hover\\:flex:is(:where(.peer):focus ~ *):is(:where(.group):hover *) {
display: flex;
}
}
.group-focus\\:peer-focus\\:flex:is(:where(.group):focus *):is(:where(.peer):focus ~ *) {
display: flex;
}
.peer-focus\\:group-focus\\:flex:is(:where(.peer):focus ~ *):is(:where(.group):focus *) {
.group-focus\\:peer-focus\\:flex:is(:where(.group):focus *):is(:where(.peer):focus ~ *), .peer-focus\\:group-focus\\:flex:is(:where(.peer):focus ~ *):is(:where(.group):focus *) {
display: flex;
}
@ -2198,11 +2168,7 @@ describe('plugins', () => {
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
"@layer utilities {
.rtl\\:flex:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
display: flex;
}
.dark\\:flex:is([data-theme="dark"] *) {
.rtl\\:flex:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *), .dark\\:flex:is([data-theme="dark"] *) {
display: flex;
}
@ -2386,11 +2352,7 @@ describe('@variant', () => {
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
"@layer utilities {
.group-selected\\:underline:is(:where(.group)[data-selected] *) {
text-decoration-line: underline;
}
.selected\\:underline[data-selected] {
.group-selected\\:underline:is(:where(.group)[data-selected] *), .selected\\:underline[data-selected] {
text-decoration-line: underline;
}
}"
@ -2414,11 +2376,7 @@ describe('@variant', () => {
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
"@layer utilities {
.group-hocus\\:underline:is(:is(:where(.group):hover, :where(.group):focus) *) {
text-decoration-line: underline;
}
.hocus\\:underline:hover, .hocus\\:underline:focus {
.group-hocus\\:underline:is(:is(:where(.group):hover, :where(.group):focus) *), .hocus\\:underline:hover, .hocus\\:underline:focus {
text-decoration-line: underline;
}
}"
@ -2445,11 +2403,7 @@ describe('@variant', () => {
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
"@layer utilities {
.group-hocus\\:underline:is(:where(.group):hover *), .group-hocus\\:underline:is(:where(.group):focus *) {
text-decoration-line: underline;
}
.hocus\\:underline:hover, .hocus\\:underline:focus {
.group-hocus\\:underline:is(:where(.group):hover *), .group-hocus\\:underline:is(:where(.group):focus *), .hocus\\:underline:hover, .hocus\\:underline:focus {
text-decoration-line: underline;
}
}"
@ -2583,13 +2537,7 @@ describe('@variant', () => {
expect(optimizeCss(compiled).trim()).toMatchInlineSnapshot(`
"@layer utilities {
@media (hover: hover) {
.group-hocus\\:underline:is(:where(.group):hover *) {
text-decoration-line: underline;
}
}
@media (hover: hover) {
.hocus\\:underline:hover {
.group-hocus\\:underline:is(:where(.group):hover *), .hocus\\:underline:hover {
text-decoration-line: underline;
}
}
@ -2745,11 +2693,7 @@ describe('@variant', () => {
),
).toMatchInlineSnapshot(`
"@layer utilities {
.rtl\\:flex:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *) {
display: flex;
}
.dark\\:flex:is([data-theme="dark"] *) {
.rtl\\:flex:where(:dir(rtl), [dir="rtl"], [dir="rtl"] *), .dark\\:flex:is([data-theme="dark"] *) {
display: flex;
}

View File

@ -15,22 +15,28 @@ export function optimizeCss(
input: string,
{ file = 'input.css', minify = false }: { file?: string; minify?: boolean } = {},
) {
return transform({
filename: file,
code: Buffer.from(input),
minify,
sourceMap: false,
drafts: {
customMedia: true,
},
nonStandard: {
deepSelectorCombinator: true,
},
include: Features.Nesting,
exclude: Features.LogicalProperties,
targets: {
safari: (16 << 16) | (4 << 8),
},
errorRecovery: true,
}).code.toString()
function optimize(code: Buffer | Uint8Array) {
return transform({
filename: file,
code,
minify,
sourceMap: false,
drafts: {
customMedia: true,
},
nonStandard: {
deepSelectorCombinator: true,
},
include: Features.Nesting,
exclude: Features.LogicalProperties,
targets: {
safari: (16 << 16) | (4 << 8),
},
errorRecovery: true,
}).code
}
// Running Lightning CSS twice to ensure that adjacent rules are merged after
// nesting is applied. This creates a more optimized output.
return optimize(optimize(Buffer.from(input))).toString()
}

View File

@ -6384,18 +6384,24 @@ test('color-scheme', async () => {
]),
).toMatchInlineSnapshot(`
".scheme-dark {
--lightningcss-light: ;
--lightningcss-dark: initial;
--lightningcss-light: ;
--lightningcss-dark: initial;
color-scheme: dark;
}
.scheme-light {
--lightningcss-light: initial;
--lightningcss-dark: ;
--lightningcss-light: initial;
--lightningcss-dark: ;
color-scheme: light;
}
.scheme-light-dark {
--lightningcss-light: initial;
--lightningcss-dark: ;
--lightningcss-light: initial;
--lightningcss-dark: ;
color-scheme: light dark;
@ -6413,12 +6419,16 @@ test('color-scheme', async () => {
}
.scheme-only-dark {
--lightningcss-light: ;
--lightningcss-dark: initial;
--lightningcss-light: ;
--lightningcss-dark: initial;
color-scheme: dark only;
}
.scheme-only-light {
--lightningcss-light: initial;
--lightningcss-dark: ;
--lightningcss-light: initial;
--lightningcss-dark: ;
color-scheme: light only;
@ -8100,15 +8110,7 @@ test('divide-color', async () => {
border-color: #08c;
}
:where(.divide-\\[\\#0088cc\\]\\/50 > :not(:last-child)) {
border-color: oklch(59.9824% .14119 241.555 / .5);
}
:where(.divide-\\[\\#0088cc\\]\\/\\[0\\.5\\] > :not(:last-child)) {
border-color: oklch(59.9824% .14119 241.555 / .5);
}
:where(.divide-\\[\\#0088cc\\]\\/\\[50\\%\\] > :not(:last-child)) {
:where(.divide-\\[\\#0088cc\\]\\/50 > :not(:last-child)), :where(.divide-\\[\\#0088cc\\]\\/\\[0\\.5\\] > :not(:last-child)), :where(.divide-\\[\\#0088cc\\]\\/\\[50\\%\\] > :not(:last-child)) {
border-color: oklch(59.9824% .14119 241.555 / .5);
}
@ -8116,15 +8118,7 @@ test('divide-color', async () => {
border-color: currentColor;
}
:where(.divide-current\\/50 > :not(:last-child)) {
border-color: color-mix(in oklch, currentColor 50%, transparent);
}
:where(.divide-current\\/\\[0\\.5\\] > :not(:last-child)) {
border-color: color-mix(in oklch, currentColor 50%, transparent);
}
:where(.divide-current\\/\\[50\\%\\] > :not(:last-child)) {
:where(.divide-current\\/50 > :not(:last-child)), :where(.divide-current\\/\\[0\\.5\\] > :not(:last-child)), :where(.divide-current\\/\\[50\\%\\] > :not(:last-child)) {
border-color: color-mix(in oklch, currentColor 50%, transparent);
}
@ -8136,15 +8130,7 @@ test('divide-color', async () => {
border-color: var(--color-red-500);
}
:where(.divide-red-500\\/50 > :not(:last-child)) {
border-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
}
:where(.divide-red-500\\/\\[0\\.5\\] > :not(:last-child)) {
border-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
}
:where(.divide-red-500\\/\\[50\\%\\] > :not(:last-child)) {
:where(.divide-red-500\\/50 > :not(:last-child)), :where(.divide-red-500\\/\\[0\\.5\\] > :not(:last-child)), :where(.divide-red-500\\/\\[50\\%\\] > :not(:last-child)) {
border-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
}
@ -12553,15 +12539,7 @@ test('placeholder', async () => {
color: #08c;
}
.placeholder-\\[\\#0088cc\\]\\/50::placeholder {
color: oklch(59.9824% .14119 241.555 / .5);
}
.placeholder-\\[\\#0088cc\\]\\/\\[0\\.5\\]::placeholder {
color: oklch(59.9824% .14119 241.555 / .5);
}
.placeholder-\\[\\#0088cc\\]\\/\\[50\\%\\]::placeholder {
.placeholder-\\[\\#0088cc\\]\\/50::placeholder, .placeholder-\\[\\#0088cc\\]\\/\\[0\\.5\\]::placeholder, .placeholder-\\[\\#0088cc\\]\\/\\[50\\%\\]::placeholder {
color: oklch(59.9824% .14119 241.555 / .5);
}
@ -12569,15 +12547,7 @@ test('placeholder', async () => {
color: currentColor;
}
.placeholder-current\\/50::placeholder {
color: color-mix(in oklch, currentColor 50%, transparent);
}
.placeholder-current\\/\\[0\\.5\\]::placeholder {
color: color-mix(in oklch, currentColor 50%, transparent);
}
.placeholder-current\\/\\[50\\%\\]::placeholder {
.placeholder-current\\/50::placeholder, .placeholder-current\\/\\[0\\.5\\]::placeholder, .placeholder-current\\/\\[50\\%\\]::placeholder {
color: color-mix(in oklch, currentColor 50%, transparent);
}
@ -12589,15 +12559,7 @@ test('placeholder', async () => {
color: var(--color-red-500);
}
.placeholder-red-500\\/50::placeholder {
color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
}
.placeholder-red-500\\/\\[0\\.5\\]::placeholder {
color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
}
.placeholder-red-500\\/\\[50\\%\\]::placeholder {
.placeholder-red-500\\/50::placeholder, .placeholder-red-500\\/\\[0\\.5\\]::placeholder, .placeholder-red-500\\/\\[50\\%\\]::placeholder {
color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
}
@ -12695,21 +12657,25 @@ test('decoration', async () => {
}
.decoration-\\[color\\:var\\(--my-color\\)\\] {
-webkit-text-decoration-color: var(--my-color);
-webkit-text-decoration-color: var(--my-color);
text-decoration-color: var(--my-color);
}
.decoration-\\[color\\:var\\(--my-color\\)\\]\\/50, .decoration-\\[color\\:var\\(--my-color\\)\\]\\/\\[0\\.5\\], .decoration-\\[color\\:var\\(--my-color\\)\\]\\/\\[50\\%\\] {
-webkit-text-decoration-color: color-mix(in oklch, var(--my-color) 50%, transparent);
-webkit-text-decoration-color: color-mix(in oklch, var(--my-color) 50%, transparent);
text-decoration-color: color-mix(in oklch, var(--my-color) 50%, transparent);
}
.decoration-\\[var\\(--my-color\\)\\] {
-webkit-text-decoration-color: var(--my-color);
-webkit-text-decoration-color: var(--my-color);
text-decoration-color: var(--my-color);
}
.decoration-\\[var\\(--my-color\\)\\]\\/50, .decoration-\\[var\\(--my-color\\)\\]\\/\\[0\\.5\\], .decoration-\\[var\\(--my-color\\)\\]\\/\\[50\\%\\] {
-webkit-text-decoration-color: color-mix(in oklch, var(--my-color) 50%, transparent);
-webkit-text-decoration-color: color-mix(in oklch, var(--my-color) 50%, transparent);
text-decoration-color: color-mix(in oklch, var(--my-color) 50%, transparent);
}
@ -12719,21 +12685,25 @@ test('decoration', async () => {
}
.decoration-current\\/50, .decoration-current\\/\\[0\\.5\\], .decoration-current\\/\\[50\\%\\] {
-webkit-text-decoration-color: color-mix(in oklch, currentColor 50%, transparent);
-webkit-text-decoration-color: color-mix(in oklch, currentColor 50%, transparent);
text-decoration-color: color-mix(in oklch, currentColor 50%, transparent);
}
.decoration-inherit {
-webkit-text-decoration-color: inherit;
-webkit-text-decoration-color: inherit;
text-decoration-color: inherit;
}
.decoration-red-500 {
-webkit-text-decoration-color: var(--color-red-500);
-webkit-text-decoration-color: var(--color-red-500);
text-decoration-color: var(--color-red-500);
}
.decoration-red-500\\/50, .decoration-red-500\\/\\[0\\.5\\], .decoration-red-500\\/\\[50\\%\\] {
-webkit-text-decoration-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
-webkit-text-decoration-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
text-decoration-color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
}
@ -12787,7 +12757,7 @@ test('decoration', async () => {
}
.decoration-\\[50\\%\\] {
text-decoration-thickness: calc(1em / 2);
text-decoration-thickness: .5em;
}
.decoration-\\[length\\:var\\(--my-thickness\\)\\], .decoration-\\[percentage\\:var\\(--my-thickness\\)\\] {
@ -13616,7 +13586,7 @@ test('transition', async () => {
}
.transition {
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, -webkit-backdrop-filter, backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, -webkit-backdrop-filter, -webkit-backdrop-filter, backdrop-filter;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
transition-duration: var(--tw-duration, var(--default-transition-duration));
}
@ -13683,7 +13653,7 @@ test('transition', async () => {
}
.transition {
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, -webkit-backdrop-filter, backdrop-filter;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, -webkit-backdrop-filter, -webkit-backdrop-filter, backdrop-filter;
transition-timing-function: var(--tw-ease, ease);
transition-duration: var(--tw-duration, .1s);
}

File diff suppressed because it is too large Load Diff

View File

@ -7,5 +7,5 @@ packages:
catalog:
'@types/node': ^20.14.8
lightningcss: ^1.26.0
lightningcss: ^1.28.1
vite: ^5.4.0