# CSS transition on body background

**URL:** https://forum.kirupa.com/t/css-transition-on-body-background/650380
**Category:** Uncategorized
**Created:** [January 9, 2022, 3:29pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380 "2022-01-09T15:29:23Z")
**Posts on this page:** 19
**Page:** 1

<div class="post-metadata">

### Author: ![Wayne](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wayne/32/16501_2.png) [@Wayne](https://forum.kirupa.com/u/Wayne)
#### Post date: [January 9, 2022, 3:29pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/1 "2022-01-09T15:29:23Z")

</div>

I’m trying to change background on body via JavaScript. Most of the info online use CSS :hover style transitions. What I want is doing it via JavaScript. The background-Color changes without animation, even when I have added transition. Why?

```auto

body {
        background-color: silver;
        color: white;
        font-family: Arial, Helvetica, sans-serif;
        overflow: hidden;
        transition: background-color 29s ease-in;
      }

document.body.style.backgroundColor = "red";

```

---

<div class="post-metadata">

### Author: ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)
#### Post date: [January 9, 2022, 7:11pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/2 "2022-01-09T19:11:18Z")

</div>

Can you paste your full code or a link to the example?

---

<div class="post-metadata">

### Author: ![Wayne](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wayne/32/16501_2.png) [@Wayne](https://forum.kirupa.com/u/Wayne)
#### Post date: [January 9, 2022, 7:22pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/3 "2022-01-09T19:22:40Z")

</div>

```auto

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Test</title>
    <style>
    
      h1 {
        font-size: 4em;
        margin-top: 0em;
      }

      body {
        background-color: silver;
        color: white;
        font-family: Arial, Helvetica, sans-serif;
        overflow: hidden;
        transition: background-color 29s ease-in;
      }
    
      .main {
        width: 400px;
        padding: 2em;
      }
      .main h1 {
        margin-bottom: 0;
      }

      .fade-in {
        position: relative;
        animation: fadeIn ease 1s;
      }

      @keyframes fadeIn {
        0% {
          opacity: 0;
          left: 200px;
        }
        70% {
          left: 20px;
          transform: scale(1.2);
        }
        100% {
          opacity: 1;
          left: 0px;
        }
      }
    </style>
  </head>
  <body>
    <div class="main">
      <h1 class="fade-in">hello world</h1>
    </div>

    <script type="text/javascript">
      const hours = new Date().getHours();
      const isDarkmodeTime = hours >= 15 || hours <= 8;
      const body = document.querySelector("body");
      body.style.color = isDarkmodeTime ? "white" : "black";
      body.style.backgroundColor = isDarkmodeTime ? "black" : "white";
    </script>
  </body>
</html>

```

---

<div class="post-metadata">

### Author: ![steve.mills](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/steve.mills/32/14961_2.png) [@steve.mills](https://forum.kirupa.com/u/steve.mills)
#### Post date: [January 9, 2022, 11:21pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/4 "2022-01-09T23:21:40Z")

</div>

I like to think of it like this:

state 1 e.g. `.open{}`  
state 2 e.g. `.closed{}`

The transition is between the two “states” or `selectors`.

Lets say you want to transition something 2s to open 2s to close.  
You would have to apply the transition to both open and close selectors.

Transitions need both a value change and a CSS selector change to work.

In the above code you haven’t changed the `class or selector` just the `color` and by using JS directly on the element you have effectively “in-lined” the color so it kind of like doing ` <body style = "background-color: red" >`

You’ve got 3 options:  
-add the transition to your change on the element e.g.

```auto
document.body.style = "background-color: red; 
transition: background-color 29s ease-in"

```

-add a CSS class and change the body class e.g

```auto
 .redBody{ background-color: red; 
transition: background-color 29s ease-in;}
document.body.classList.add('redBody')

```

- use WAAPI (web animations api)

```auto
document.body.animate([ { background-color: silver, easing: 'ease-in' },
                  { background-color: red, easing: 'ease-in' },
                  ],
                {duration: 29000, fill: 'forwards'});
```

---

<div class="post-metadata">

### Author: ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)
#### Post date: [January 9, 2022, 11:23pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/5 "2022-01-09T23:23:30Z")

</div>

In addition to the excellent points Steve made, the other option might be to use a CSS animation and set it to not loop 🙂

---

<div class="post-metadata">

### Author: ![steve.mills](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/steve.mills/32/14961_2.png) [@steve.mills](https://forum.kirupa.com/u/steve.mills)
#### Post date: [January 9, 2022, 11:52pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/6 "2022-01-09T23:52:18Z")

