Skip to content

Commit bee271c

Browse files
committed
implemented workaround using atMax and added documentation in README.md
1 parent 8932106 commit bee271c

File tree

3 files changed

+351
-2
lines changed

3 files changed

+351
-2
lines changed

README.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,26 @@ Start by marking an element as a container using the `@container` class, and the
3939

4040
By default we provide [container sizes](#configuration) from `@xs` (`20rem`) to `@7xl` (`80rem`).
4141

42+
In case of `max-width` container queries:
43+
44+
```html
45+
<div class="@container">
46+
<div class="@max-lg:underline">
47+
<!-- This text will be underlined when the container is larger than `32rem` -->
48+
</div>
49+
</div>
50+
```
51+
52+
or alternatively there is an `atMax` version:
53+
54+
```html
55+
<div class="@container">
56+
<div class="atMax-lg:underline">
57+
<!-- This text will be underlined when the container is larger than `32rem` -->
58+
</div>
59+
</div>
60+
```
61+
4262
### Named containers
4363

4464
You can optionally name containers using a `@container/{name}` class, and then include that name in the container variants using classes like `@lg/{name}:underline`:
@@ -52,6 +72,26 @@ You can optionally name containers using a `@container/{name}` class, and then i
5272
</div>
5373
```
5474

75+
In case of `max-width` container queries:
76+
77+
```html
78+
<div class="@container/main">
79+
<div class="@max-lg/main:underline">
80+
<!-- This text will be underlined when the container is larger than `32rem` -->
81+
</div>
82+
</div>
83+
```
84+
85+
or alternatively the `atMax` version:
86+
87+
```html
88+
<div class="@container/main">
89+
<div class="atMax-lg/main:underline">
90+
<!-- This text will be underlined when the container is larger than `32rem` -->
91+
</div>
92+
</div>
93+
```
94+
5595
### Arbitrary container sizes
5696

5797
In addition to using one of the [container sizes](#configuration) provided by default, you can also create one-off sizes using any arbitrary value:
@@ -64,6 +104,56 @@ In addition to using one of the [container sizes](#configuration) provided by de
64104
</div>
65105
```
66106

107+
In case of `max-width` container queries:
108+
109+
```html
110+
<div class="@container">
111+
<div class="@max-[17.5rem]:underline">
112+
<!-- This text will be underlined when the container is larger than `32rem` -->
113+
</div>
114+
</div>
115+
```
116+
117+
or alternatively the `atMax` version:
118+
119+
```html
120+
<div class="@container">
121+
<div class="atMax-[17.5rem]:underline">
122+
<!-- This text will be underlined when the container is larger than `32rem` -->
123+
</div>
124+
</div>
125+
```
126+
127+
### Combining named containers and arbitrary container sizes
128+
129+
You can combine both [named containers](#named-containers) and
130+
[arbitrary container sizes](#arbitrary-container-sizes) this way:
131+
132+
```html
133+
<div class="@container/main">
134+
<div class="@[17.5rem]/main:underline"></div>
135+
<!-- This text will be underlined when the container is larger than `17.5rem` -->
136+
</div>
137+
</div>
138+
```
139+
140+
In case of `max-width` container queries only the `atMax` version is working
141+
because to support extraction of `@max-[17.5rem]/main:underline` by the default
142+
extractor of Tailwind CSS its regular expressions would need to be updated
143+
(or a custom extractor could be used but that is really an advanced topic since it
144+
overrides the default one which does really an excellent job to extract class name
145+
candidates from anywhere).
146+
147+
```html
148+
<div class="@container/main">
149+
<div class="atMax-[17.5rem]/main:underline">
150+
<!-- This text will be underlined when the container is larger than `32rem` -->
151+
</div>
152+
</div>
153+
```
154+
155+
156+
67157
### Removing a container
68158

69159
To stop an element from acting as a container, use the `@container-normal` class.

src/index.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@ export = plugin(
5757
return aLabel.localeCompare(zLabel, 'en', { numeric: true })
5858
}
5959

60+
matchVariant(
61+
'@',
62+
(value = '', { modifier }) => {
63+
let parsed = parseValue(value)
64+
65+
return parsed !== null ? `@container ${modifier ?? ''} (min-width: ${value})` : []
66+
},
67+
{
68+
values,
69+
sort,
70+
}
71+
)
72+
6073
matchVariant(
6174
'@max',
6275
(value = '', { modifier }) => {
@@ -71,11 +84,11 @@ export = plugin(
7184
)
7285

7386
matchVariant(
74-
'@',
87+
'atMax',
7588
(value = '', { modifier }) => {
7689
let parsed = parseValue(value)
7790

78-
return parsed !== null ? `@container ${modifier ?? ''} (min-width: ${value})` : []
91+
return parsed !== null ? `@container ${modifier ?? ''} (max-width: ${value})` : []
7992
},
8093
{
8194
values,

tests/index.test.ts

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,3 +489,249 @@ it('should be possible to use default max-width container queries', () => {
489489
`)
490490
})
491491
})
492+
493+
it('atMax max-width container queries', () => {
494+
let config = {
495+
content: [
496+
{
497+
raw: html`
498+
<div
499+
class="@container @container-normal @container/sidebar @container-normal/sidebar @container-[size]/sidebar"
500+
>
501+
<div class="atMax-md:underline"></div>
502+
<div class="atMax-md/container1:underline"></div>
503+
<div class="atMax-md/container2:underline"></div>
504+
<div class="atMax-md/container10:underline"></div>
505+
506+
<div class="atMax-sm:underline"></div>
507+
<div class="atMax-sm/container1:underline"></div>
508+
<div class="atMax-sm/container2:underline"></div>
509+
<div class="atMax-sm/container10:underline"></div>
510+
511+
<div class="atMax-lg:underline"></div>
512+
<div class="atMax-lg/container1:underline"></div>
513+
<div class="atMax-lg/container2:underline"></div>
514+
<div class="atMax-lg/container10:underline"></div>
515+
<div class="atMax-[1024px]:underline"></div>
516+
<div class="atMax-[1024px]/container1:underline"></div>
517+
<div class="atMax-[1024]/container1:underline"></div>
518+
519+
<div class="atMax-[312px]:underline"></div>
520+
<div class="atMax-[200rem]:underline"></div>
521+
<div class="atMax-[123px]:underline"></div>
522+
</div>
523+
`,
524+
},
525+
],
526+
theme: {
527+
containers: {
528+
sm: '320px',
529+
md: '768px',
530+
lg: '1024px',
531+
},
532+
},
533+
corePlugins: { preflight: false },
534+
}
535+
536+
let input = css`
537+
@tailwind utilities;
538+
`
539+
540+
return run(input, config).then((result) => {
541+
expect(result.css).toMatchFormattedCss(css`
542+
.\@container {
543+
container-type: inline-size;
544+
}
545+
546+
.\@container-normal {
547+
container-type: normal;
548+
}
549+
550+
.\@container\/sidebar {
551+
container-type: inline-size;
552+
container-name: sidebar;
553+
}
554+
555+
.\@container-normal\/sidebar {
556+
container-type: normal;
557+
container-name: sidebar;
558+
}
559+
560+
@container (max-width: 123px) {
561+
.atMax-\[123px\]\:underline {
562+
text-decoration-line: underline;
563+
}
564+
}
565+
566+
@container (max-width: 200rem) {
567+
.atMax-\[200rem\]\:underline {
568+
text-decoration-line: underline;
569+
}
570+
}
571+
572+
@container (max-width: 312px) {
573+
.atMax-\[312px\]\:underline {
574+
text-decoration-line: underline;
575+
}
576+
}
577+
578+
@container container1 (max-width: 320px) {
579+
.atMax-sm\/container1\:underline {
580+
text-decoration-line: underline;
581+
}
582+
}
583+
584+
@container container2 (max-width: 320px) {
585+
.atMax-sm\/container2\:underline {
586+
text-decoration-line: underline;
587+
}
588+
}
589+
590+
@container container10 (max-width: 320px) {
591+
.atMax-sm\/container10\:underline {
592+
text-decoration-line: underline;
593+
}
594+
}
595+
596+
@container (max-width: 320px) {
597+
.atMax-sm\:underline {
598+
text-decoration-line: underline;
599+
}
600+
}
601+
602+
@container container1 (max-width: 768px) {
603+
.atMax-md\/container1\:underline {
604+
text-decoration-line: underline;
605+
}
606+
}
607+
608+
@container container2 (max-width: 768px) {
609+
.atMax-md\/container2\:underline {
610+
text-decoration-line: underline;
611+
}
612+
}
613+
614+
@container container10 (max-width: 768px) {
615+
.atMax-md\/container10\:underline {
616+
text-decoration-line: underline;
617+
}
618+
}
619+
620+
@container (max-width: 768px) {
621+
.atMax-md\:underline {
622+
text-decoration-line: underline;
623+
}
624+
}
625+
626+
@container container1 (max-width: 1024px) {
627+
.atMax-lg\/container1\:underline {
628+
text-decoration-line: underline;
629+
}
630+
631+
.atMax-\[1024px\]\/container1\:underline {
632+
text-decoration-line: underline;
633+
}
634+
}
635+
636+
@container container2 (max-width: 1024px) {
637+
.atMax-lg\/container2\:underline {
638+
text-decoration-line: underline;
639+
}
640+
}
641+
642+
@container container10 (max-width: 1024px) {
643+
.atMax-lg\/container10\:underline {
644+
text-decoration-line: underline;
645+
}
646+
}
647+
648+
@container (max-width: 1024px) {
649+
.atMax-lg\:underline {
650+
text-decoration-line: underline;
651+
}
652+
.atMax-\[1024px\]\:underline {
653+
text-decoration-line: underline;
654+
}
655+
}
656+
`)
657+
})
658+
})
659+
660+
it('should be possible to use default atMax max-width container queries', () => {
661+
let config = {
662+
content: [
663+
{
664+
raw: html`
665+
<div>
666+
<div class="atMax-md:underline"></div>
667+
<div class="atMax-lg:underline"></div>
668+
<div class="atMax-sm:underline"></div>
669+
<div class="atMax-xs:underline"></div>
670+
<div class="atMax-7xl:underline"></div>
671+
<div class="atMax-6xl:underline"></div>
672+
<div class="atMax-3xl:underline"></div>
673+
<div class="atMax-5xl:underline"></div>
674+
</div>
675+
`,
676+
},
677+
],
678+
theme: {},
679+
corePlugins: { preflight: false },
680+
}
681+
682+
let input = css`
683+
@tailwind utilities;
684+
`
685+
686+
return run(input, config).then((result) => {
687+
expect(result.css).toMatchFormattedCss(css`
688+
@container (max-width: 20rem) {
689+
.atMax-xs\:underline {
690+
text-decoration-line: underline;
691+
}
692+
}
693+
694+
@container (max-width: 24rem) {
695+
.atMax-sm\:underline {
696+
text-decoration-line: underline;
697+
}
698+
}
699+
700+
@container (max-width: 28rem) {
701+
.atMax-md\:underline {
702+
text-decoration-line: underline;
703+
}
704+
}
705+
706+
@container (max-width: 32rem) {
707+
.atMax-lg\:underline {
708+
text-decoration-line: underline;
709+
}
710+
}
711+
712+
@container (max-width: 48rem) {
713+
.atMax-3xl\:underline {
714+
text-decoration-line: underline;
715+
}
716+
}
717+
718+
@container (max-width: 64rem) {
719+
.atMax-5xl\:underline {
720+
text-decoration-line: underline;
721+
}
722+
}
723+
724+
@container (max-width: 72rem) {
725+
.atMax-6xl\:underline {
726+
text-decoration-line: underline;
727+
}
728+
}
729+
730+
@container (max-width: 80rem) {
731+
.atMax-7xl\:underline {
732+
text-decoration-line: underline;
733+
}
734+
}
735+
`)
736+
})
737+
})

0 commit comments

Comments
 (0)