diff --git a/packages/tailwindcss/src/apply.ts b/packages/tailwindcss/src/apply.ts index 0cbdf4940..66a97ab40 100644 --- a/packages/tailwindcss/src/apply.ts +++ b/packages/tailwindcss/src/apply.ts @@ -1,4 +1,4 @@ -import { walk, type AstNode } from './ast' +import { walk, WalkAction, type AstNode } from './ast' import { compileCandidates } from './compile' import type { DesignSystem } from './design-system' import { escape } from './utils/escape' @@ -6,6 +6,21 @@ import { escape } from './utils/escape' export function substituteAtApply(ast: AstNode[], designSystem: DesignSystem) { walk(ast, (node, { replaceWith }) => { if (node.kind !== 'rule') return + + // Do not allow `@apply` rules inside `@keyframes` rules. + if (node.selector[0] === '@' && node.selector.startsWith('@keyframes')) { + walk(node.nodes, (child) => { + if ( + child.kind === 'rule' && + child.selector[0] === '@' && + child.selector.startsWith('@apply ') + ) { + throw new Error(`You cannot use \`@apply\` inside \`@keyframes\`.`) + } + }) + return WalkAction.Skip + } + if (!(node.selector[0] === '@' && node.selector.startsWith('@apply '))) return let candidates = node.selector diff --git a/packages/tailwindcss/src/index.test.ts b/packages/tailwindcss/src/index.test.ts index 3eee033dd..04c0c7c4d 100644 --- a/packages/tailwindcss/src/index.test.ts +++ b/packages/tailwindcss/src/index.test.ts @@ -148,6 +148,20 @@ describe('arbitrary properties', () => { }) describe('@apply', () => { + it('@apply in @keyframes is not allowed', () => { + return expect(() => + compileCss(css` + @keyframes foo { + 0% { + @apply bg-red-500; + } + } + `), + ).rejects.toThrowErrorMatchingInlineSnapshot( + `[Error: You cannot use \`@apply\` inside \`@keyframes\`.]`, + ) + }) + it('should replace @apply with the correct result', async () => { expect( await compileCss(css`