Using CSS selectors with @media queries

Hey! I want user to select between dark, light, and system themes (and maybe even third, fourth, etc). I came up with this pen in mind: https://codepen.io/zobweyt/pen/BagdyGq But it's not working as expected. I want to turn on dark styles when any of the following conditions satisfy: - There's [data-theme="dark"] on an element - There's [data-theme="system"] on an element with @media (prefers-color-scheme: dark) I can't find a solution to make it without copy-pasting and mixins from SCSS or PostCSS, etc Is it even possible?
zobweyt
CodePen
BagdyGq
...
4 Replies
Kevin Powell
Kevin Powellโ€ข3mo ago
You'll need to copy paste, like you said. Media queries aren't selectors.
body {
background: var(--bg);
}

[data-theme="dark"] {
--bg: black;
}

@media (prefers-color-scheme: dark) {
:root {
--bg: black;
}
}
body {
background: var(--bg);
}

[data-theme="dark"] {
--bg: black;
}

@media (prefers-color-scheme: dark) {
:root {
--bg: black;
}
}
As for the data-theme="system", I wouldn't include that anywhere, so it just goes back to the default that way. They've added a light-dark() function, but support for it isn't great yet, but it will make things a lot easier and allow you to do it with only selectors though ๐Ÿ™‚
zobweyt
zobweytโ€ข3mo ago
Didn't expect to get an answer right from you :) Thank you for your awesome videos!!
You'll need to copy paste
So a more neat solution is to use a preprocessor like SASS for this, right?
As for the data-theme="system", I wouldn't include that anywhere, so it just goes back to the default that way.
Yeah, you're right, but I'd move the @media queries upper. If you had more than 2 themes, it'd be better to do it like this:
body {
background: var(--bg);
}

@media (prefers-color-scheme: light) {
:root {
--bg: white;
}
}

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

[data-theme="light"] {
--bg: white;
}

[data-theme="dark"] {
--bg: black;
}

[data-theme="third"] {
--bg: green;
}
body {
background: var(--bg);
}

@media (prefers-color-scheme: light) {
:root {
--bg: white;
}
}

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

[data-theme="light"] {
--bg: white;
}

[data-theme="dark"] {
--bg: black;
}

[data-theme="third"] {
--bg: green;
}
I guess light-dark() function is suitable if you have only 2 color schemes: light and dark But it's still very cool!
Kevin Powell
Kevin Powellโ€ข3mo ago
The above would work, yup! They are also working on mixins for CSS, so that could also potentially solve it, but that's years away ๐Ÿ˜„
แผ”ฯฯ‰ฯ‚
you can reduce a lot of the black/white part by using nested css:
:root {
--bg: white;

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

@media (prefers-color-scheme: dark) {
--bg: black;
}
}
this is actually plain css (but you can pass it through scss to make it compatible with older browsers, which you should avoid because plenty of chrome versions have RCE exploits that were used in the wild)
Want results from more Discord servers?
Add your server