Search code examples
csssassmedia-queries

How to use media query and selectors at the same time using scss?


So I am creating a web app that supports dark mode.

If the device prefers dark mode by default, it will use the dark mode by the media query @media (prefers-color-scheme: dark).

But I also want to have a feature that users can manually switch to dark mode by adding an attribute to the body: data-theme="dark".

So I tried this:

// ...

.ChatScreen {
    background-color: #eee;
}

@media (prefers-color-scheme: dark), body[data-theme="dark"] {
    .ChatScreen {
        background-color: #000;
    }
}

It gives me this error while compiling:

Failed to compile.

./src/scss/app.scss (./node_modules/css-loader/dist/cjs.js??ref--6-oneOf-5-1!./node_modules/postcss-loader/src??postcss!./node_modules/resolve-url-loader??ref--6-oneOf-5-3!./node_modules/sass-loader/dist/cjs.js??ref--6-oneOf-5-4!./src/scss/app.scss)
SassError: Invalid CSS after "...me: dark), body": expected "{", was '[data-theme="dark"]'
        on line 107 of src/scss/screens/_chat.scss
        from line 6 of /Users/****/src/scss/app.scss
>> @media (prefers-color-scheme: dark), body[data-theme="dark"] {

   -------------------------------------^

How can I achieve this without duplicate these codes?


Solution

  • @media (prefers-color-scheme: dark) {
      body {
        &[data-theme="dark"] {
       .ChatScreen {
            background-color: #000;
        }
       }
      }
    }
    

    You can look at sass mixins and define your dark styling and then include that rule wherever you need.

    Edit

    @mixin dark-theme {
      .ChatScreen {
            background-color: #000;
        }
    }
    
    @media (prefers-color-scheme: dark) {
        @include dark-theme;
    }
    
    body {
        &[data-theme="dark"] {
            @include dark-theme;
       }
    }