csstools / postcss-plugins

PostCSS Tools and Plugins
https://preset-env.cssdb.org/
MIT No Attribution
888 stars 71 forks source link

Add polyfill only for browser that don't support `light-dark()` #1428

Closed Th3S4mur41 closed 2 months ago

Th3S4mur41 commented 2 months ago

What would you want to propose?

postcss-light-dark-function currently wraps the original light-darkusage in an @supports block.

Suggested solution

Would it be possible to optionally wrap the generated fallback into an inverted @supports block? e.g.

@supports not (color: light-dark(red, red))

While potentially breaking support for browser that don't support @supports this would heavily reduce the output CSS to be considered by modern browsers

Additional context

No response

Validations

Would you like to open a PR for this feature?

romainmenke commented 2 months ago

Do you have some CSS source as an example?

Th3S4mur41 commented 2 months ago

Taking a snippet out of a design system, it would look like this:

html {
  /* colors */
  --color-light: hsl(0 0% 100%);
  --color-dark: hsl(0 0% 16%);
  /* theme */
  color-scheme:light dark;
  --color-bg: light-dark(var(--color-light), var(--color-dark));
  --color-text: light-dark(var(--color-dark), var(--color-light));
}

The generated output currently looks like

html {
  --color-light: hsl(0 0% 100%);
  --color-dark: hsl(0 0% 16%);
  --csstools-color-scheme--dark: ;
  color-scheme:light dark;
  --csstools-light-dark-toggle--0:var(--csstools-color-scheme--dark) var(--color-light);
  --color-bg:var(--csstools-light-dark-toggle--0,var(--color-dark));
  --csstools-light-dark-toggle--1:var(--csstools-color-scheme--dark) var(--color-dark);
  --color-text:var(--csstools-light-dark-toggle--1,var(--color-light));
}

@supports (color:light-dark(red,red)) {
  html {
    --color-bg: light-dark(var(--color-light), var(--color-dark));
    --color-text: light-dark(black, white);
  }
}

So, upscaling this when there are dozens of color variables makes for a lot of variables to load and overwrite in modern browsers. Make also debugging in DevTools quite complex.

What I'd expect instead would be something like this:

html {
  --color-light: hsl(0 0% 100%);
  --color-dark: hsl(0 0% 16%);
  color-scheme:light dark;
}

@supports not (color:light-dark(red,red))
  html {
    --csstools-color-scheme--dark: ;
    --csstools-light-dark-toggle--0:var(--csstools-color-scheme--dark) var(--color-light);
    --color-bg:var(--csstools-light-dark-toggle--0,var(--color-dark));
    --csstools-light-dark-toggle--1:var(--csstools-color-scheme--dark) var(--color-dark);
    --color-text:var(--csstools-light-dark-toggle--1,var(--color-light));
  }
}

@supports (color:light-dark(red,red)) {
  html {
    --color-bg: light-dark(var(--color-light), var(--color-dark));
    --color-text: light-dark(black, white);
  }
}

That way, modern browsers would ignore the polyfill and it would also declutter their DevTools.

romainmenke commented 2 months ago

@Th3S4mur41 I am sorry but that is not something we can do.

That would dramatically increase the complexity of our code and it doesn't actually affect the outcome of a page render. Optimizing for DevTools is not something we want to do.

Things you can do:

Th3S4mur41 commented 2 months ago

Thanks @romainmenke... I'll have a look at our build chain and check if we can generate the polyfilled version in a separate file that we would only serve to older browsers