Home > Enterprise >  CSS attribute from body element used on other classes?
CSS attribute from body element used on other classes?

Time:02-03

I am trying to create a basic CSS template for a project. It needs to support both a light and dark mode.

In the html, the body tag has data-layout-color attribute. I have some toggles that allow switching between light and dark, and it is updating this attribute. In my CSS sheet, I use the attribute selector for background color, and it works! Now I need to be able to set other elements color based on the light/dark mode, but that's not working as the individual element doesn't have the attribute. I don't want to add data-layout-color to everything, and then have to update it all with my js. Any suggestions?

HTML:

<body ng-controller="myApp" data-layout-color="dark" data-layout="topnav">
<button type="button" >PRESS ME!</button>
</body>

CSS:

body[data-layout-color="dark"]{
background-color: var(--my-body-dark-bg);
}
body[data-layout-color="light"]{
background-color: var(--my-body-light-bg);
}
.btn-primary[data-layout-color="light" {
color: var(--my-white-light);
background-color: var(--my-primary-light);
border-color: var(--my-primary-light);
}
.btn-primary[data-layout-color="dark" {
color: var(--my-white-dark);
background-color: var(--my-primary-dark);
border-color: var(--my-primary-dark);
}

CodePudding user response:

You could write your selectors such that the attribute selector remains on body:

  /* primary button under a "light" layout parent */

  [data-layout-color="light"] .btn-primary {
    color: var(--my-white-light);
    background-color: var(--my-primary-light);
    border-color: var(--my-primary-light);
  }

But I think a better idea would be to change the custom property values so you don't need the theme-specific selectors on child elements in the first place:

[data-layout-color="dark"] {
  --button-color-bg: white;
  --button-color-fg: black;
}

[data-layout-color="light"] {
  --button-color-bg: black;
  --button-color-fg: white;
}

.btn-primary {
  background-color: var(--button-color-bg);
  color: var(--button-color-fg);
  
  display: inline-block;
  padding: 0.25em 1em;
  border: 1px solid grey;
  margin: 0.5em;
}
<div data-layout-color="dark">
  <div >Dark Body</div>
</div>

<div data-layout-color="light">
  <div >Light Body</div>
</div>

CodePudding user response:

With plain css you can write it like this

body[data-layout-color="dark"]{
    background-color: var(--my-body-dark-bg);
}

body[data-layout-color="dark"] .btn-primary{
    color: var(--my-white-dark);
    background-color: var(--my-primary-dark);
    border-color: var(--my-primary-dark);
}

body[data-layout-color="dark"] .btn-primary a{
    text-decoration: underline overline #FF3028;
}

I suggest you use scss though. It will make your life easier. If you'r using visualstudio code just download Live sass complier and click watch sass in the bottom right corner.

Using scss you would write it like this:


body[data-layout-color="dark"]{
    background-color: var(--my-body-dark-bg);

    .btn-primary{
        color: var(--my-white-dark);
        background-color: var(--my-primary-dark);
        border-color: var(--my-primary-dark);

        a{
             text-decoration: underline overline #FF3028;
        }
    }


    .btn-secondary{
        color: var(--my-white-dark-secondary);
        background-color: var(--my-primary-dark-secondary);
        border-color: var(--my-primary-dark-secondary);
    }

    p{
        color: var(--my-white-dark);
    }
}
body[data-layout-color="light"]{
    background-color: var(--my-body-light-bg);

    /*etc etc*/

}
  •  Tags:  
  • css
  • Related