Skip to content

Commit 06dfa39

Browse files
authored
Ensure we always emit @keyframes correctly (#16237)
This PR fixes an issue where we didn't always generate the `@keyframes`. Right now we only generate `@keyframes` _if_ they are being used as one of the `--animate-*` utilities. However, if your `--animate-*` definition is pretty long such that it is defined across multiple lines, then we didn't always generate the `@keyframes` for it. This is because the animation name would look like `'my-animation-name\n'` instead of `'my-animation-name'`. Fixes: #16227
1 parent ac202ff commit 06dfa39

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
- Nothing yet!
11-
1210
### Fixed
1311

1412
- Ensure that the `containers` JS theme key is added to the `--container-*` namespace. ([#16169](https://github.com/tailwindlabs/tailwindcss/pull/16169))
13+
- Fix missing `@keyframes` definition ([#16237](https://github.com/tailwindlabs/tailwindcss/pull/16237))
1514

1615
## [4.0.3] - 2025-02-01
1716

packages/tailwindcss/src/index.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,45 @@ describe('Parsing themes values from CSS', () => {
11701170
`)
11711171
})
11721172

1173+
test('`@keyframes` in `@theme` are generated when name contains a new line', async () => {
1174+
expect(
1175+
await compileCss(
1176+
css`
1177+
@theme {
1178+
--animate-very-long-animation-name: very-long-animation-name
1179+
var(
1180+
--very-long-animation-name-configuration,
1181+
2.5s ease-in-out 0s infinite normal none running
1182+
);
1183+
1184+
@keyframes very-long-animation-name {
1185+
to {
1186+
opacity: 1;
1187+
}
1188+
}
1189+
}
1190+
1191+
@tailwind utilities;
1192+
`,
1193+
['animate-very-long-animation-name'],
1194+
),
1195+
).toMatchInlineSnapshot(`
1196+
":root, :host {
1197+
--animate-very-long-animation-name: very-long-animation-name var(--very-long-animation-name-configuration, 2.5s ease-in-out 0s infinite normal none running);
1198+
}
1199+
1200+
.animate-very-long-animation-name {
1201+
animation: var(--animate-very-long-animation-name);
1202+
}
1203+
1204+
@keyframes very-long-animation-name {
1205+
to {
1206+
opacity: 1;
1207+
}
1208+
}"
1209+
`)
1210+
})
1211+
11731212
test('`@theme` values can be unset', async () => {
11741213
expect(
11751214
await compileCss(

packages/tailwindcss/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ async function parseCss(
545545
let keyframesRules = theme.getKeyframes()
546546
if (keyframesRules.length > 0) {
547547
let animationParts = [...theme.namespace('--animate').values()].flatMap((animation) =>
548-
animation.split(' '),
548+
animation.split(/\s+/),
549549
)
550550

551551
for (let keyframesRule of keyframesRules) {

0 commit comments

Comments
 (0)