JS/CSS Switching all related classes in a function

59 views Asked by At

I created a function which changes the background of the body depending on the time of day. This aspect is working perfectly, but I want to make other elements change along with it (i.e. dark and light mode but more specific). It's definitely related to the order of my CSS elements, but I can't just wait around and change the order every time the background changes. The only elements being listened to are the ones at the end of the list (again, except for the background color which is changing as expected). So in the below case all elements would be following the .sunrise properties regardless of the time.

I've tried playing with the function to see if I can remove the class combinations, played with the syntax, rearranged the classes in CSS, but no luck. I understand that the more specific the CSS class the higher the priority but since these are all pretty much the same I'm stumped. I looked through as many related questions as I could. Thank you!

function colorChange(hour) {
  let body = document.querySelector("body");

  if (hour >= 6 && hour < 9) {
    body.classList.add("sunrise");
    body.classList.remove("night-mode", "sunset", "day-mode");
  } else if (hour >= 9 && hour < 16) {
    body.classList.add("day-mode");
    body.classList.remove("night-mode", "sunrise", "sunset");
  } else if (hour >= 16 && hour < 20) {
    body.classList.add("sunset");
    body.classList.remove("night-mode", "sunrise", "day-mode");
  } else if (hour >= 20 || hour <= 6) {
    body.classList.add("night-mode");
    body.classList.remove("sunset", "sunrise", "day-mode");
  }
}
.night-mode {
  background: linear-gradient( to bottom, rgb(34, 34, 34), rgb(0, 40, 60), rgb(0, 143, 213));
}

.night-mode,
.content {
  background-color: rgba(228, 228, 228, 0.815);
  color: #bebebe;
}

.night-mode h1 {
  color: #bebebe;
}

.sunset {
  background: linear-gradient(to top, rgb(255, 7, 7), rgb(255, 255, 5));
}

.sunset,
.content {
  background-color: rgba(27, 27, 27, 0.397);
  color: rgb(26, 26, 26);
}

.sunset h1 {
  color: rgb(26, 26, 26);
}

.day-mode {
  background: linear-gradient( to top, rgb(238, 254, 183), rgb(169, 254, 222), rgb(90, 222, 255));
}

.day-mode,
.content {
  background-color: rgba(161, 211, 192, 0.336);
  color: #383838;
}

.day-mode h1 {
  color: #383838;
}

.day-mode,
.btn {
  border-color: #383838;
}

.day-mode,
.btn:hover {
  background-color: #383838;
}

.sunrise {
  background: linear-gradient(to top, rgb(248, 250, 107), rgb(238, 148, 148));
}

.sunrise,
.content {
  background-color: rgba(197, 103, 103, 0.26);
  color: rgb(56, 56, 56);
}

.sunrise,
.btn {
  border-color: rgb(133, 133, 133);
}

.sunrise,
.btn:hover {
  background-color: rgb(133, 133, 133);
}

.sunrise h1 {
  color: rgb(56, 56, 56);
}

1

There are 1 answers

0
Keith Pickering On

You need to use descendant selectors. There are some places where you have it right, for example:

.night-mode h1 {
  color: #bebebe;
}

This selects every h1 inside every element with the class night-mode, and applies a font color to all matching elements.

But then you have selectors like this:

.night-mode,
.content {
  background-color: rgba(228, 228, 228, 0.815);
  color: #bebebe;
}

In this selector, you are selecting every element with the class night-mode and every element with the class content, and applying the same styles to all matching elements. Instead you want to do this:

.night-mode .content {
  background-color: rgba(228, 228, 228, 0.815);
  color: #bebebe;
}

This will select every element with the class content inside every element with the class night-mode.