Skip to content

Commit 4489493

Browse files
authored
Fix inferring data type of border-[…] with multiple values (#17248)
This PR fixes an issue where arbitrary values such as `border-[12px_4px]` were incorrectly producing `border-color` instead of `border-width` values. To solve it, I extended the `<line-width>` check to make sure that every part of the value is a valid `<line-width>`. In order for a `line-width` to be valid, every part should be one of: 1. A keyword: `thin`, `medium`, `thick` 2. A length: `12px` 3. A number: `0` Fixes: #17221 # Test plan 1. Added test to verify this works 2. All existing tests pass
1 parent 1a88518 commit 4489493

File tree

4 files changed

+193
-1
lines changed

4 files changed

+193
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
### Fixed
2222

2323
- Fix incorrect angle in `-bg-conic-*` utilities ([#17174](https://github.com/tailwindlabs/tailwindcss/pull/17174))
24+
- Fix `border-[12px_4px]` being interpreted as a `border-color` instead of a `border-width` ([#17248](https://github.com/tailwindlabs/tailwindcss/pull/17248))
2425

2526
## [4.0.14] - 2025-03-13
2627

packages/tailwindcss/src/__snapshots__/utilities.test.ts.snap

+180
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,26 @@ exports[`border-* 1`] = `
3030
border-width: 123px;
3131
}
3232
33+
.border-\\[0_1\\] {
34+
border-style: var(--tw-border-style);
35+
border-width: 0 1px;
36+
}
37+
38+
.border-\\[0_2px_0_2px\\] {
39+
border-style: var(--tw-border-style);
40+
border-width: 0 2px;
41+
}
42+
3343
.border-\\[12px\\] {
3444
border-style: var(--tw-border-style);
3545
border-width: 12px;
3646
}
3747
48+
.border-\\[12px_8px\\] {
49+
border-style: var(--tw-border-style);
50+
border-width: 12px 8px;
51+
}
52+
3853
.border-\\[length\\:var\\(--my-width\\)\\], .border-\\[line-width\\:var\\(--my-width\\)\\] {
3954
border-style: var(--tw-border-style);
4055
border-width: var(--my-width);
@@ -55,6 +70,11 @@ exports[`border-* 1`] = `
5570
border-width: thin;
5671
}
5772
73+
.border-\\[thin_2px\\] {
74+
border-style: var(--tw-border-style);
75+
border-width: thin 2px;
76+
}
77+
5878
.border-\\[\\#0088cc\\] {
5979
border-color: #08c;
6080
}
@@ -152,11 +172,26 @@ exports[`border-b-* 1`] = `
152172
border-bottom-width: 123px;
153173
}
154174
175+
.border-b-\\[0_1\\] {
176+
border-bottom-style: var(--tw-border-style);
177+
border-bottom-width: 0 1;
178+
}
179+
180+
.border-b-\\[0_2px_0_2px\\] {
181+
border-bottom-style: var(--tw-border-style);
182+
border-bottom-width: 0 2px 0 2px;
183+
}
184+
155185
.border-b-\\[12px\\] {
156186
border-bottom-style: var(--tw-border-style);
157187
border-bottom-width: 12px;
158188
}
159189
190+
.border-b-\\[12px_8px\\] {
191+
border-bottom-style: var(--tw-border-style);
192+
border-bottom-width: 12px 8px;
193+
}
194+
160195
.border-b-\\[length\\:var\\(--my-width\\)\\], .border-b-\\[line-width\\:var\\(--my-width\\)\\] {
161196
border-bottom-style: var(--tw-border-style);
162197
border-bottom-width: var(--my-width);
@@ -177,6 +212,11 @@ exports[`border-b-* 1`] = `
177212
border-bottom-width: thin;
178213
}
179214
215+
.border-b-\\[thin_2px\\] {
216+
border-bottom-style: var(--tw-border-style);
217+
border-bottom-width: thin 2px;
218+
}
219+
180220
.border-b-\\[\\#0088cc\\] {
181221
border-bottom-color: #08c;
182222
}
@@ -274,11 +314,26 @@ exports[`border-e-* 1`] = `
274314
border-inline-end-width: 123px;
275315
}
276316
317+
.border-e-\\[0_1\\] {
318+
border-inline-end-style: var(--tw-border-style);
319+
border-inline-end-width: 0 1;
320+
}
321+
322+
.border-e-\\[0_2px_0_2px\\] {
323+
border-inline-end-style: var(--tw-border-style);
324+
border-inline-end-width: 0 2px 0 2px;
325+
}
326+
277327
.border-e-\\[12px\\] {
278328
border-inline-end-style: var(--tw-border-style);
279329
border-inline-end-width: 12px;
280330
}
281331
332+
.border-e-\\[12px_8px\\] {
333+
border-inline-end-style: var(--tw-border-style);
334+
border-inline-end-width: 12px 8px;
335+
}
336+
282337
.border-e-\\[length\\:var\\(--my-width\\)\\], .border-e-\\[line-width\\:var\\(--my-width\\)\\] {
283338
border-inline-end-style: var(--tw-border-style);
284339
border-inline-end-width: var(--my-width);
@@ -299,6 +354,11 @@ exports[`border-e-* 1`] = `
299354
border-inline-end-width: thin;
300355
}
301356
357+
.border-e-\\[thin_2px\\] {
358+
border-inline-end-style: var(--tw-border-style);
359+
border-inline-end-width: thin 2px;
360+
}
361+
302362
.border-e-\\[\\#0088cc\\] {
303363
border-inline-end-color: #08c;
304364
}
@@ -396,11 +456,26 @@ exports[`border-l-* 1`] = `
396456
border-left-width: 123px;
397457
}
398458
459+
.border-l-\\[0_1\\] {
460+
border-left-style: var(--tw-border-style);
461+
border-left-width: 0 1;
462+
}
463+
464+
.border-l-\\[0_2px_0_2px\\] {
465+
border-left-style: var(--tw-border-style);
466+
border-left-width: 0 2px 0 2px;
467+
}
468+
399469
.border-l-\\[12px\\] {
400470
border-left-style: var(--tw-border-style);
401471
border-left-width: 12px;
402472
}
403473
474+
.border-l-\\[12px_8px\\] {
475+
border-left-style: var(--tw-border-style);
476+
border-left-width: 12px 8px;
477+
}
478+
404479
.border-l-\\[length\\:var\\(--my-width\\)\\], .border-l-\\[line-width\\:var\\(--my-width\\)\\] {
405480
border-left-style: var(--tw-border-style);
406481
border-left-width: var(--my-width);
@@ -421,6 +496,11 @@ exports[`border-l-* 1`] = `
421496
border-left-width: thin;
422497
}
423498
499+
.border-l-\\[thin_2px\\] {
500+
border-left-style: var(--tw-border-style);
501+
border-left-width: thin 2px;
502+
}
503+
424504
.border-l-\\[\\#0088cc\\] {
425505
border-left-color: #08c;
426506
}
@@ -518,11 +598,26 @@ exports[`border-r-* 1`] = `
518598
border-right-width: 123px;
519599
}
520600
601+
.border-r-\\[0_1\\] {
602+
border-right-style: var(--tw-border-style);
603+
border-right-width: 0 1;
604+
}
605+
606+
.border-r-\\[0_2px_0_2px\\] {
607+
border-right-style: var(--tw-border-style);
608+
border-right-width: 0 2px 0 2px;
609+
}
610+
521611
.border-r-\\[12px\\] {
522612
border-right-style: var(--tw-border-style);
523613
border-right-width: 12px;
524614
}
525615
616+
.border-r-\\[12px_8px\\] {
617+
border-right-style: var(--tw-border-style);
618+
border-right-width: 12px 8px;
619+
}
620+
526621
.border-r-\\[length\\:var\\(--my-width\\)\\], .border-r-\\[line-width\\:var\\(--my-width\\)\\] {
527622
border-right-style: var(--tw-border-style);
528623
border-right-width: var(--my-width);
@@ -543,6 +638,11 @@ exports[`border-r-* 1`] = `
543638
border-right-width: thin;
544639
}
545640
641+
.border-r-\\[thin_2px\\] {
642+
border-right-style: var(--tw-border-style);
643+
border-right-width: thin 2px;
644+
}
645+
546646
.border-r-\\[\\#0088cc\\] {
547647
border-right-color: #08c;
548648
}
@@ -640,11 +740,26 @@ exports[`border-s-* 1`] = `
640740
border-inline-start-width: 123px;
641741
}
642742
743+
.border-s-\\[0_1\\] {
744+
border-inline-start-style: var(--tw-border-style);
745+
border-inline-start-width: 0 1;
746+
}
747+
748+
.border-s-\\[0_2px_0_2px\\] {
749+
border-inline-start-style: var(--tw-border-style);
750+
border-inline-start-width: 0 2px 0 2px;
751+
}
752+
643753
.border-s-\\[12px\\] {
644754
border-inline-start-style: var(--tw-border-style);
645755
border-inline-start-width: 12px;
646756
}
647757
758+
.border-s-\\[12px_8px\\] {
759+
border-inline-start-style: var(--tw-border-style);
760+
border-inline-start-width: 12px 8px;
761+
}
762+
648763
.border-s-\\[length\\:var\\(--my-width\\)\\], .border-s-\\[line-width\\:var\\(--my-width\\)\\] {
649764
border-inline-start-style: var(--tw-border-style);
650765
border-inline-start-width: var(--my-width);
@@ -665,6 +780,11 @@ exports[`border-s-* 1`] = `
665780
border-inline-start-width: thin;
666781
}
667782
783+
.border-s-\\[thin_2px\\] {
784+
border-inline-start-style: var(--tw-border-style);
785+
border-inline-start-width: thin 2px;
786+
}
787+
668788
.border-s-\\[\\#0088cc\\] {
669789
border-inline-start-color: #08c;
670790
}
@@ -762,11 +882,26 @@ exports[`border-t-* 1`] = `
762882
border-top-width: 123px;
763883
}
764884
885+
.border-t-\\[0_1\\] {
886+
border-top-style: var(--tw-border-style);
887+
border-top-width: 0 1;
888+
}
889+
890+
.border-t-\\[0_2px_0_2px\\] {
891+
border-top-style: var(--tw-border-style);
892+
border-top-width: 0 2px 0 2px;
893+
}
894+
765895
.border-t-\\[12px\\] {
766896
border-top-style: var(--tw-border-style);
767897
border-top-width: 12px;
768898
}
769899
900+
.border-t-\\[12px_8px\\] {
901+
border-top-style: var(--tw-border-style);
902+
border-top-width: 12px 8px;
903+
}
904+
770905
.border-t-\\[length\\:var\\(--my-width\\)\\], .border-t-\\[line-width\\:var\\(--my-width\\)\\] {
771906
border-top-style: var(--tw-border-style);
772907
border-top-width: var(--my-width);
@@ -787,6 +922,11 @@ exports[`border-t-* 1`] = `
787922
border-top-width: thin;
788923
}
789924
925+
.border-t-\\[thin_2px\\] {
926+
border-top-style: var(--tw-border-style);
927+
border-top-width: thin 2px;
928+
}
929+
790930
.border-t-\\[\\#0088cc\\] {
791931
border-top-color: #08c;
792932
}
@@ -884,11 +1024,26 @@ exports[`border-x-* 1`] = `
8841024
border-inline-width: 123px;
8851025
}
8861026
1027+
.border-x-\\[0_1\\] {
1028+
border-inline-style: var(--tw-border-style);
1029+
border-inline-width: 0 1px;
1030+
}
1031+
1032+
.border-x-\\[0_2px_0_2px\\] {
1033+
border-inline-style: var(--tw-border-style);
1034+
border-inline-width: 0 2px 0 2px;
1035+
}
1036+
8871037
.border-x-\\[12px\\] {
8881038
border-inline-style: var(--tw-border-style);
8891039
border-inline-width: 12px;
8901040
}
8911041
1042+
.border-x-\\[12px_8px\\] {
1043+
border-inline-style: var(--tw-border-style);
1044+
border-inline-width: 12px 8px;
1045+
}
1046+
8921047
.border-x-\\[length\\:var\\(--my-width\\)\\], .border-x-\\[line-width\\:var\\(--my-width\\)\\] {
8931048
border-inline-style: var(--tw-border-style);
8941049
border-inline-width: var(--my-width);
@@ -909,6 +1064,11 @@ exports[`border-x-* 1`] = `
9091064
border-inline-width: thin;
9101065
}
9111066
1067+
.border-x-\\[thin_2px\\] {
1068+
border-inline-style: var(--tw-border-style);
1069+
border-inline-width: thin 2px;
1070+
}
1071+
9121072
.border-x-\\[\\#0088cc\\] {
9131073
border-inline-color: #08c;
9141074
}
@@ -1006,11 +1166,26 @@ exports[`border-y-* 1`] = `
10061166
border-block-width: 123px;
10071167
}
10081168
1169+
.border-y-\\[0_1\\] {
1170+
border-block-style: var(--tw-border-style);
1171+
border-block-width: 0 1px;
1172+
}
1173+
1174+
.border-y-\\[0_2px_0_2px\\] {
1175+
border-block-style: var(--tw-border-style);
1176+
border-block-width: 0 2px 0 2px;
1177+
}
1178+
10091179
.border-y-\\[12px\\] {
10101180
border-block-style: var(--tw-border-style);
10111181
border-block-width: 12px;
10121182
}
10131183
1184+
.border-y-\\[12px_8px\\] {
1185+
border-block-style: var(--tw-border-style);
1186+
border-block-width: 12px 8px;
1187+
}
1188+
10141189
.border-y-\\[length\\:var\\(--my-width\\)\\], .border-y-\\[line-width\\:var\\(--my-width\\)\\] {
10151190
border-block-style: var(--tw-border-style);
10161191
border-block-width: var(--my-width);
@@ -1031,6 +1206,11 @@ exports[`border-y-* 1`] = `
10311206
border-block-width: thin;
10321207
}
10331208
1209+
.border-y-\\[thin_2px\\] {
1210+
border-block-style: var(--tw-border-style);
1211+
border-block-width: thin 2px;
1212+
}
1213+
10341214
.border-y-\\[\\#0088cc\\] {
10351215
border-block-color: #08c;
10361216
}

