1

I use SCSS code in my Laravel 8 project with webpack. I want to handle switching dark mode and light mode and manually overwrite the browser settings too.

I search a while to find solution for this problem, and I checked this question and many more, tried out, but found not working solutions only.

Here is my SCSS code:

// colors in light mode
$color-primary: hsl(19, 8%, 52%);
$color-primary-hover: hsl(17, 8%, 45%);

// colors in dark mode
$color-dark-primary: hsl(18, 27%, 52%);
$color-dark-primary-hover: hsl(17, 8%, 57%);

@media (prefers-color-scheme: light) {
    :root {
        --color-primary: #{$color-primary};
        --color-primary-hover: #{$color-primary-hover};
    }
}

@media (prefers-color-scheme: dark) {
    :root {
        --color-primary: #{$color-dark-primary};
        --color-primary-hover: #{$color-dark-primary-hover};
    }
}

// overwrite light mode
@media (prefers-color-scheme: light) {
    body.forceDarkMode {
        --color-primary: #{$color-dark-primary};
        --color-primary-hover: #{$color-dark-primary-hover};
    }
}


.btn-primary {
    background-color: color(primary);

    &:hover {
        background-color: color(primary-hover);
    }
}

As the upper linked StackOverflow answer suggested I implemented this code:

@function color($color-name) {
    @return var(--color-#{$color-name});
}

And the compiled result is this:

.btn-primary {
  background-color: undefined;
}
@media (prefers-color-scheme: dark){
  .btn-primary{
    background-color: #a67764;
  }
}
@media (prefers-color-scheme: light){
  .btn-primary{
    background-color: #8e817b;
  }
}

.btn-primary:hover {
  background-color: undefined;
}
@media (prefers-color-scheme: dark){
  .btn-primary:hover{
    background-color: #9a8e89;
  }
}
@media (prefers-color-scheme: light){
  .btn-primary:hover{
    background-color: #7c6f6a;
  }
}

Of course on the body element I toggle forceDarkMode class name with JavaScript when user change a checkbox.

Now I think the undefined value is shomehow related to my basic problem: I expect something like this code:

.btn-primary {
  background-color: var(--color-primary);
}
@media (prefers-color-scheme: dark){
  .btn-primary{
    background-color: var(--color-primary);
  }
}
@media (prefers-color-scheme: light){
  .btn-primary{
    background-color: var(--color-primary);
  }
}

But the sass compiler change the CSS variables (more precisely the var(--css-variable-name) string) to SCSS variable's value.

UPDATE:

Here is the webpack.mix.js file's content:

const mix = require('laravel-mix');
const fs = require('fs');
const webpack = require('webpack');

require('dotenv').config();

const domain = process.env.APP_URL.replace(/https?:\/\//, '');
const mixPath = 'theme_' + domain.replace(/\./g, '_');

if (mix.inProduction()) {
  mix.version();
}

mix.js('resources/themes/' + domain + '/js/app.js', 'public/' + mixPath + '/js')
  .vue()
  .sass('resources/themes/' + domain + '/css/app.scss', 'public/' + mixPath + '/css')
  .options({
    postCss: [
      require('postcss-css-variables')()
    ]
  })
  .copyDirectory('resources/themes/' + domain + '/img/', 'public/' + mixPath + '/img');

mix.webpackConfig({
  plugins: [
    new webpack.DefinePlugin({
      __VUE_OPTIONS_API__: true,
      __VUE_PROD_DEVTOOLS__: false,
    }),
  ],
});

How can I avoid this replace and keep the CSS variables in the code?

netdjw
  • 5,419
  • 21
  • 88
  • 162
  • Are you sure? I tried to reproduce it at https://www.sassmeister.com/ and the compiled css looks fine: `.btn-primary { background-color: var(--color-primary); } .btn-primary:hover { background-color: var(--color-primary-hover); }`. It is strange that sass should try to replace the `var` during compile time. This would completely counteract any usefulness of using var in the first place. – Martin Oct 05 '21 at 16:22
  • Yes. Pretty sure. Maybe this is a bug of `sass` compiler. – netdjw Oct 05 '21 at 16:30
  • Better you check your configuration options, maybe there is one that says `replace-css-var-during-compile` as some form of IE11 support option. Or do you have any `post-css` steps configured? Because this doesn't seem the kind of bug that gets released unnoticed. – Martin Oct 06 '21 at 13:01
  • @Martin I don't have any special post-css configuration. I update my question with the `webpack.mix.js` file content. – netdjw Oct 07 '21 at 08:27

0 Answers0