Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid CSS generation with color-scheme and light-dark() function #873

Open
cevdetardaharan opened this issue Dec 17, 2024 · 2 comments
Open

Comments

@cevdetardaharan
Copy link

Problems:

  • lightningcss switches up the only and dark || light words, which is invalid, it has to be only dark || only light. 1
  • lightningcss transpiles light-dark() function --lightningcss-light and --lightningcss-dark; with theme one of them is set to initial and other one is left as none, but if you ask me the best approach would be having @media (prefers-color-scheme: dark) and setting it there as the dark of light-dark() function's second argument and in :root or where it's declared, creating it as normal.

Input Example Code:

:root {
  color-scheme: light dark;

  --bg: light-dark(var(--white), var(--black));
  --fg: light-dark(var(--black), var(--white));
}

body {
  background-color: var(--bg);
  color: var(--fg);
}

.dark {
  color-scheme: only dark;
}

.light {
  color-scheme: only light;
}

Output Example Code:

:root {
  --black:#000;
  --white:#fff;

  --lightningcss-light:initial;
  --lightningcss-dark: ;

  color-scheme:light dark;

  --bg:var(--lightningcss-light,var(--white))var(--lightningcss-dark,var(--black));
  --fg:var(--lightningcss-light,var(--black))var(--lightningcss-dark,var(--white))
}

@media (prefers-color-scheme:dark) {
  :root {
    --lightningcss-light: ;
    --lightningcss-dark:initial
  }
}

.dark {
  --lightningcss-light: ;
  --lightningcss-dark:initial;
  color-scheme:dark only;
}

.light {
  --lightningcss-light:initial;
  --lightningcss-dark: ;
  color-scheme:light only;
}

What it should be?

:root {
  color-scheme: light dark;

  --bg: white;
  --fg: black;
}

@media (prefers-color-scheme: dark) {
  --bg: black;
  --fg: white;
}

body {
  background-color: var(--bg);
  color: var(--fg);
}

.dark {
  color-scheme: only dark;
}

.light {
  color-scheme: only light;
}
@devongovett
Copy link
Member

lightningcss switches up the only and dark || light words, which is invalid, it has to be only dark || only light. 1

No, they may be in any order. The syntax is [ light | dark | <custom-ident> ]+ && only?, and && is defined as "A double ampersand (&&) separates two or more components, all of which must occur, in any order."

but if you ask me the best approach would be having @media (prefers-color-scheme: dark) and setting it there as the dark of light-dark() function's second argument and in :root or where it's declared, creating it as normal.

That's not how light-dark() works. It is not affected by prefers-color-scheme directly, it is only affected by the color-scheme property. If you set color-scheme: dark it will always be dark, even when prefers-color-scheme is light. That's why we compile as we do.

@cevdetardaharan
Copy link
Author

No, they may be in any order. The syntax is [ light | dark | <custom-ident> ]+ && only?, and && is defined as "A double ampersand (&&) separates two or more components, all of which must occur, in any order."

Ah, thank you, I tested and that's true, only dark and dark only work.

That's not how light-dark() works. It is not affected by prefers-color-scheme directly, it is only affected by the color-scheme property. If you set color-scheme: dark it will always be dark, even when prefers-color-scheme is light. That's why we compile as we do.

I'd say it's broken, let's take this code, we're setting color-scheme: light dark and we're creating --bg, --fg with light-dark() function, for .dark and .light class we're setting the color-scheme accordingly, for .inverse class we're inversing --fg and --bg, normally what would we except is to .dark to be always dark and .light to be always light but that's not the case:

:root {
  color-scheme: light dark;
  
  --white: #fff;
  --black: #000;

  --bg: light-dark(var(--white), var(--black));
  --fg: light-dark(var(--black), var(--white));
}

body {
  background-color: var(--bg);
  color: var(--fg);
}

.dark {
  color-scheme: only dark;
  background-color: var(--bg);
  color: var(--fg);
}

.light {
  color-scheme: only light;
  background-color: var(--bg);
  color: var(--fg);
}

.inverse {
  background-color: var(--fg);
  color: var(--bg);
}
Output with simple HTML (inlining the stylesheet):

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>C CSS Framework</title>
    <style>:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark;--white:#fff;--black:#000;--bg:var(--lightningcss-light,var(--white))var(--lightningcss-dark,var(--black));--fg:var(--lightningcss-light,var(--black))var(--lightningcss-dark,var(--white))}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}body{background-color:var(--bg);color:var(--fg)}.dark{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark only;background-color:var(--bg);color:var(--fg)}.light{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light only;background-color:var(--bg);color:var(--fg)}.inverse{background-color:var(--fg);color:var(--bg)}</style>
  </head>
  <body>
    <article class="grid">
      <h1>C CSS Framework</h1>
      <section class="dark">
        <h2>Everytime dark</h2>
      </section>
      <section class="light">
        <h2>Everytime light</h2>
      </section>
      <section class="inverse">
        <h2>Everytime inverse</h2>
      </section>
    </article>
  </body>
</html>

How it should be?

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>C CSS Framework</title>
    <style>
    :root {
      color-scheme: light dark;
    
      --white: #fff;
      --black: #000;
    
      --bg: light-dark(var(--white), var(--black));
      --fg: light-dark(var(--black), var(--white));
    }
    
    body {
      background-color: var(--bg);
      color: var(--fg);
    }
    
    .dark {
      color-scheme: only dark;
      background-color: var(--bg);
      color: var(--fg);
    }
    
    .light {
      color-scheme: only light;
      background-color: var(--bg);
      color: var(--fg);
    }
    
    .inverse {
      background-color: var(--fg);
      color: var(--bg);
    }
    </style>
  </head>
  <body>
    <article class="grid">
      <h1>C CSS Framework</h1>
      <section class="dark">
        <h2>Everytime dark</h2>
      </section>
      <section class="light">
        <h2>Everytime light</h2>
      </section>
      <section class="inverse">
        <h2>Everytime inverse</h2>
      </section>
    </article>
  </body>
</html>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants