Repository: tailwindlabs/tailwindcss

Problem statement:
Gradients do not work in Firefox in v4.0.0-alpha.16, potentially caused by special `@supports (-moz-orient: inline)` selector
### Discussed in https://github.com/tailwindlabs/tailwindcss/discussions/13941 , since it is reproducible in tailwind play, I think it is indeed a bug and created the issue for it.

**What version of Tailwind CSS are you using?**

v4.0.0-alpha.16

**What build tool (or framework if it abstracts the build tool) are you using?**

`vite` v5.3.3, `@tailwindcss/vite` v4.0.0-alpha.16

**What version of Node.js are you using?**

v22.4.0

**What browser are you using?**

Chrome, Opera, Edge, Firefox

**What operating system are you using?**

Windows

**Reproduction URL**

See the following example in Chrome vs. Firefox:
https://play.tailwindcss.com/ASf2fh5fiH

In Chrome it works but in Firefox the gradient is not displayed.
While I applied layers in the example, the same issue occurs if I just `@import 'tailwindcss';` instead:
https://play.tailwindcss.com/MPNPWOGHdL?file=css

**Describe your issue**

<div type='discussions-op-text'>

<sup>Originally posted by **sceee** July  3, 2024</sup>
Gradients do not seem to work in Firefox in `v4.0.0-alpha.16` whereas they work in Chrome.

See the following example in Chrome vs. Firefox:
https://play.tailwindcss.com/ASf2fh5fiH

In Chrome it works but in Firefox the gradient is not displayed.
While I applied layers in the example, the same issue occurs if I just `@import 'tailwindcss';` instead:
https://play.tailwindcss.com/MPNPWOGHdL?file=css

It seems in Firefox there is a special ruling applied to the element based on the `@supports (-moz-orient: inline)` selector. It seems this is injected here: https://github.com/tailwindlabs/tailwindcss/blob/62de02a37946c48c5fa6cdb800173b54198ebb9b/packages/tailwindcss/src/ast.ts#L202
```css
@supports (-moz-orient: inline) {
  @layer base {
    *, ::before, ::after, ::backdrop {
      --tw-gradient-from: #0000;
      --tw-gradient-to: #0000;
      --tw-gradient-via: transparent;
      --tw-gradient-stops: ;
      --tw-gradient-via-stops: ;
      --tw-gradient-from-position: 0%;
      --tw-gradient-via-position: 50%;
      --tw-gradient-to-position: 100%;
    }
  }
}
```

According to the Browser dev tools, `--tw-gradient-from`, `--tw-gradient-to` and `--tw-gradient-stops` are overwritten (and therefore not applied) but `--tw-gradient-via-stops` is set to [nothing] which seems to cause this issue.

If I disable the `--tw-gradient-via-stops` setting from this rule in the dev tools, the gradient also appears in Firefox.

Is this a known issue or shall I open a issue for this?</div>


Hints:

