Skip to content

Commit 6bd9912

Browse files
Only sort pseudo elements after classes when using @apply and variants (#9765)
* Sort pseudo elements ONLY after classes * Update changelog
1 parent aac468c commit 6bd9912

File tree

5 files changed

+51
-17
lines changed

5 files changed

+51
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- Fixed use of `raw` content in the CLI ([#9773](https://github.com/tailwindlabs/tailwindcss/pull/9773))
1313
- Pick up changes from files that are both context and content deps ([#9787](https://github.com/tailwindlabs/tailwindcss/pull/9787))
14+
- Sort pseudo-elements ONLY after classes when using variants and `@apply` ([#9765](https://github.com/tailwindlabs/tailwindcss/pull/9765))
1415

1516
## [3.2.2] - 2022-11-04
1617

src/lib/expandApplyAtRules.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,9 @@ function processApply(root, context, localCache) {
370370
return -1
371371
} else if (a.type === 'class' && b.type === 'tag') {
372372
return 1
373-
} else if (a.type === 'class' && b.type === 'pseudo') {
373+
} else if (a.type === 'class' && b.type === 'pseudo' && b.value.startsWith('::')) {
374374
return -1
375-
} else if (a.type === 'pseudo' && b.type === 'class') {
375+
} else if (a.type === 'pseudo' && a.value.startsWith('::') && b.type === 'class') {
376376
return 1
377377
}
378378

src/util/formatVariantSelector.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ function resortSelector(sel) {
6969
return -1
7070
} else if (a.type === 'class' && b.type === 'tag') {
7171
return 1
72-
} else if (a.type === 'class' && b.type === 'pseudo' && b.value !== ':merge') {
72+
} else if (a.type === 'class' && b.type === 'pseudo' && b.value.startsWith('::')) {
7373
return -1
74-
} else if (a.type === 'pseudo' && a.value !== ':merge' && b.type === 'class') {
74+
} else if (a.type === 'pseudo' && a.value.startsWith('::') && b.type === 'class') {
7575
return 1
7676
}
7777

tests/apply.test.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,6 +1601,9 @@ it('can apply joined classes when using elements', async () => {
16011601
header:nth-of-type(odd) {
16021602
@apply foo;
16031603
}
1604+
header::after {
1605+
@apply foo;
1606+
}
16041607
main {
16051608
@apply foo bar;
16061609
}
@@ -1618,7 +1621,13 @@ it('can apply joined classes when using elements', async () => {
16181621
.bar.foo {
16191622
color: green;
16201623
}
1624+
header:nth-of-type(odd).bar {
1625+
color: red;
1626+
}
16211627
header.bar:nth-of-type(odd) {
1628+
color: green;
1629+
}
1630+
header.bar::after {
16221631
color: red;
16231632
color: green;
16241633
}
@@ -1721,21 +1730,15 @@ it('should maintain the correct selector when applying other utilities', () => {
17211730

17221731
return run(input, config).then((result) => {
17231732
expect(result.css).toMatchFormattedCss(css`
1724-
.foo.bar:hover .baz {
1733+
.foo:hover.bar .baz {
17251734
--tw-bg-opacity: 1;
17261735
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
1727-
}
1728-
1729-
.foo:hover.bar .baz {
17301736
color: red;
17311737
}
17321738
1733-
.foo.bar:hover > .baz {
1739+
.foo:hover.bar > .baz {
17341740
--tw-bg-opacity: 1;
17351741
background-color: rgb(0 0 0 / var(--tw-bg-opacity));
1736-
}
1737-
1738-
.foo:hover.bar > .baz {
17391742
color: red;
17401743
}
17411744
`)

tests/variants.test.js

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -861,12 +861,12 @@ test('multi-class utilities handle selector-mutating variants correctly', () =>
861861
content: [
862862
{
863863
raw: html`<div
864-
class="hover:foo hover:bar hover:baz group-hover:foo group-hover:bar group-hover:baz peer-checked:foo peer-checked:bar peer-checked:baz"
864+
class="after:foo after:bar after:baz hover:foo hover:bar hover:baz group-hover:foo group-hover:bar group-hover:baz peer-checked:foo peer-checked:bar peer-checked:baz"
865865
></div>`,
866866
},
867867
{
868868
raw: html`<div
869-
class="hover:foo1 hover:bar1 hover:baz1 group-hover:foo1 group-hover:bar1 group-hover:baz1 peer-checked:foo1 peer-checked:bar1 peer-checked:baz1"
869+
class="after:foo1 after:bar1 after:baz1 hover:foo1 hover:bar1 hover:baz1 group-hover:foo1 group-hover:bar1 group-hover:baz1 peer-checked:foo1 peer-checked:bar1 peer-checked:baz1"
870870
></div>`,
871871
},
872872
],
@@ -885,15 +885,45 @@ test('multi-class utilities handle selector-mutating variants correctly', () =>
885885
}
886886
`
887887

888+
// The second set of ::after cases (w/ descendant selectors)
889+
// are clearly "wrong" BUT you can't have a descendant of a
890+
// pseudo - element so the utilities `after:foo1` and
891+
// `after:bar1` are non-sensical so this is still
892+
// perfectly fine behavior
893+
888894
return run(input, config).then((result) => {
889895
expect(result.css).toMatchFormattedCss(css`
890-
.hover\:foo.bar.baz:hover {
896+
.after\:foo.bar.baz::after {
897+
content: var(--tw-content);
898+
color: red;
899+
}
900+
.after\:bar.foo.baz::after {
901+
content: var(--tw-content);
902+
color: red;
903+
}
904+
.after\:baz.foo.bar::after {
905+
content: var(--tw-content);
906+
color: red;
907+
}
908+
.after\:foo1 .bar1 .baz1::after {
909+
content: var(--tw-content);
910+
color: red;
911+
}
912+
.foo1 .after\:bar1 .baz1::after {
913+
content: var(--tw-content);
914+
color: red;
915+
}
916+
.foo1 .bar1 .after\:baz1::after {
917+
content: var(--tw-content);
918+
color: red;
919+
}
920+
.hover\:foo:hover.bar.baz {
891921
color: red;
892922
}
893-
.hover\:bar.foo.baz:hover {
923+
.hover\:bar:hover.foo.baz {
894924
color: red;
895925
}
896-
.hover\:baz.foo.bar:hover {
926+
.hover\:baz:hover.foo.bar {
897927
color: red;
898928
}
899929
.hover\:foo1:hover .bar1 .baz1 {

0 commit comments

Comments
 (0)