diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index ac9fbb11926e..89f8515d061b 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -118,10 +118,20 @@ function applyImportant(matches, classCandidate) { let result = [] + function isInKeyframes(rule) { + return rule.parent && rule.parent.type === 'atrule' && rule.parent.name === 'keyframes' + } + for (let [meta, rule] of matches) { let container = postcss.root({ nodes: [rule.clone()] }) container.walkRules((r) => { + // Declarations inside keyframes cannot be marked as important + // They will be ignored by the browser + if (isInKeyframes(r)) { + return + } + let ast = selectorParser().astSync(r.selector) // Remove extraneous selectors that do not include the base candidate diff --git a/tests/important-modifier.test.js b/tests/important-modifier.test.js index fe4e14b335fe..da5ac5d7d4e6 100644 --- a/tests/important-modifier.test.js +++ b/tests/important-modifier.test.js @@ -147,3 +147,32 @@ test('the important modifier works on utilities using :where()', () => { `) }) }) + +test('the important modifier does not break keyframes', () => { + let config = { + content: [ + { + raw: html`
`, + }, + ], + corePlugins: { preflight: false }, + } + + let input = css` + @tailwind utilities; + ` + + return run(input, config).then((result) => { + expect(result.css).toMatchFormattedCss(css` + @keyframes pulse { + 50% { + opacity: 0.5; + } + } + + .\!animate-pulse { + animation: 2s cubic-bezier(0.4, 0, 0.6, 1) infinite pulse !important; + } + `) + }) +})