Skip to content

Commit 193fc60

Browse files
authored
Ensure CSS variable shorthand uses valid CSS variables (#15738)
This PR fixes an issue where we didn't always correctly validated invalid CSS variables when using the CSS variable shorthand syntax. This PR fixes that by ensuring we start with `--`. We can't validate that the variable exists at runtime, but we can validate if it looks like a valid CSS variable. We can go a step further by validating if the CSS variable is valid syntax (e.g.: all characters are valid), but we can introduce this if this is causing actual issues in projects. ``` p-(a-b) ``` Used to compile to: ```css .p-\(a-b\) { padding: var(a-b); } ``` But not anymore.
1 parent 79541c9 commit 193fc60

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

CHANGELOG.md

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

1212
- Remove invalid `min-w/h-none` utilities ([#15845](https://github.com/tailwindlabs/tailwindcss/pull/15845))
13+
- Ensure CSS variable shorthand uses valid CSS variables ([#15738](https://github.com/tailwindlabs/tailwindcss/pull/15738))
1314

1415
## [4.0.0] - 2025-01-21
1516

packages/tailwindcss/src/candidate.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,13 @@ it('should parse a utility with an arbitrary value with parens', () => {
570570
`)
571571
})
572572

573+
it('should not parse a utility with an arbitrary value with parens that does not start with --', () => {
574+
let utilities = new Utilities()
575+
utilities.functional('bg', () => [])
576+
577+
expect(run('bg-(my-color)', { utilities })).toMatchInlineSnapshot(`[]`)
578+
})
579+
573580
it('should parse a utility with an arbitrary value including a typehint', () => {
574581
let utilities = new Utilities()
575582
utilities.functional('bg', () => [])
@@ -616,6 +623,13 @@ it('should parse a utility with an arbitrary value with parens including a typeh
616623
`)
617624
})
618625

626+
it('should not parse a utility with an arbitrary value with parens including a typehint that does not start with --', () => {
627+
let utilities = new Utilities()
628+
utilities.functional('bg', () => [])
629+
630+
expect(run('bg-(color:my-color)', { utilities })).toMatchInlineSnapshot(`[]`)
631+
})
632+
619633
it('should parse a utility with an arbitrary value with parens and a fallback', () => {
620634
let utilities = new Utilities()
621635
utilities.functional('bg', () => [])
@@ -888,6 +902,8 @@ it('should not parse invalid arbitrary values in variants', () => {
888902

889903
'data-foo-(--value)/(number:--mod):flex',
890904
'data-foo(--value)/(number:--mod):flex',
905+
906+
'data-(value):flex',
891907
]) {
892908
expect(run(candidate, { utilities, variants })).toEqual([])
893909
}
@@ -945,6 +961,13 @@ it('should parse a utility with an implicit variable as the modifier using the s
945961
`)
946962
})
947963

964+
it('should not parse a utility with an implicit invalid variable as the modifier using the shorthand', () => {
965+
let utilities = new Utilities()
966+
utilities.functional('bg', () => [])
967+
968+
expect(run('bg-red-500/(value)', { utilities })).toMatchInlineSnapshot(`[]`)
969+
})
970+
948971
it('should parse a utility with an implicit variable as the modifier that is important', () => {
949972
let utilities = new Utilities()
950973
utilities.functional('bg', () => [])

packages/tailwindcss/src/candidate.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,9 @@ function parseModifier(modifier: string): CandidateModifier | null {
517517
// ^^
518518
if (arbitraryValue.length === 0 || arbitraryValue.trim().length === 0) return null
519519

520+
// Arbitrary values must start with `--` since it represents a CSS variable.
521+
if (arbitraryValue[0] !== '-' && arbitraryValue[1] !== '-') return null
522+
520523
return {
521524
kind: 'arbitrary',
522525
value: `var(${arbitraryValue})`,
@@ -651,6 +654,9 @@ export function parseVariant(variant: string, designSystem: DesignSystem): Varia
651654
// ^^
652655
if (arbitraryValue.length === 0 || arbitraryValue.trim().length === 0) return null
653656

657+
// Arbitrary values must start with `--` since it represents a CSS variable.
658+
if (arbitraryValue[0] !== '-' && arbitraryValue[1] !== '-') return null
659+
654660
return {
655661
kind: 'functional',
656662
root,

0 commit comments

Comments
 (0)