Skip to content

Commit

Permalink
Ensure CSS variable shorthand uses valid CSS variables (#15738)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
RobinMalfait authored Jan 27, 2025
1 parent 79541c9 commit 193fc60
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

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

## [4.0.0] - 2025-01-21

Expand Down
23 changes: 23 additions & 0 deletions packages/tailwindcss/src/candidate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,13 @@ it('should parse a utility with an arbitrary value with parens', () => {
`)
})

it('should not parse a utility with an arbitrary value with parens that does not start with --', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-(my-color)', { utilities })).toMatchInlineSnapshot(`[]`)
})

it('should parse a utility with an arbitrary value including a typehint', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])
Expand Down Expand Up @@ -616,6 +623,13 @@ it('should parse a utility with an arbitrary value with parens including a typeh
`)
})

it('should not parse a utility with an arbitrary value with parens including a typehint that does not start with --', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-(color:my-color)', { utilities })).toMatchInlineSnapshot(`[]`)
})

it('should parse a utility with an arbitrary value with parens and a fallback', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])
Expand Down Expand Up @@ -888,6 +902,8 @@ it('should not parse invalid arbitrary values in variants', () => {

'data-foo-(--value)/(number:--mod):flex',
'data-foo(--value)/(number:--mod):flex',

'data-(value):flex',
]) {
expect(run(candidate, { utilities, variants })).toEqual([])
}
Expand Down Expand Up @@ -945,6 +961,13 @@ it('should parse a utility with an implicit variable as the modifier using the s
`)
})

it('should not parse a utility with an implicit invalid variable as the modifier using the shorthand', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])

expect(run('bg-red-500/(value)', { utilities })).toMatchInlineSnapshot(`[]`)
})

it('should parse a utility with an implicit variable as the modifier that is important', () => {
let utilities = new Utilities()
utilities.functional('bg', () => [])
Expand Down
6 changes: 6 additions & 0 deletions packages/tailwindcss/src/candidate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,9 @@ function parseModifier(modifier: string): CandidateModifier | null {
// ^^
if (arbitraryValue.length === 0 || arbitraryValue.trim().length === 0) return null

// Arbitrary values must start with `--` since it represents a CSS variable.
if (arbitraryValue[0] !== '-' && arbitraryValue[1] !== '-') return null

return {
kind: 'arbitrary',
value: `var(${arbitraryValue})`,
Expand Down Expand Up @@ -651,6 +654,9 @@ export function parseVariant(variant: string, designSystem: DesignSystem): Varia
// ^^
if (arbitraryValue.length === 0 || arbitraryValue.trim().length === 0) return null

// Arbitrary values must start with `--` since it represents a CSS variable.
if (arbitraryValue[0] !== '-' && arbitraryValue[1] !== '-') return null

return {
kind: 'functional',
root,
Expand Down

0 comments on commit 193fc60

Please sign in to comment.