</div>

BTW, it’s probably no big deal for a 29s animation, but if your doing fast animations directly on the element its probably best to use requestAnimationFrame e.g

```auto
window.requestAnimationFrame(() => 
document.body.style = "background-color: red; 
transition: background-color 29s ease-in"
 )

```

WAAPI does RAF by default apparently.  
I think you still need to use it for classList changes.

I mostly use WAAPI or transitions now. WAAPI is pretty performant. 🙂

---

<div class="post-metadata">

### Author: ![Wayne](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wayne/32/16501_2.png) [@Wayne](https://forum.kirupa.com/u/Wayne)
#### Post date: [January 10, 2022, 8:14am UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/7 "2022-01-10T08:14:57Z")

</div>

Applying this does not initiate the animation from silver til red:

```auto
document.body.style = "background-color: red; 
transition: background-color 29s ease-in;"

// Not working either

 .fadeBG{ background-color: red; 
transition: background-color 29s ease-in;}
document.body.classList.add('fadeBG')

```

---

<div class="post-metadata">

### Author: ![steve.mills](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/steve.mills/32/14961_2.png) [@steve.mills](https://forum.kirupa.com/u/steve.mills)
#### Post date: [January 10, 2022, 11:09am UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/8 "2022-01-10T11:09:48Z")

</div>

My bad `document.body.style` is read only  
try:  
`document.body.setAttribute("style", "background-color: blue; transition: background-color 29s ease-in");`

```auto
.fadeBG{ background-color: red; 
transition: background-color 29s ease-in;}

```

This won’t work because `body.style.backgroundColor = 'black'`

The inline style is more specific than a ‘class’

You either set on the `element` or go `class` all the way 🙂

---

<div class="post-metadata">

### Author: ![Wayne](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wayne/32/16501_2.png) [@Wayne](https://forum.kirupa.com/u/Wayne)
#### Post date: [January 10, 2022, 11:19am UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/9 "2022-01-10T11:19:12Z")

</div>

why does not this work? `document.body.classList.add()`  
document.body.setAttribute does not animate the body bg either

---

<div class="post-metadata">

### Author: ![steve.mills](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/steve.mills/32/14961_2.png) [@steve.mills](https://forum.kirupa.com/u/steve.mills)
#### Post date: [January 10, 2022, 11:25am UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/10 "2022-01-10T11:25:46Z")

</div>

I just opened up your doc in Chrome and in the console pasted in that, then hit enter  
`document.body.setAttribute("style", "background-color: blue; transition: background-color 29s ease-in")`  
and it turned blue after a while…

The class change wont work unless you remove:  
`body.style.backgroundColor = isDarkmodeTime ? "black" : "white";`

`"inline"` styles on the `element` have more CSS specificity than anything except `!important;`

---

<div class="post-metadata">

### Author: ![steve.mills](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/steve.mills/32/14961_2.png) [@steve.mills](https://forum.kirupa.com/u/steve.mills)
#### Post date: [January 10, 2022, 12:01pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/11 "2022-01-10T12:01:15Z")

</div>

I personally would not set the `<body>` with JS.

You could try using `CSS custom properties (vars)` and set those with JS so you can still use `class` without `!important`

I modified your code to work with CSS custom properties.

```auto
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Test</title>
    <style>
      :root {
            --main-color: white;
            --bg-color: silver;
        }  
      h1 {
        font-size: 4em;
        margin-top: 0em;
      }
      .body {
        background-color: var(--bg-color);
        color: var(--main-color);
        font-family: Arial, Helvetica, sans-serif;
        overflow: hidden;
        transition: background-color 29s ease-in;
      }
    .fadeBG{ background-color: red;
        transition: background-color 29s ease-in;}
      .main {
        width: 400px;
        padding: 2em;
      }
      .main h1 {
        margin-bottom: 0;
      }
      .fade-in {
        position: relative;
        animation: fadeIn ease 1s;
      }
      @keyframes fadeIn {
        0% {
          opacity: 0;
          left: 200px;
        }
        70% {
          left: 20px;
          transform: scale(1.2);
        }
        100% {
          opacity: 1;
          left: 0px;
        }
      }
    </style>
    <script type="text/javascript">
      const hours = new Date().getHours();
      const isDarkmodeTime = hours >= 15 || hours <= 8;
      const root = document.documentElement;
      if(isDarkmodeTime){
        root.style.setProperty('--main-color', 'white');
        root.style.setProperty('--bg-color', 'black');
      }
      else{
        root.style.setProperty('--main-color', 'black');
        root.style.setProperty('--bg-color', 'white');
      }
      const fade = () => document.body.className = 'fadeBG'
    </script>
  </head>
  <body class = 'body'>
    <div class="main">
      <h1 class="fade-in">hello world</h1>
    </div>
    <br>
    <button onclick="fade()">Fade me</button>
  </body>
</html>

```

