I have two separate SASS files among many, on a ReactJS repository, such as _main.sass
and _partials.sass
. They are combined using @use
on a separate file named index.css
.
The SASS package as a dependency is just sass
via npm.
_main.sass
and all of its variables can be accessed by _partials.sass
, thanks to @use "./main" as *
.
I have the following code on _main.sass
which detects OS preference for dark mode:
@media (prefers-color-scheme: light)
body
background-color: $white
color: $black
@media (prefers-color-scheme: dark)
body
background-color: $dark
color: $light
All of these color variables are defined and they're working well.
But the problem is that I need to use complement()
function on the background-color
which is currently active, in _partials.sass
.
The main issue seems to me that when I assign a variable e.g. $accent
on both ends of the media queries, the variable does not get picked up by the remote file. I could not wrap my head around to do it in such way, since I'm only a beginner at coding SASS.
Unfortunately, I need the plain CSS @media query implementations for automatically detecting the preference. But any suggestion is appreciated in case it is impossible to keep it like that and achieve what I wanted.
Thank you!
I've found the solution myself.
So, I was trying to make a light/dark theme compliant SASS
implementation.
What complement
function does is that it rotates the color in the input for 180deg
on the RGB hue. I needed this to get corresponding inverted-like colors for each color, for better dark-mode contrast. The difference between invert
and complement
are listed here.
But, I realized that I did not need that. Here is the code for my theme implementation using SASS
.
// rainbow
$blue: #00a4ef
$yellow: #f4b400
$red: #db4437
$green: #61b500
$purple: #6e14ef
$pink: #ff0090
$carmine: #c6004b
// monochroma
$white: #fff
$light: #f5f5f5
$lgray: #c2c2c2
$dgray: #6e6e6e
$ldark: #363636
$dark: #232323
$black: #000
$themes: (light: (logo: url("../static/logo-light.svg"), bg: $white, card-bg: $light, text: $black, link: $red, hover: $pink, active: $carmine, border: $lgray, button: $yellow), dark: (logo: url("../static/logo-dark.svg"), bg: $dark, card-bg: $ldark, text: $light, link: $red, hover: $pink, active: $carmine, border: $dgray, button: $purple))
@mixin themeProperty($theme, $property, $color, $additionalProperties)
@if $additionalProperties
#{$property}: unquote(map-get($theme, $color) + " " + $additionalProperties)
@else
#{$property}: unquote(map-get($theme, $color))
@mixin theme($property, $color, $additionalProperties: "")
$light: map-get($themes, light)
$dark: map-get($themes, dark)
@media (prefers-color-scheme: light)
@include themeProperty($light, $property, $color, $additionalProperties)
@media (prefers-color-scheme: dark)
@include themeProperty($dark, $property, $color, $additionalProperties)
There is a color map named "themes" which lists each color for light and dark themes for different use cases.
Furthermore, the mixin
s match the exact color for exact usage for the desired theme mode, whichever is being used by the client-side (browser or OS), thanks to @media
queries.
For example, if you'd like to color a background-color
using the button
preset on the theme mapping, the usage is as follows:
@include theme("background-color", button)