diff --git a/src/lib/generateRules.js b/src/lib/generateRules.js index 57bb1d140cd3..05bdd784e95e 100644 --- a/src/lib/generateRules.js +++ b/src/lib/generateRules.js @@ -119,10 +119,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 6d30fd0bceb3..6f6f1a8de54a 100644 --- a/tests/important-modifier.test.js +++ b/tests/important-modifier.test.js @@ -150,4 +150,34 @@ crosscheck(() => { `) }) }) + + 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; + } + `) + }) + }) }) +