Sharing CSS code between a selector and a media query
Posted in daily
Tags :
While cleaning up the CSS of this site (aka procrastinating), I realised that it wasn’t possible to use @extend in a media query.
You may not @extend an outer selector from within @media
I need to reuse a block of code inside and outside a media query: my dark theme can be turned on either by setting an attribute in the html element (on demand), or by honoring the user’s preferences via a media query.
I naively throught I could @extend a set of custom properties and styles both in the html selector and the media query, but it turns out that media queries don’t support @extend. Trying to extend a placeholder inside a media query from another scope (in this case, the root) won’t work.
:root {
// custom properties for light theme
}
%dark-theme-cvars {
// redefined custom properties for dark theme
}
[data-theme="dark"] {
@extend %dark-theme-cvars;
}
@media (prefers-color-scheme: dark) {
:root {
@extend %dark-theme-cvars;
}
}
But using @include will, so I set out to use a mixin instead.
:root {
// custom properties for light theme
}
@mixin dark-theme-cvars {
// redefined custom properties for dark theme
}
[data-theme="dark"] {
@include dark-theme-cvars;
}
@media (prefers-color-scheme: dark) {
:root {
@include dark-theme-cvars;
}
}
The limitation of this solution is that I need to create a mixin for each class I wish to extend within the media query, but it’s a start.
Alternatively, I tried to @extend the selector within a media query from the outside, but that didn’t help my use case.
There are discussions going on to allow @extend across media queries on GitHub.