postcss-dark-theme-class icon indicating copy to clipboard operation
postcss-dark-theme-class copied to clipboard

Suggestion: allow to discard original syntax `@media (prefers-color-scheme: dark)`

Open aletorrado opened this issue 1 year ago • 9 comments

Hi,

I just wanted to suggest adding a flag to the config to discard the original syntax, avoiding code duplication in the CSS output. This would help keeping the output code small when not needed.

For example, the app may add a little snippet like this on top: document.documentElement.classList.toggle('is-dark', matchMedia('(prefers-color-scheme: dark)').matches)

Please let me know if a PR would be welcomed.

Thanks!

aletorrado avatar Apr 21 '24 17:04 aletorrado

Hm. Can you show an input and output example for this option?

ai avatar Apr 21 '24 18:04 ai

It would be the same output with the parts wrapped in the media queries stripped. Like this:

/* Input CSS */

@media (prefers-color-scheme: dark) {
  html {
    --text-color: white
  }
  body {
    background: black
  }
}

section {
  background: light-dark(white, black);
}
/* Output CSS */

html:where(.is-dark) {
  --text-color: white
}
:where(html.is-dark) body {
  background: black
}

:where(html.is-dark) section {
  background: black;
}
:where(html.is-light) section {
  background: white;
}

aletorrado avatar Apr 21 '24 18:04 aletorrado

What is use case of not using @media?

ai avatar Apr 21 '24 18:04 ai

Just keeping the output small, with the drawback that will require JS code to initialize the classList (just like it's also needed to avoid FART). It's pretty common in postcss plugins to have a preserve flag that can be disabled to avoid duplicating code.

aletorrado avatar Apr 21 '24 18:04 aletorrado

There are 2 problems:

  1. You will need also JS code to switch class on system theme changes (like schedule day/night theme change feature in all OS).
  2. When app is loading in night theme, you will see a flash of light (the most popular option is a system theme, not some specific one).

Do you think that it is still a better option than extra CSS?

ai avatar Apr 21 '24 18:04 ai

I don't think it's a better option. I think there are drawbacks in both options, and having duplicated code may be a bigger drawback in some cases.

I don't think there should be any "FART" if the JS snippet is loaded right away. It's the same case as described in Step 7 of the Usage, when a custom theme was previously selected by the user.

Regarding system theme changes, the same snippet (or even a latter loaded script) may have that logic embedded, like this:

const mql = window.matchMedia("(prefers-color-scheme: dark)");

mql.onchange = (e) => {
  if (e.matches) {
    ...
  } else {
    ...
  }
};

aletorrado avatar Apr 21 '24 19:04 aletorrado

OK, send PR with option.

I don't think there should be any "FART" if the JS snippet is loaded right away

You have a different probability of FART in CSS-way and in JS-way. In JS-way you will have FART on any website when you are using dark theme. In CSS-way you will have FART only in user use dark theme for website and light theme for system (is it even a FART if everything is light around the page?).

ai avatar Apr 21 '24 20:04 ai

Thanks for merging #34

Continuing the discussion, I don't think there will be any FART at all if you have the JS snippet embedded into the HTML code, or loaded synchronously at the <head>, before any <body> content is downloaded and ready to render.

Did you experience FART this way (snippet + css, both at head)?

aletorrado avatar Apr 22 '24 19:04 aletorrado

I don't think there will be any FART at all if you have the JS snippet embedded into the HTML code

In this case, no. You will not FART.

But this way looks too complicated for me and many developers will make a mistake (like forgetting to embed JS code) to recommend it.

CSS way looks simpler.

ai avatar Apr 22 '24 19:04 ai