Just run that and it should be kind of what your after 🙂

---

<div class="post-metadata">

### Author: ![Wayne](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wayne/32/16501_2.png) [@Wayne](https://forum.kirupa.com/u/Wayne)
#### Post date: [January 10, 2022, 4:12pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/12 "2022-01-10T16:12:03Z")

</div>

Thanks for the help but the animation does not load on page load/refresh. I have to add a button listener for it to animate. Something similar to @kirupa web animation book chapter 6 where you click a button to apply js animations. I guess I can add an event listener for onLoad and add the fadeIn animation.

---

<div class="post-metadata">

### Author: ![Wayne](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wayne/32/16501_2.png) [@Wayne](https://forum.kirupa.com/u/Wayne)
#### Post date: [January 10, 2022, 6:07pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/13 "2022-01-10T18:07:58Z")

</div>

Fade in on page onLoad did the trick with setAttribute(“style”,”…”)

---

<div class="post-metadata">

### Author: ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)
#### Post date: [January 10, 2022, 9:44pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/14 "2022-01-10T21:44:05Z")

</div>

If you just want to change the background color on page load, the CSS animation route is quite handy:

```auto
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Change Background Color</title>

  <style>
    body {
      background-color: yellow;
      animation-name: change_color;
      animation-duration: 10s;
      animation-iteration-count: 1;
    }

    @keyframes change_color {
      100% {
        background-color: black;
      }
    }
  </style>
</head>
<body>
  
</body>
</html>

```

---

<div class="post-metadata">

### Author: ![steve.mills](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/steve.mills/32/14961_2.png) [@steve.mills](https://forum.kirupa.com/u/steve.mills)
#### Post date: [January 10, 2022, 11:36pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/15 "2022-01-10T23:36:39Z")

</div>

Yeah like @kirupa said just use a simple animation.

If you want to do night mode just use `css vars` like above.

That way you are setting them on the `<html>` / `root` and you don’t have to put your script in the body.

They should work fine with your animation.

The `vars` will do the changes before the body loads so you shouldn’t get a FOUC. 🙂

---

<div class="post-metadata">

### Author: ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)
#### Post date: [January 11, 2022, 12:19am UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/16 "2022-01-11T00:19:38Z")

</div>

Check out the source on the main [kirupa.com](http://kirupa.com) site on how dark mode is done. You’ll see a giant list of css vars at the very top. The script for loading the right set of vars runs before the rest of the page renders (just above the `body` element), and that ensures there is no FOUC with only a very small slowdown in rendering time since JS is running before the page can start displaying.

---

<div class="post-metadata">

### Author: ![kirupa](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/kirupa/32/11616_2.png) [@kirupa](https://forum.kirupa.com/u/kirupa)
#### Post date: [January 18, 2022, 10:47pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/17 "2022-01-18T22:47:14Z")

</div>

While in the process of recording a video on generating random colors, I stumbled upon another approach that I used for animating something with a transition on page load: [kirupa/simple\_random\_color\_changer.htm at master · kirupa/kirupa · GitHub](https://github.com/kirupa/kirupa/blob/master/animations/simple_random_color_changer.htm)

I use an empty CSS keyframes rule to trigger the **animationiteration** event!

---

<div class="post-metadata">

### Author: ![Wayne](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/wayne/32/16501_2.png) [@Wayne](https://forum.kirupa.com/u/Wayne)
#### Post date: [January 19, 2022, 5:36am UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/18 "2022-01-19T05:36:45Z")

</div>

That’s a great way to do it. It looks like the animation loop is infinite too. Thank you for sharing.

---

<div class="post-metadata">

### Author: ![VaiFanatic](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/vaifanatic/32/7159_2.png) [@VaiFanatic](https://forum.kirupa.com/u/VaiFanatic)
#### Post date: [January 19, 2022, 5:26pm UTC](https://forum.kirupa.com/t/css-transition-on-body-background/650380/19 "2022-01-19T17:26:53Z")

</div>

I had fun just following along and messing around with this myself.
