diff --git a/CHANGELOG.md b/CHANGELOG.md index d6ef24b4883a..0d1528b096e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed use of `raw` content in the CLI ([#9773](https://github.com/tailwindlabs/tailwindcss/pull/9773)) - Pick up changes from files that are both context and content deps ([#9787](https://github.com/tailwindlabs/tailwindcss/pull/9787)) +- Sort pseudo-elements ONLY after classes when using variants and `@apply` ([#9765](https://github.com/tailwindlabs/tailwindcss/pull/9765)) ## [3.2.2] - 2022-11-04 diff --git a/src/lib/expandApplyAtRules.js b/src/lib/expandApplyAtRules.js index e1453af0152a..8ca50fb99ae9 100644 --- a/src/lib/expandApplyAtRules.js +++ b/src/lib/expandApplyAtRules.js @@ -370,9 +370,9 @@ function processApply(root, context, localCache) { return -1 } else if (a.type === 'class' && b.type === 'tag') { return 1 - } else if (a.type === 'class' && b.type === 'pseudo') { + } else if (a.type === 'class' && b.type === 'pseudo' && b.value.startsWith('::')) { return -1 - } else if (a.type === 'pseudo' && b.type === 'class') { + } else if (a.type === 'pseudo' && a.value.startsWith('::') && b.type === 'class') { return 1 } diff --git a/src/util/formatVariantSelector.js b/src/util/formatVariantSelector.js index ffcc5f037eed..ae6aa69a0a29 100644 --- a/src/util/formatVariantSelector.js +++ b/src/util/formatVariantSelector.js @@ -69,9 +69,9 @@ function resortSelector(sel) { return -1 } else if (a.type === 'class' && b.type === 'tag') { return 1 - } else if (a.type === 'class' && b.type === 'pseudo' && b.value !== ':merge') { + } else if (a.type === 'class' && b.type === 'pseudo' && b.value.startsWith('::')) { return -1 - } else if (a.type === 'pseudo' && a.value !== ':merge' && b.type === 'class') { + } else if (a.type === 'pseudo' && a.value.startsWith('::') && b.type === 'class') { return 1 } diff --git a/tests/apply.test.js b/tests/apply.test.js index 5eb8ecb38151..6f7214d990ab 100644 --- a/tests/apply.test.js +++ b/tests/apply.test.js @@ -1601,6 +1601,9 @@ it('can apply joined classes when using elements', async () => { header:nth-of-type(odd) { @apply foo; } + header::after { + @apply foo; + } main { @apply foo bar; } @@ -1618,7 +1621,13 @@ it('can apply joined classes when using elements', async () => { .bar.foo { color: green; } + header:nth-of-type(odd).bar { + color: red; + } header.bar:nth-of-type(odd) { + color: green; + } + header.bar::after { color: red; color: green; } @@ -1721,21 +1730,15 @@ it('should maintain the correct selector when applying other utilities', () => { return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - .foo.bar:hover .baz { + .foo:hover.bar .baz { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity)); - } - - .foo:hover.bar .baz { color: red; } - .foo.bar:hover > .baz { + .foo:hover.bar > .baz { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity)); - } - - .foo:hover.bar > .baz { color: red; } `) diff --git a/tests/variants.test.js b/tests/variants.test.js index e05c826fdfc2..6de7c3dd0caf 100644 --- a/tests/variants.test.js +++ b/tests/variants.test.js @@ -861,12 +861,12 @@ test('multi-class utilities handle selector-mutating variants correctly', () => content: [ { raw: html`
`, }, { raw: html`
`, }, ], @@ -885,15 +885,45 @@ test('multi-class utilities handle selector-mutating variants correctly', () => } ` + // The second set of ::after cases (w/ descendant selectors) + // are clearly "wrong" BUT you can't have a descendant of a + // pseudo - element so the utilities `after:foo1` and + // `after:bar1` are non-sensical so this is still + // perfectly fine behavior + return run(input, config).then((result) => { expect(result.css).toMatchFormattedCss(css` - .hover\:foo.bar.baz:hover { + .after\:foo.bar.baz::after { + content: var(--tw-content); + color: red; + } + .after\:bar.foo.baz::after { + content: var(--tw-content); + color: red; + } + .after\:baz.foo.bar::after { + content: var(--tw-content); + color: red; + } + .after\:foo1 .bar1 .baz1::after { + content: var(--tw-content); + color: red; + } + .foo1 .after\:bar1 .baz1::after { + content: var(--tw-content); + color: red; + } + .foo1 .bar1 .after\:baz1::after { + content: var(--tw-content); + color: red; + } + .hover\:foo:hover.bar.baz { color: red; } - .hover\:bar.foo.baz:hover { + .hover\:bar:hover.foo.baz { color: red; } - .hover\:baz.foo.bar:hover { + .hover\:baz:hover.foo.bar { color: red; } .hover\:foo1:hover .bar1 .baz1 {