skip to Main Content

Now that there is CSS Nesting, if I’m using a body-level class for "dark" or "light" mode, I would love to set attributes to a selector that’s deep in the nest by referencing the parent:

body{
  .header{
    .button{
      .image{
        background-color: white;
      .image::has-parent(.dark-mode){ <-- something like this
        background-color: black;
...

I assume this violates some core CSS principles, but I figured I’d ask just in case! Is there an alternative technique for this?

This is different (as I understand it) from the :has selector because :has means has child or sibling. There is not a selector that selects if it has a parent.

Here’s an example snippet:

div{
 &.dark{
   background-color:black;
 }
 .child{
   /* doesn't work */
   &:has(.dark){
     color:white;
   }
 }
<div>
 <div class="child">Should be dark text on white background</div>
</div>

<div class="dark">
 <div class="child">Should be white text on dark background</div>
</div>

2

Answers


  1. There are ways to do this, but they all lead to nesting hell and trying to override things.

    I’d suggest using CSS variables instead, where you can define a set of them to control your themed color schemes. For example:

    body.light-mode {
      --theme-text-color: black;
      --theme-background-color: white;
    }
    body.dark-mode {
      --theme-text-color: white;
      --theme-background-color: black;
    }
    

    and then for your image CSS, you can just reference:

    .image {
      background-color: var(--theme-background-color);
    }
    

    This will allow you to keep your theme-based settings easily organized in one place, and then just reference them throughout the rest of your codebase. This is also helpful for example, if you wanted to change your darkmode background from black to #222222 without needing to make that update for every element that references it

    Login or Signup to reply.
  2. It seems you are over-complicating this. What you want is the selector .dark .child that you can write like below

    div{
     &.dark{
       background-color:black;
     }
     .child{
       .dark &{
         color:white;
       }
     }
    <div>
     <div class="child">Should be dark text on white background</div>
    </div>
    
    <div class="dark">
     <div class="child">Should be white text on dark background</div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search