Skip to content

Commit e40b73a

Browse files
authored
Make dark and rtl/ltr variants insensitive to DOM order (#10766)
* Make `dark` and `rtl`/`ltr` variants insensitive to DOM order * Add explicit test for stacking dark and rtl variants * Update changelog --------- Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
1 parent ba56e42 commit e40b73a

12 files changed

+70
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3232
- [Oxide] Enable relative content paths for the `oxide` engine ([#10621](https://github.com/tailwindlabs/tailwindcss/pull/10621))
3333
- Mark `rtl` and `ltr` variants as stable and remove warnings ([#10764](https://github.com/tailwindlabs/tailwindcss/pull/10764))
3434
- Use `inset` instead of `top`, `right`, `bottom`, and `left` properties ([#10765](https://github.com/tailwindlabs/tailwindcss/pull/10765))
35+
- Make `dark` and `rtl`/`ltr` variants insensitive to DOM order ([#10766](https://github.com/tailwindlabs/tailwindcss/pull/10766))
3536

3637
## [3.2.7] - 2023-02-16
3738

src/corePlugins.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ export let variantPlugins = {
199199
},
200200

201201
directionVariants: ({ addVariant }) => {
202-
addVariant('ltr', '[dir="ltr"] &')
203-
addVariant('rtl', '[dir="rtl"] &')
202+
addVariant('ltr', ':is([dir="ltr"] &)')
203+
addVariant('rtl', ':is([dir="rtl"] &)')
204204
},
205205

206206
reducedMotionVariants: ({ addVariant }) => {
@@ -221,7 +221,7 @@ export let variantPlugins = {
221221
}
222222

223223
if (mode === 'class') {
224-
addVariant('dark', `${className} &`)
224+
addVariant('dark', `:is(${className} &)`)
225225
} else if (mode === 'media') {
226226
addVariant('dark', '@media (prefers-color-scheme: dark)')
227227
}

tests/apply.test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,14 @@ crosscheck(({ stable, oxide }) => {
216216
text-align: left;
217217
}
218218
}
219-
.dark .apply-dark-variant {
219+
:is(.dark .apply-dark-variant) {
220220
text-align: center;
221221
}
222-
.dark .apply-dark-variant:hover {
222+
:is(.dark .apply-dark-variant:hover) {
223223
text-align: right;
224224
}
225225
@media (min-width: 1024px) {
226-
.dark .apply-dark-variant {
226+
:is(.dark .apply-dark-variant) {
227227
text-align: left;
228228
}
229229
}
@@ -513,14 +513,14 @@ crosscheck(({ stable, oxide }) => {
513513
text-align: left;
514514
}
515515
}
516-
.dark .apply-dark-variant {
516+
:is(.dark .apply-dark-variant) {
517517
text-align: center;
518518
}
519-
.dark .apply-dark-variant:hover {
519+
:is(.dark .apply-dark-variant:hover) {
520520
text-align: right;
521521
}
522522
@media (min-width: 1024px) {
523-
.dark .apply-dark-variant {
523+
:is(.dark .apply-dark-variant) {
524524
text-align: left;
525525
}
526526
}

tests/custom-separator.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ crosscheck(() => {
2323
.group:hover .group-hover_focus-within_text-left:focus-within {
2424
text-align: left;
2525
}
26-
[dir='rtl'] .rtl_active_text-center:active {
26+
:is([dir='rtl'] .rtl_active_text-center:active) {
2727
text-align: center;
2828
}
2929
@media (prefers-reduced-motion: no-preference) {
3030
.motion-safe_hover_text-center:hover {
3131
text-align: center;
3232
}
3333
}
34-
.dark .dark_focus_text-left:focus {
34+
:is(.dark .dark_focus_text-left:focus) {
3535
text-align: left;
3636
}
3737
@media (min-width: 768px) {

tests/dark-mode.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ crosscheck(() => {
1717
return run(input, config).then((result) => {
1818
expect(result.css).toMatchFormattedCss(css`
1919
${defaults}
20-
.dark .dark\:font-bold {
20+
:is(.dark .dark\:font-bold) {
2121
font-weight: 700;
2222
}
2323
`)
@@ -40,7 +40,7 @@ crosscheck(() => {
4040
return run(input, config).then((result) => {
4141
expect(result.css).toMatchFormattedCss(css`
4242
${defaults}
43-
.test-dark .dark\:font-bold {
43+
:is(.test-dark .dark\:font-bold) {
4444
font-weight: 700;
4545
}
4646
`)

tests/important-boolean.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,15 @@ crosscheck(() => {
138138
.group:hover .group-hover\:focus-within\:text-left:focus-within {
139139
text-align: left !important;
140140
}
141-
[dir='rtl'] .rtl\:active\:text-center:active {
141+
:is([dir='rtl'] .rtl\:active\:text-center:active) {
142142
text-align: center !important;
143143
}
144144
@media (prefers-reduced-motion: no-preference) {
145145
.motion-safe\:hover\:text-center:hover {
146146
text-align: center !important;
147147
}
148148
}
149-
.dark .dark\:focus\:text-left:focus {
149+
:is(.dark .dark\:focus\:text-left:focus) {
150150
text-align: left !important;
151151
}
152152
@media (min-width: 768px) {

tests/important-selector.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,15 @@ crosscheck(() => {
134134
#app .group:hover .group-hover\:focus-within\:text-left:focus-within {
135135
text-align: left;
136136
}
137-
#app [dir='rtl'] .rtl\:active\:text-center:active {
137+
#app :is([dir='rtl'] .rtl\:active\:text-center:active) {
138138
text-align: center;
139139
}
140140
@media (prefers-reduced-motion: no-preference) {
141141
#app .motion-safe\:hover\:text-center:hover {
142142
text-align: center;
143143
}
144144
}
145-
#app .dark .dark\:focus\:text-left:focus {
145+
#app :is(.dark .dark\:focus\:text-left:focus) {
146146
text-align: left;
147147
}
148148
@media (min-width: 768px) {

tests/kitchen-sink.test.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ crosscheck(({ stable, oxide }) => {
303303
}
304304
.drop-empty-rules:hover,
305305
.group:hover .apply-group,
306-
.dark .apply-dark-mode {
306+
:is(.dark .apply-dark-mode) {
307307
font-weight: 700;
308308
}
309309
.apply-with-existing:hover {
@@ -338,7 +338,7 @@ crosscheck(({ stable, oxide }) => {
338338
.apply-order-b {
339339
margin: 1.5rem 1.25rem 1.25rem;
340340
}
341-
.dark .group:hover .apply-dark-group-example-a {
341+
:is(.dark .group:hover .apply-dark-group-example-a) {
342342
--tw-bg-opacity: 1;
343343
background-color: rgb(34 197 94 / var(--tw-bg-opacity));
344344
}
@@ -715,7 +715,7 @@ crosscheck(({ stable, oxide }) => {
715715
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
716716
}
717717
}
718-
.dark .dark\:custom-util {
718+
:is(.dark .dark\:custom-util) {
719719
background: #abcdef;
720720
}
721721
@media (min-width: 640px) {
@@ -762,7 +762,7 @@ crosscheck(({ stable, oxide }) => {
762762
transition-duration: 0.15s;
763763
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
764764
}
765-
.dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active {
765+
:is(.dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active) {
766766
background: #abcdef !important;
767767
}
768768
}
@@ -849,7 +849,7 @@ crosscheck(({ stable, oxide }) => {
849849
}
850850
.drop-empty-rules:hover,
851851
.group:hover .apply-group,
852-
.dark .apply-dark-mode {
852+
:is(.dark .apply-dark-mode) {
853853
font-weight: 700;
854854
}
855855
.apply-with-existing:hover {
@@ -883,7 +883,7 @@ crosscheck(({ stable, oxide }) => {
883883
.apply-order-b {
884884
margin: 1.5rem 1.25rem 1.25rem;
885885
}
886-
.dark .group:hover .apply-dark-group-example-a {
886+
:is(.dark .group:hover .apply-dark-group-example-a) {
887887
background-color: #22c55e;
888888
}
889889
@media (min-width: 640px) {
@@ -1250,7 +1250,7 @@ crosscheck(({ stable, oxide }) => {
12501250
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
12511251
}
12521252
}
1253-
.dark .dark\:custom-util {
1253+
:is(.dark .dark\:custom-util) {
12541254
background: #abcdef;
12551255
}
12561256
@media (min-width: 640px) {
@@ -1297,7 +1297,7 @@ crosscheck(({ stable, oxide }) => {
12971297
transition-duration: 0.15s;
12981298
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
12991299
}
1300-
.dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active {
1300+
:is(.dark .md\:dark\:motion-safe\:foo\:active\:custom-util:active) {
13011301
background: #abcdef !important;
13021302
}
13031303
}

tests/prefix.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ crosscheck(({ stable, oxide }) => {
128128
.custom-component {
129129
font-weight: 700;
130130
}
131-
.tw-dark .tw-group:hover .custom-component {
131+
:is(.tw-dark .tw-group:hover .custom-component) {
132132
font-weight: 400;
133133
}
134134
.tw--ml-4 {
@@ -155,19 +155,19 @@ crosscheck(({ stable, oxide }) => {
155155
.tw-group:hover .group-hover\:focus-within\:tw-text-left:focus-within {
156156
text-align: left;
157157
}
158-
[dir='rtl'] .rtl\:active\:tw-text-center:active {
158+
:is([dir='rtl'] .rtl\:active\:tw-text-center:active) {
159159
text-align: center;
160160
}
161161
@media (prefers-reduced-motion: no-preference) {
162162
.motion-safe\:hover\:tw-text-center:hover {
163163
text-align: center;
164164
}
165165
}
166-
.tw-dark .dark\:tw-bg-\[rgb\(255\,0\,0\)\] {
166+
:is(.tw-dark .dark\:tw-bg-\[rgb\(255\,0\,0\)\]) {
167167
--tw-bg-opacity: 1;
168168
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
169169
}
170-
.tw-dark .dark\:focus\:tw-text-left:focus {
170+
:is(.tw-dark .dark\:focus\:tw-text-left:focus) {
171171
text-align: left;
172172
}
173173
@media (min-width: 768px) {

tests/variants.oxide.test.css

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,8 @@
283283
.peer:disabled ~ .peer-disabled\:shadow-md,
284284
.peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:shadow-md,
285285
.peer:disabled:focus:hover ~ .peer-disabled\:peer-focus\:peer-hover\:first\:shadow-md:first-child,
286-
[dir="ltr"] .ltr\:shadow-md,
287-
[dir="rtl"] .rtl\:shadow-md {
286+
:is([dir='ltr'] .ltr\:shadow-md),
287+
:is([dir='rtl'] .rtl\:shadow-md) {
288288
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
289289
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
290290
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
@@ -318,9 +318,9 @@
318318
background-color: #fde047;
319319
}
320320
}
321-
.dark .dark\:shadow-md,
322-
.dark .group:disabled:focus:hover .dark\:group-disabled\:group-focus\:group-hover\:shadow-md,
323-
.dark .peer:disabled:focus:hover ~ .dark\:peer-disabled\:peer-focus\:peer-hover\:shadow-md {
321+
:is(.dark .dark\:shadow-md),
322+
:is(.dark .group:disabled:focus:hover .dark\:group-disabled\:group-focus\:group-hover\:shadow-md),
323+
:is(.dark .peer:disabled:focus:hover ~ .dark\:peer-disabled\:peer-focus\:peer-hover\:shadow-md) {
324324
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
325325
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
326326
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000),
@@ -361,7 +361,7 @@
361361
animation: 1s linear infinite spin;
362362
}
363363
.lg\:shadow-md,
364-
.dark .lg\:dark\:shadow-md {
364+
:is(.dark .lg\:dark\:shadow-md) {
365365
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
366366
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
367367
0 2px 4px -2px var(--tw-shadow-color);
@@ -371,7 +371,7 @@
371371
}
372372
@media (min-width: 1280px) {
373373
.xl\:shadow-md,
374-
.dark .xl\:dark\:disabled\:shadow-md:disabled {
374+
:is(.dark .xl\:dark\:disabled\:shadow-md:disabled) {
375375
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
376376
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
377377
0 2px 4px -2px var(--tw-shadow-color);
@@ -388,7 +388,7 @@
388388
var(--tw-shadow);
389389
}
390390
@media (prefers-reduced-motion: no-preference) {
391-
.dark .\32 xl\:dark\:motion-safe\:focus-within\:shadow-md:focus-within {
391+
:is(.dark .\32 xl\:dark\:motion-safe\:focus-within\:shadow-md:focus-within) {
392392
--tw-shadow: 0 4px 6px -1px #0000001a, 0 2px 4px -2px #0000001a;
393393
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color),
394394
0 2px 4px -2px var(--tw-shadow-color);
@@ -407,4 +407,3 @@
407407
background-color: #fde047;
408408
}
409409
}
410-

0 commit comments

Comments
 (0)