Skip to content

Commit 40a76e3

Browse files
Revert "Don't use color-mix(…) on currentColor (#17247)" and work around Preflight crash (#17306)
Closes #17194. This reverts commit d6d913e. The initial fix does breaks older versions of Chrome (where text won't render with a color for the placeholder at all anymore) and the usage of the _relative colors_ features also means it'll require a much newer version of Safari/Firefox/Chrome to work correctly. The implementation was also wrong as it always set alpha to the specific percent instead of applying it additively (note that this can be fixed with `calc(alpha * opacity)` though). Instead we decided to fix this by adding a `@supports` query to Preflight that only targets browsers that aren't affected by the crash. We currently use the following workaround: ```css /* Set the default placeholder color to a semi-transparent version of the current text color in browsers that do not crash when using `color-mix(…)` with `currentColor`. (#17194) */ @supports (not (-webkit-appearance: -apple-pay-button)) /* Not Safari */ or (contain-intrinsic-size: 1px) /* Safari 17+ */ { ::placeholder { color: color-mix(in oklab, currentColor 50%, transparent); } } ``` ## Test plan When testing the `color-mix(currentColor)` vs `oklab(from currentColor …)` we created the following support matrix. I'm extending it with _our fix_ which is the fix ended up using: | Browser | Version | `color-mix(… currentColor …)` | `oklab(from currentColor …)` | `@supports { color-mix(…) }` | | ------- | ------- | ----------------------------- | ---------------------------- | ------- | | Chrome | 111 | ❌ | ❌ | ❌ | | Chrome | 116 | ✅ | ❌ | ✅ | | Chrome | 131+ | ✅ | ✅ | ✅ | | Safari | 16.4 | 💥 | ❌ | ❌ | | Safari | 16.6+ | ✅ | ❌ | ❌ | | Safari | 18+ | ✅ | ✅ | ✅ | | Firefox | 128 | ✅ | ❌ | ✅ | | Firefox | 133 | ✅ | ✅ | ✅ | Note that on Safari 16, this change makes it so that the browser does not crash yet it still won't work either. That's because now the browser will fall back to the default placeholder color instead. We used the following play to test the fix: https://play.tailwindcss.com/RF1RYbZLKY
1 parent 3f313b4 commit 40a76e3

File tree

8 files changed

+61
-48
lines changed

8 files changed

+61
-48
lines changed

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424

2525
- Fix incorrect angle in `-bg-conic-*` utilities ([#17174](https://github.com/tailwindlabs/tailwindcss/pull/17174))
2626
- Fix `border-[12px_4px]` being interpreted as a `border-color` instead of a `border-width` ([#17248](https://github.com/tailwindlabs/tailwindcss/pull/17248))
27-
- Use the `oklab(…)` function when applying opacity to `currentColor` to work around a crash in Safari 16.4 and 16.5 ([#17247](https://github.com/tailwindlabs/tailwindcss/pull/17247))
27+
- Work around a crash in Safari 16.4 and 16.5 when using the default Preflight styles ([#17306](https://github.com/tailwindlabs/tailwindcss/pull/17306))
2828
- Pre-process `<template lang="…">` in Vue files ([#17252](https://github.com/tailwindlabs/tailwindcss/pull/17252))
29-
- Ensure that all CSS variables used by preflight are prefixed ([#17036](https://github.com/tailwindlabs/tailwindcss/pull/17036))
29+
- Ensure that all CSS variables used by Preflight are prefixed ([#17036](https://github.com/tailwindlabs/tailwindcss/pull/17036))
3030

3131
### Changed
3232

packages/@tailwindcss-postcss/src/__snapshots__/index.test.ts.snap

+6-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,12 @@ exports[`\`@import 'tailwindcss'\` is replaced with the generated CSS 1`] = `
161161
162162
::placeholder {
163163
opacity: 1;
164-
color: oklab(from currentColor l a b / 50%);
164+
}
165+
166+
@supports (not ((-webkit-appearance: -apple-pay-button))) or (contain-intrinsic-size: 1px) {
167+
::placeholder {
168+
color: color-mix(in oklab, currentColor 50%, transparent);
169+
}
165170
}
166171
167172
textarea {

packages/tailwindcss/preflight.css

+14-4
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,23 @@ textarea,
276276
}
277277

278278
/*
279-
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
280-
2. Set the default placeholder color to a semi-transparent version of the current text color. We use the `oklab(…)` function to work around an issue in Safari 16.4 and 16.5. (https://github.com/tailwindlabs/tailwindcss/issues/17194)
279+
Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
281280
*/
282281

283282
::placeholder {
284-
opacity: 1; /* 1 */
285-
color: oklab(from currentColor l a b / 50%); /* 2 */
283+
opacity: 1;
284+
}
285+
286+
/*
287+
Set the default placeholder color to a semi-transparent version of the current text color in browsers that do not
288+
crash when using `color-mix(…)` with `currentColor`. (https://github.com/tailwindlabs/tailwindcss/issues/17194)
289+
*/
290+
291+
@supports (not (-webkit-appearance: -apple-pay-button)) /* Not Safari */ or
292+
(contain-intrinsic-size: 1px) /* Safari 17+ */ {
293+
::placeholder {
294+
color: color-mix(in oklab, currentColor 50%, transparent);
295+
}
286296
}
287297

288298
/*

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,12 @@ exports[`compiling CSS > prefix all CSS variables inside preflight 1`] = `
250250
251251
::placeholder {
252252
opacity: 1;
253-
color: oklab(from currentColor l a b / 50%);
253+
}
254+
255+
@supports (not ((-webkit-appearance: -apple-pay-button))) or (contain-intrinsic-size: 1px) {
256+
::placeholder {
257+
color: color-mix(in oklab, currentColor 50%, transparent);
258+
}
254259
}
255260
256261
textarea {

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

+9-9
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ exports[`border-* 1`] = `
104104
}
105105
106106
.border-current\\/50 {
107-
border-color: oklab(from currentColor l a b / 50%);
107+
border-color: color-mix(in oklab, currentColor 50%, transparent);
108108
}
109109
110110
.border-inherit {
@@ -246,7 +246,7 @@ exports[`border-b-* 1`] = `
246246
}
247247
248248
.border-b-current\\/50 {
249-
border-bottom-color: oklab(from currentColor l a b / 50%);
249+
border-bottom-color: color-mix(in oklab, currentColor 50%, transparent);
250250
}
251251
252252
.border-b-inherit {
@@ -388,7 +388,7 @@ exports[`border-e-* 1`] = `
388388
}
389389
390390
.border-e-current\\/50 {
391-
border-inline-end-color: oklab(from currentColor l a b / 50%);
391+
border-inline-end-color: color-mix(in oklab, currentColor 50%, transparent);
392392
}
393393
394394
.border-e-inherit {
@@ -530,7 +530,7 @@ exports[`border-l-* 1`] = `
530530
}
531531
532532
.border-l-current\\/50 {
533-
border-left-color: oklab(from currentColor l a b / 50%);
533+
border-left-color: color-mix(in oklab, currentColor 50%, transparent);
534534
}
535535
536536
.border-l-inherit {
@@ -672,7 +672,7 @@ exports[`border-r-* 1`] = `
672672
}
673673
674674
.border-r-current\\/50 {
675-
border-right-color: oklab(from currentColor l a b / 50%);
675+
border-right-color: color-mix(in oklab, currentColor 50%, transparent);
676676
}
677677
678678
.border-r-inherit {
@@ -814,7 +814,7 @@ exports[`border-s-* 1`] = `
814814
}
815815
816816
.border-s-current\\/50 {
817-
border-inline-start-color: oklab(from currentColor l a b / 50%);
817+
border-inline-start-color: color-mix(in oklab, currentColor 50%, transparent);
818818
}
819819
820820
.border-s-inherit {
@@ -956,7 +956,7 @@ exports[`border-t-* 1`] = `
956956
}
957957
958958
.border-t-current\\/50 {
959-
border-top-color: oklab(from currentColor l a b / 50%);
959+
border-top-color: color-mix(in oklab, currentColor 50%, transparent);
960960
}
961961
962962
.border-t-inherit {
@@ -1098,7 +1098,7 @@ exports[`border-x-* 1`] = `
10981098
}
10991099
11001100
.border-x-current\\/50 {
1101-
border-inline-color: oklab(from currentColor l a b / 50%);
1101+
border-inline-color: color-mix(in oklab, currentColor 50%, transparent);
11021102
}
11031103
11041104
.border-x-inherit {
@@ -1240,7 +1240,7 @@ exports[`border-y-* 1`] = `
12401240
}
12411241
12421242
.border-y-current\\/50 {
1243-
border-block-color: oklab(from currentColor l a b / 50%);
1243+
border-block-color: color-mix(in oklab, currentColor 50%, transparent);
12441244
}
12451245
12461246
.border-y-inherit {

packages/tailwindcss/src/compat/plugin-api.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3860,7 +3860,7 @@ describe('matchUtilities()', () => {
38603860
}
38613861
38623862
.scrollbar-current\\/45 {
3863-
scrollbar-color: oklab(from currentColor l a b / 45%);
3863+
scrollbar-color: color-mix(in oklab, currentColor 45%, transparent);
38643864
}"
38653865
`)
38663866
})

packages/tailwindcss/src/utilities.test.ts

+23-23
Original file line numberDiff line numberDiff line change
@@ -8058,7 +8058,7 @@ test('accent', async () => {
80588058
}
80598059
80608060
.accent-current\\/50, .accent-current\\/\\[0\\.5\\], .accent-current\\/\\[50\\%\\] {
8061-
accent-color: oklab(from currentColor l a b / 50%);
8061+
accent-color: color-mix(in oklab, currentColor 50%, transparent);
80628062
}
80638063
80648064
.accent-inherit {
@@ -8173,7 +8173,7 @@ test('caret', async () => {
81738173
}
81748174
81758175
.caret-current\\/50, .caret-current\\/\\[0\\.5\\], .caret-current\\/\\[50\\%\\] {
8176-
caret-color: oklab(from currentColor l a b / 50%);
8176+
caret-color: color-mix(in oklab, currentColor 50%, transparent);
81778177
}
81788178
81798179
.caret-inherit {
@@ -8286,7 +8286,7 @@ test('divide-color', async () => {
82868286
}
82878287
82888288
:where(.divide-current\\/50 > :not(:last-child)), :where(.divide-current\\/\\[0\\.5\\] > :not(:last-child)), :where(.divide-current\\/\\[50\\%\\] > :not(:last-child)) {
8289-
border-color: oklab(from currentColor l a b / 50%);
8289+
border-color: color-mix(in oklab, currentColor 50%, transparent);
82908290
}
82918291
82928292
:where(.divide-inherit > :not(:last-child)) {
@@ -10248,11 +10248,11 @@ test('bg', async () => {
1024810248
}
1024910249
1025010250
.bg-current\\/50, .bg-current\\/\\[0\\.5\\], .bg-current\\/\\[50\\%\\] {
10251-
background-color: oklab(from currentColor l a b / 50%);
10251+
background-color: color-mix(in oklab, currentColor 50%, transparent);
1025210252
}
1025310253
1025410254
.bg-current\\/\\[var\\(--bg-opacity\\)\\] {
10255-
background-color: oklab(from currentColor l a b / var(--bg-opacity));
10255+
background-color: color-mix(in oklab, currentColor var(--bg-opacity), transparent);
1025610256
}
1025710257
1025810258
.bg-inherit {
@@ -10770,11 +10770,11 @@ test('bg', async () => {
1077010770
),
1077110771
).toMatchInlineSnapshot(`
1077210772
".bg-current\\/custom {
10773-
background-color: oklab(from currentColor l a b / var(--opacity-custom, var(--custom-opacity)));
10773+
background-color: color-mix(in oklab, currentColor var(--opacity-custom, var(--custom-opacity)), transparent);
1077410774
}
1077510775
1077610776
.bg-current\\/half {
10777-
background-color: oklab(from currentColor l a b / var(--opacity-half, .5));
10777+
background-color: color-mix(in oklab, currentColor var(--opacity-half, .5), transparent);
1077810778
}
1077910779
1078010780
.\\[color\\:red\\]\\/half {
@@ -10868,7 +10868,7 @@ test('from', async () => {
1086810868
}
1086910869
1087010870
.from-current\\/50, .from-current\\/\\[0\\.5\\], .from-current\\/\\[50\\%\\] {
10871-
--tw-gradient-from: oklab(from currentColor l a b / 50%);
10871+
--tw-gradient-from: color-mix(in oklab, currentColor 50%, transparent);
1087210872
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
1087310873
}
1087410874
@@ -11094,7 +11094,7 @@ test('via', async () => {
1109411094
}
1109511095
1109611096
.via-current\\/50, .via-current\\/\\[0\\.5\\], .via-current\\/\\[50\\%\\] {
11097-
--tw-gradient-via: oklab(from currentColor l a b / 50%);
11097+
--tw-gradient-via: color-mix(in oklab, currentColor 50%, transparent);
1109811098
--tw-gradient-via-stops: var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);
1109911099
--tw-gradient-stops: var(--tw-gradient-via-stops);
1110011100
}
@@ -11316,7 +11316,7 @@ test('to', async () => {
1131611316
}
1131711317
1131811318
.to-current\\/50, .to-current\\/\\[0\\.5\\], .to-current\\/\\[50\\%\\] {
11319-
--tw-gradient-to: oklab(from currentColor l a b / 50%);
11319+
--tw-gradient-to: color-mix(in oklab, currentColor 50%, transparent);
1132011320
--tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));
1132111321
}
1132211322
@@ -11843,7 +11843,7 @@ test('fill', async () => {
1184311843
}
1184411844
1184511845
.fill-current\\/50, .fill-current\\/\\[0\\.5\\], .fill-current\\/\\[50\\%\\] {
11846-
fill: oklab(from currentColor l a b / 50%);
11846+
fill: color-mix(in oklab, currentColor 50%, transparent);
1184711847
}
1184811848
1184911849
.fill-inherit {
@@ -11980,7 +11980,7 @@ test('stroke', async () => {
1198011980
}
1198111981
1198211982
.stroke-current\\/50, .stroke-current\\/\\[0\\.5\\], .stroke-current\\/\\[50\\%\\] {
11983-
stroke: oklab(from currentColor l a b / 50%);
11983+
stroke: color-mix(in oklab, currentColor 50%, transparent);
1198411984
}
1198511985
1198611986
.stroke-inherit {
@@ -12956,7 +12956,7 @@ test('placeholder', async () => {
1295612956
}
1295712957
1295812958
.placeholder-current\\/50::placeholder, .placeholder-current\\/\\[0\\.5\\]::placeholder, .placeholder-current\\/\\[50\\%\\]::placeholder {
12959-
color: oklab(from currentColor l a b / 50%);
12959+
color: color-mix(in oklab, currentColor 50%, transparent);
1296012960
}
1296112961
1296212962
.placeholder-inherit::placeholder {
@@ -13105,9 +13105,9 @@ test('decoration', async () => {
1310513105
}
1310613106
1310713107
.decoration-current\\/50, .decoration-current\\/\\[0\\.5\\], .decoration-current\\/\\[50\\%\\] {
13108-
-webkit-text-decoration-color: oklab(from currentColor l a b / 50%);
13109-
-webkit-text-decoration-color: oklab(from currentColor l a b / 50%);
13110-
text-decoration-color: oklab(from currentColor l a b / 50%);
13108+
-webkit-text-decoration-color: color-mix(in oklab, currentColor 50%, transparent);
13109+
-webkit-text-decoration-color: color-mix(in oklab, currentColor 50%, transparent);
13110+
text-decoration-color: color-mix(in oklab, currentColor 50%, transparent);
1311113111
}
1311213112
1311313113
.decoration-inherit {
@@ -14810,7 +14810,7 @@ test('outline', async () => {
1481014810
}
1481114811
1481214812
.outline-current\\/50, .outline-current\\/\\[0\\.5\\], .outline-current\\/\\[50\\%\\] {
14813-
outline-color: oklab(from currentColor l a b / 50%);
14813+
outline-color: color-mix(in oklab, currentColor 50%, transparent);
1481414814
}
1481514815
1481614816
.outline-inherit {
@@ -15260,7 +15260,7 @@ test('text', async () => {
1526015260
}
1526115261
1526215262
.text-current\\/50, .text-current\\/\\[0\\.5\\], .text-current\\/\\[50\\%\\] {
15263-
color: oklab(from currentColor l a b / 50%);
15263+
color: color-mix(in oklab, currentColor 50%, transparent);
1526415264
}
1526515265
1526615266
.text-inherit {
@@ -15429,7 +15429,7 @@ test('shadow', async () => {
1542915429
}
1543015430
1543115431
.shadow-current\\/50, .shadow-current\\/\\[0\\.5\\], .shadow-current\\/\\[50\\%\\] {
15432-
--tw-shadow-color: oklab(from currentColor l a b / 50%);
15432+
--tw-shadow-color: color-mix(in oklab, currentColor 50%, transparent);
1543315433
}
1543415434
1543515435
.shadow-inherit {
@@ -15651,7 +15651,7 @@ test('inset-shadow', async () => {
1565115651
}
1565215652
1565315653
.inset-shadow-current\\/50, .inset-shadow-current\\/\\[0\\.5\\], .inset-shadow-current\\/\\[50\\%\\] {
15654-
--tw-inset-shadow-color: oklab(from currentColor l a b / 50%);
15654+
--tw-inset-shadow-color: color-mix(in oklab, currentColor 50%, transparent);
1565515655
}
1565615656
1565715657
.inset-shadow-inherit {
@@ -15889,7 +15889,7 @@ test('ring', async () => {
1588915889
}
1589015890
1589115891
.ring-current\\/50, .ring-current\\/\\[0\\.5\\], .ring-current\\/\\[50\\%\\] {
15892-
--tw-ring-color: oklab(from currentColor l a b / 50%);
15892+
--tw-ring-color: color-mix(in oklab, currentColor 50%, transparent);
1589315893
}
1589415894
1589515895
.ring-inherit {
@@ -16228,7 +16228,7 @@ test('inset-ring', async () => {
1622816228
}
1622916229
1623016230
.inset-ring-current\\/50, .inset-ring-current\\/\\[0\\.5\\], .inset-ring-current\\/\\[50\\%\\] {
16231-
--tw-inset-ring-color: oklab(from currentColor l a b / 50%);
16231+
--tw-inset-ring-color: color-mix(in oklab, currentColor 50%, transparent);
1623216232
}
1623316233
1623416234
.inset-ring-inherit {
@@ -16472,7 +16472,7 @@ test('ring-offset', async () => {
1647216472
}
1647316473
1647416474
.ring-offset-current\\/50, .ring-offset-current\\/\\[0\\.5\\], .ring-offset-current\\/\\[50\\%\\] {
16475-
--tw-ring-offset-color: oklab(from currentColor l a b / 50%);
16475+
--tw-ring-offset-color: color-mix(in oklab, currentColor 50%, transparent);
1647616476
}
1647716477
1647816478
.ring-offset-inherit {

packages/tailwindcss/src/utilities.ts

-7
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,6 @@ export function withAlpha(value: string, alpha: string): string {
136136
alpha = `${alphaAsNumber * 100}%`
137137
}
138138

139-
// Use the `oklab(…)` function when applying alpha to `currentColor` to work
140-
// around a crash with Safari 16.4 and 16.5
141-
// https://github.com/tailwindlabs/tailwindcss/issues/17194
142-
if (value === 'currentColor') {
143-
return `oklab(from currentColor l a b / ${alpha})`
144-
}
145-
146139
return `color-mix(in oklab, ${value} ${alpha}, transparent)`
147140
}
148141

0 commit comments

Comments
 (0)