From de48a76b6da6ba6331dfa6d54dafcccd84ace04c Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 10 Jul 2024 15:52:05 +0200 Subject: [PATCH] Ensure opacity modifier with variables work with `color-mix()` (#13972) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ensure opacity modifier variables work as expected We use `color-mix()` in v4 which means that we can use this for the opacity modifier. One thing we do already is convert values such as `0.5` to `50%` because that's what the `color-mix()` function expects. However, if you use a variable like this: ```html
``` This currently generates: ```css .bg-red-500\/\[var\(--opacity\)\] { background-color: color-mix( in srgb, var(--color-red-500, #ef4444) var(--opacity), transparent ); } .\[--opacity\:0\.5\] { --opacity: 0.5; } ``` Which won't work because the opacity variable resolves to `0.5` instead of the expected`50%`. This commit fixes that by always ensuring that we use `* 100%`. - If you already had a percentage, we would have `calc(50% * 100%)` which is `50%`. - If we have `0.5` then we would have `calc(0.5 * 100%)` which is also `50%`. * wrap everything but percentages in `calc(… * 100%)` * use `else if` * update changelog --- CHANGELOG.md | 1 + packages/tailwindcss/src/utilities.test.ts | 15 ++++++++++++--- packages/tailwindcss/src/utilities.ts | 7 +++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb91cb4f7..eb3998061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Discard invalid classes such as `bg-red-[#000]` ([#13970](https://github.com/tailwindlabs/tailwindcss/pull/13970)) - Fix parsing body-less at-rule without terminating semicolon ([#13978](https://github.com/tailwindlabs/tailwindcss/pull/13978)) +- Ensure opacity modifier with variables work with `color-mix()` ([#13972](https://github.com/tailwindlabs/tailwindcss/pull/13972)) ## [4.0.0-alpha.17] - 2024-07-04 diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts index 3c8324d53..7e3e37347 100644 --- a/packages/tailwindcss/src/utilities.test.ts +++ b/packages/tailwindcss/src/utilities.test.ts @@ -7673,6 +7673,7 @@ test('bg', () => { 'bg-current/50', 'bg-current/[0.5]', 'bg-current/[50%]', + 'bg-current/[--bg-opacity]', 'bg-inherit', 'bg-transparent', 'bg-[#0088cc]', @@ -7792,7 +7793,15 @@ test('bg', () => { background-color: currentColor; } - .bg-current\\/50, .bg-current\\/\\[0\\.5\\], .bg-current\\/\\[50\\%\\] { + .bg-current\\/50 { + background-color: color-mix(in srgb, currentColor 50%, transparent); + } + + .bg-current\\/\\[--bg-opacity\\] { + background-color: color-mix(in srgb, currentColor calc(var(--bg-opacity) * 100%), transparent); + } + + .bg-current\\/\\[0\\.5\\], .bg-current\\/\\[50\\%\\] { background-color: color-mix(in srgb, currentColor 50%, transparent); } @@ -8091,11 +8100,11 @@ test('bg', () => { } .bg-current\\/custom { - background-color: color-mix(in srgb, currentColor var(--opacity-custom, var(--custom-opacity)), transparent); + background-color: color-mix(in srgb, currentColor calc(var(--opacity-custom, var(--custom-opacity)) * 100%), transparent); } .bg-current\\/half { - background-color: color-mix(in srgb, currentColor var(--opacity-half, .5), transparent); + background-color: color-mix(in srgb, currentColor calc(var(--opacity-half, .5) * 100%), transparent); }" `) }) diff --git a/packages/tailwindcss/src/utilities.ts b/packages/tailwindcss/src/utilities.ts index 58ad4c56d..8cc8d29bd 100644 --- a/packages/tailwindcss/src/utilities.ts +++ b/packages/tailwindcss/src/utilities.ts @@ -137,6 +137,13 @@ function withAlpha(value: string, alpha: string): string { alpha = `${alphaAsNumber * 100}%` } + // If the alpha value is a percentage, we can pass it directly to + // `color-mix()`. In any other case, e.g.: `var(…)`, `round(…)`, … we need to + // make sure it's a percentage. + else if (alpha[alpha.length - 1] !== '%') { + alpha = `calc(${alpha} * 100%)` + } + return `color-mix(in srgb, ${value} ${alpha}, transparent)` }