Patch:
diff --git a/packages/tailwindcss/playwright.config.ts b/packages/tailwindcss/playwright.config.ts
--- a/packages/tailwindcss/playwright.config.ts
+++ b/packages/tailwindcss/playwright.config.ts
@@ -36,11 +36,14 @@ export default defineConfig({
       name: 'chromium',
       use: { ...devices['Desktop Chrome'] },
     },
-
     {
       name: 'webkit',
       use: { ...devices['Desktop Safari'] },
     },
+    {
+      name: 'firefox',
+      use: { ...devices['Desktop Firefox'] },
+    },
 
     /* Test against mobile viewports. */
     // {
diff --git a/packages/tailwindcss/src/ast.ts b/packages/tailwindcss/src/ast.ts
--- a/packages/tailwindcss/src/ast.ts
+++ b/packages/tailwindcss/src/ast.ts
@@ -148,9 +148,9 @@ export function toCss(ast: AstNode[]) {
         }
 
         if (inherits) {
-          propertyFallbacksRoot.push(decl(property, initialValue ?? ' '))
+          propertyFallbacksRoot.push(decl(property, initialValue ?? 'initial'))
         } else {
-          propertyFallbacksUniversal.push(decl(property, initialValue ?? ' '))
+          propertyFallbacksUniversal.push(decl(property, initialValue ?? 'initial'))
         }
 
         seenAtProperties.add(node.selector)


Test patch:
diff --git a/packages/tailwindcss/src/__snapshots__/index.test.ts.snap b/packages/tailwindcss/src/__snapshots__/index.test.ts.snap
--- a/packages/tailwindcss/src/__snapshots__/index.test.ts.snap
+++ b/packages/tailwindcss/src/__snapshots__/index.test.ts.snap
@@ -431,11 +431,11 @@ exports[`compiling CSS > \`@tailwind utilities\` is replaced by utilities using
       --tw-shadow-colored: 0 0 #0000;
       --tw-inset-shadow: 0 0 #0000;
       --tw-inset-shadow-colored: 0 0 #0000;
-      --tw-ring-color: ;
+      --tw-ring-color: initial;
       --tw-ring-shadow: 0 0 #0000;
-      --tw-inset-ring-color: ;
+      --tw-inset-ring-color: initial;
       --tw-inset-ring-shadow: 0 0 #0000;
-      --tw-ring-inset: ;
+      --tw-ring-inset: initial;
       --tw-ring-offset-width: 0px;
       --tw-ring-offset-color: #fff;
       --tw-ring-offset-shadow: 0 0 #0000;
diff --git a/packages/tailwindcss/src/utilities.test.ts b/packages/tailwindcss/src/utilities.test.ts
--- a/packages/tailwindcss/src/utilities.test.ts
+++ b/packages/tailwindcss/src/utilities.test.ts
@@ -3824,9 +3824,9 @@ test('touch-pan', () => {
     @supports (-moz-orient: inline) {
       @layer base {
         *, :before, :after, ::backdrop {
-          --tw-pan-x: ;
-          --tw-pan-y: ;
-          --tw-pinch-zoom: ;
+          --tw-pan-x: initial;
+          --tw-pan-y: initial;
+          --tw-pinch-zoom: initial;
         }
       }
     }
@@ -3868,9 +3868,9 @@ test('touch-pinch-zoom', () => {
     @supports (-moz-orient: inline) {
       @layer base {
         *, :before, :after, ::backdrop {
-          --tw-pan-x: ;
-          --tw-pan-y: ;
-          --tw-pinch-zoom: ;
+          --tw-pan-x: initial;
+          --tw-pan-y: initial;
+          --tw-pinch-zoom: initial;
         }
       }
     }
@@ -8239,8 +8239,8 @@ test('from', () => {
           --tw-gradient-from: #0000;
           --tw-gradient-to: #0000;
           --tw-gradient-via: transparent;
-          --tw-gradient-stops: ;
-          --tw-gradient-via-stops: ;
+          --tw-gradient-stops: initial;
+          --tw-gradient-via-stops: initial;
           --tw-gradient-from-position: 0%;
           --tw-gradient-via-position: 50%;
           --tw-gradient-to-position: 100%;
@@ -8476,8 +8476,8 @@ test('via', () => {
           --tw-gradient-from: #0000;
           --tw-gradient-to: #0000;
           --tw-gradient-via: transparent;
-          --tw-gradient-stops: ;
-          --tw-gradient-via-stops: ;
+          --tw-gradient-stops: initial;
+          --tw-gradient-via-stops: initial;
           --tw-gradient-from-position: 0%;
           --tw-gradient-via-position: 50%;
           --tw-gradient-to-position: 100%;
@@ -8701,8 +8701,8 @@ test('to', () => {
           --tw-gradient-from: #0000;
           --tw-gradient-to: #0000;
           --tw-gradient-via: transparent;
-          --tw-gradient-stops: ;
-          --tw-gradient-via-stops: ;
+          --tw-gradient-stops: initial;
+          --tw-gradient-via-stops: initial;
           --tw-gradient-from-position: 0%;
           --tw-gradient-via-position: 50%;
           --tw-gradient-to-position: 100%;
@@ -10477,15 +10477,15 @@ test('filter', () => {
     @supports (-moz-orient: inline) {
       @layer base {
         *, :before, :after, ::backdrop {
-          --tw-blur: ;
-          --tw-brightness: ;
-          --tw-contrast: ;
-          --tw-grayscale: ;
-          --tw-hue-rotate: ;
-          --tw-invert: ;
-          --tw-opacity: ;
-          --tw-saturate: ;
-          --tw-sepia: ;
+          --tw-blur: initial;
+          --tw-brightness: initial;
+          --tw-contrast: initial;
+          --tw-grayscale: initial;
+          --tw-hue-rotate: initial;
+          --tw-invert: initial;
+          --tw-opacity: initial;
+          --tw-saturate: initial;
+          --tw-sepia: initial;
         }
       }
     }
@@ -10787,15 +10787,15 @@ test('backdrop-filter', () => {
     @supports (-moz-orient: inline) {
       @layer base {
         *, :before, :after, ::backdrop {
-          --tw-backdrop-blur: ;
-          --tw-backdrop-brightness: ;
-          --tw-backdrop-contrast: ;
-          --tw-backdrop-grayscale: ;
-          --tw-backdrop-hue-rotate: ;
-          --tw-backdrop-invert: ;
-          --tw-backdrop-opacity: ;
-          --tw-backdrop-saturate: ;
-          --tw-backdrop-sepia: ;
+          --tw-backdrop-blur: initial;
+          --tw-backdrop-brightness: initial;
+          --tw-backdrop-contrast: initial;
+          --tw-backdrop-grayscale: initial;
+          --tw-backdrop-hue-rotate: initial;
+          --tw-backdrop-invert: initial;
+          --tw-backdrop-opacity: initial;
+          --tw-backdrop-saturate: initial;
+          --tw-backdrop-sepia: initial;
         }
       }
     }
@@ -11157,10 +11157,10 @@ test('contain', () => {
     @supports (-moz-orient: inline) {
       @layer base {
         *, :before, :after, ::backdrop {
-          --tw-contain-size: ;
-          --tw-contain-layout: ;
-          --tw-contain-paint: ;
-          --tw-contain-style: ;
+          --tw-contain-size: initial;
+          --tw-contain-layout: initial;
+          --tw-contain-paint: initial;
+          --tw-contain-style: initial;
         }
       }
     }
@@ -11378,11 +11378,11 @@ test('font-variant-numeric', () => {
     @supports (-moz-orient: inline) {
       @layer base {
         *, :before, :after, ::backdrop {
-          --tw-ordinal: ;
-          --tw-slashed-zero: ;
-          --tw-numeric-figure: ;
-          --tw-numeric-spacing: ;
-          --tw-numeric-fraction: ;
+          --tw-ordinal: initial;
+          --tw-slashed-zero: initial;
+          --tw-numeric-figure: initial;
+          --tw-numeric-spacing: initial;
+          --tw-numeric-fraction: initial;
         }
       }
     }
@@ -12104,11 +12104,11 @@ test('shadow', () => {
           --tw-shadow-colored: 0 0 #0000;
           --tw-inset-shadow: 0 0 #0000;
           --tw-inset-shadow-colored: 0 0 #0000;
-          --tw-ring-color: ;
+          --tw-ring-color: initial;
           --tw-ring-shadow: 0 0 #0000;
-          --tw-inset-ring-color: ;
+          --tw-inset-ring-color: initial;
           --tw-inset-ring-shadow: 0 0 #0000;
-          --tw-ring-inset: ;
+          --tw-ring-inset: initial;
           --tw-ring-offset-width: 0px;
           --tw-ring-offset-color: #fff;
           --tw-ring-offset-shadow: 0 0 #0000;
@@ -12356,11 +12356,11 @@ test('inset-shadow', () => {
           --tw-shadow-colored: 0 0 #0000;
           --tw-inset-shadow: 0 0 #0000;
           --tw-inset-shadow-colored: 0 0 #0000;
-          --tw-ring-color: ;
+          --tw-ring-color: initial;
           --tw-ring-shadow: 0 0 #0000;
-          --tw-inset-ring-color: ;
+          --tw-inset-ring-color: initial;
           --tw-inset-ring-shadow: 0 0 #0000;
-          --tw-ring-inset: ;
+          --tw-ring-inset: initial;
           --tw-ring-offset-width: 0px;
           --tw-ring-offset-color: #fff;
           --tw-ring-offset-shadow: 0 0 #0000;
@@ -12604,11 +12604,11 @@ test('ring', () => {
           --tw-shadow-colored: 0 0 #0000;
           --tw-inset-shadow: 0 0 #0000;
           --tw-inset-shadow-colored: 0 0 #0000;
-          --tw-ring-color: ;
+          --tw-ring-color: initial;
           --tw-ring-shadow: 0 0 #0000;
-          --tw-inset-ring-color: ;
+          --tw-inset-ring-color: initial;
           --tw-inset-ring-shadow: 0 0 #0000;
-          --tw-ring-inset: ;
+          --tw-ring-inset: initial;
           --tw-ring-offset-width: 0px;
           --tw-ring-offset-color: #fff;
           --tw-ring-offset-shadow: 0 0 #0000;
@@ -12853,11 +12853,11 @@ test('inset-ring', () => {
           --tw-shadow-colored: 0 0 #0000;
           --tw-inset-shadow: 0 0 #0000;
           --tw-inset-shadow-colored: 0 0 #0000;
-          --tw-ring-color: ;
+          --tw-ring-color: initial;
           --tw-ring-shadow: 0 0 #0000;
-          --tw-inset-ring-color: ;
+          --tw-inset-ring-color: initial;
           --tw-inset-ring-shadow: 0 0 #0000;
-          --tw-ring-inset: ;
+          --tw-ring-inset: initial;
           --tw-ring-offset-width: 0px;
           --tw-ring-offset-color: #fff;
           --tw-ring-offset-shadow: 0 0 #0000;