packages/tailwindcss/src/utilities.test.ts

+4
Original file line numberDiff line numberDiff line change
@@ -9881,6 +9881,10 @@ for (let prefix of prefixes) {
98819881
classes.push(`${prefix}-[medium]`)
98829882
classes.push(`${prefix}-[thick]`)
98839883
classes.push(`${prefix}-[12px]`)
9884+
classes.push(`${prefix}-[12px_8px]`)
9885+
classes.push(`${prefix}-[0_2px_0_2px]`)
9886+
classes.push(`${prefix}-[0_1]`)
9887+
classes.push(`${prefix}-[thin_2px]`)
98849888
classes.push(`${prefix}-[length:var(--my-width)]`)
98859889
classes.push(`${prefix}-[line-width:var(--my-width)]`)
98869890

packages/tailwindcss/src/utils/infer-data-type.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,14 @@ function isUrl(value: string): boolean {
6767
/* -------------------------------------------------------------------------- */
6868

6969
function isLineWidth(value: string): boolean {
70-
return value === 'thin' || value === 'medium' || value === 'thick'
70+
return segment(value, ' ').every(
71+
(value) =>
72+
isLength(value) ||
73+
isNumber(value) ||
74+
value === 'thin' ||
75+
value === 'medium' ||
76+
value === 'thick',
77+
)
7178
}
7279

7380
/* -------------------------------------------------------------------------- */

0 commit comments

Comments
 (0)