Home  >  Q&A  >  body text

Is it possible to merge "classic" CSS rules with media queries that contain the same style?

I'm wondering if it's possible to combine 2 rules that apply to the same element and contain the same style, but one of the rules is in a media query and get something similar to:

.a,
.b .a {
  color: white;
  background-color: black;
}

The rules are:

:root {
  --dark-color: white;
  --dark-bg: black;
  --light-color: black;
  --light-bg: white;
}

@media (prefers-color-scheme: dark) {
  .content {
    color: var(--dark-color);
    background-color: var(--dark-bg);
  }
}
#dark-theme:checked~.content {
  color: var(--dark-color);
  background-color: var(--dark-bg);
}

@media (prefers-color-scheme: light) {
  .content {
    color: var(--light-color);
    background-color: var(--light-bg);
  }
}
#light-theme:checked~.content {
  color: var(--light-color);
  background-color: var(--light-bg);
}
<input type="radio" name="color-theme" id="dark-theme">
<label for="dark-theme">dark</label>
<input type="radio" name="color-theme" id="light-theme">
<label for="light-theme">light</label>
<input type="radio" name="color-theme" id="default-theme" checked>
<label for="default-theme">default</label>

<div class="content">Test</div>

If prefer-color-scheme is dark, or #dark-theme is checked, then .content here will get a black background and white color.

Both rules apply the same style.

Is there a way to combine these rules?

P粉129168206P粉129168206258 days ago430

reply all(2)I'll reply

  • P粉163951336

    P粉1639513362024-02-04 17:54:23

    :root {
      --dark-color: white;
      --dark-bg: black;
      --light-color: black;
      --light-bg: white;
    }
    
    @media (prefers-color-scheme: dark) {
      #default-theme:checked~.content {
        color: var(--dark-color);
        background-color: var(--dark-bg);
      }
    }
    #dark-theme:checked~.content {
      color: var(--dark-color);
      background-color: var(--dark-bg);
    }
    
    @media (prefers-color-scheme: light) {
      #default-theme:checked~.content {
        color: var(--light-color);
        background-color: var(--light-bg);
      }
    }
    #light-theme:checked~.content {
      color: var(--light-color);
      background-color: var(--light-bg);
    }
    
    
    
    
    
    
    
    
    Test

    reply
    0
  • P粉543344381

    P粉5433443812024-02-04 09:45:35

    You can't do this using native CSS. However, if your problem is related to writing less, then the CSS compiler has already taken care of that need. If you're willing to give it a try, here's simple code written in Sass.

    First, you wrap your content in a @mixin. It will store your class using a variable which should change based on the selected theme.

    @mixin content-style($theme) {
      .content {
        color: var(--#{$theme}-color);
        background-color: var(--#{$theme}-bg);
      }
    }
    

    Afterwards, you can use it in another mixin to define theme styles:

    @mixin themed-style($theme) {
      @media (prefers-color-scheme: $theme) {
        @include content-style($theme);
      }
      ##{$theme}-theme:checked ~ {
       @include content-style(#{$theme});
      }
    }
    

    Finally, you can use this to create as many themes as you want, just change the variables:

    @include themed-style(dark);
    @include themed-style(light);
    

    If you want to see the same output as the original code, you can try it here

    Copy and paste the complete code to see the conversion:

    :root {
        --dark-color: white;
        --dark-bg: black;
        --light-color: black;
        --light-bg: white;
    }
    
    @mixin content-style($theme) {
      .content {
        color: var(--#{$theme}-color);
        background-color: var(--#{$theme}-bg);
      }
    }
    
    @mixin themed-style($theme) {
      @media (prefers-color-scheme: $theme) {
        @include content-style($theme);
      }
      ##{$theme}-theme:checked ~ {
       @include content-style(#{$theme});
      }
    }
    
    @include themed-style(dark);
    @include themed-style(light);
    

    reply
    0
  • Cancelreply