diff --git a/CHANGELOG.md b/CHANGELOG.md index a7e4f99b017a..c8992c5123d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - Prevent nesting plugin from breaking other plugins ([#7563](https://github.com/tailwindlabs/tailwindcss/pull/7563)) +- Recursively collapse adjacent rules ([#7565](https://github.com/tailwindlabs/tailwindcss/pull/7565)) ## [3.0.23] - 2022-02-16 diff --git a/src/lib/collapseAdjacentRules.js b/src/lib/collapseAdjacentRules.js index 8a7c5775cc1b..16ebb0d1abae 100644 --- a/src/lib/collapseAdjacentRules.js +++ b/src/lib/collapseAdjacentRules.js @@ -5,7 +5,7 @@ let comparisonMap = { let types = new Set(Object.keys(comparisonMap)) export default function collapseAdjacentRules() { - return (root) => { + function collapseRulesIn(root) { let currentRule = null root.each((node) => { if (!types.has(node.type)) { @@ -35,5 +35,20 @@ export default function collapseAdjacentRules() { currentRule = node } }) + + // After we've collapsed adjacent rules & at-rules, we need to collapse + // adjacent rules & at-rules that are children of at-rules. + // We do not care about nesting rules because Tailwind CSS + // explicitly does not handle rule nesting on its own as + // the user is expected to use a nesting plugin + root.each((node) => { + if (node.type === 'atrule') { + collapseRulesIn(node) + } + }) + } + + return (root) => { + collapseRulesIn(root) } } diff --git a/tests/apply.test.js b/tests/apply.test.js index a015262c3128..99b620804654 100644 --- a/tests/apply.test.js +++ b/tests/apply.test.js @@ -1289,9 +1289,6 @@ it('apply partitioning works with media queries', async () => { body { --tw-text-opacity: 1; color: rgb(220 38 38 / var(--tw-text-opacity)); - } - html, - body { font-size: 2rem; } } diff --git a/tests/collapse-adjacent-rules.test.css b/tests/collapse-adjacent-rules.test.css index 2481c3dd7a42..0c152eb59827 100644 --- a/tests/collapse-adjacent-rules.test.css +++ b/tests/collapse-adjacent-rules.test.css @@ -72,6 +72,29 @@ color: black; font-weight: 700; } +@supports (foo: bar) { + .some-apply-thing { + font-weight: 700; + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)); + } +} +@media (min-width: 768px) { + .some-apply-thing { + font-weight: 700; + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)); + } +} +@supports (foo: bar) { + @media (min-width: 768px) { + .some-apply-thing { + font-weight: 700; + --tw-text-opacity: 1; + color: rgb(0 0 0 / var(--tw-text-opacity)); + } + } +} @media (min-width: 640px) { .sm\:text-center { text-align: center; diff --git a/tests/collapse-adjacent-rules.test.html b/tests/collapse-adjacent-rules.test.html index 3b12ab42912b..b8baba47998a 100644 --- a/tests/collapse-adjacent-rules.test.html +++ b/tests/collapse-adjacent-rules.test.html @@ -19,5 +19,6 @@
+
diff --git a/tests/collapse-adjacent-rules.test.js b/tests/collapse-adjacent-rules.test.js index 709f71269c0e..a13e1fc665fa 100644 --- a/tests/collapse-adjacent-rules.test.js +++ b/tests/collapse-adjacent-rules.test.js @@ -8,7 +8,11 @@ test('collapse adjacent rules', () => { content: [path.resolve(__dirname, './collapse-adjacent-rules.test.html')], corePlugins: { preflight: false }, theme: {}, - plugins: [], + plugins: [ + function ({ addVariant }) { + addVariant('foo-bar', '@supports (foo: bar)') + }, + ], } let input = css` @@ -45,6 +49,9 @@ test('collapse adjacent rules', () => { .bar { font-weight: 700; } + .some-apply-thing { + @apply foo-bar:md:text-black foo-bar:md:font-bold foo-bar:text-black foo-bar:font-bold md:font-bold md:text-black; + } ` return run(input, config).then((result) => { diff --git a/tests/kitchen-sink.test.css b/tests/kitchen-sink.test.css index 024106246f46..ece88f25fd6d 100644 --- a/tests/kitchen-sink.test.css +++ b/tests/kitchen-sink.test.css @@ -498,8 +498,6 @@ div { transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; } - } - @media (prefers-reduced-motion: no-preference) { .dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active { background: #abcdef !important; }