-1

This is a very simple background color change animation. Is it possible to do that using pure CSS3?

var square = document.querySelector('.square');
var percentYellow = 0;
function changeBackground(){
 percentYellow = percentYellow + 10;
 square.style.background = 'linear-gradient(90deg, yellow '+percentYellow+'%, blue 0)';
 if(percentYellow<=100){
  setTimeout(changeBackground,200);
 }
}
changeBackground();
 .square{
  width:300px;
  height:300px;
  background:linear-gradient(90deg, yellow 0%, blue 0);
  border:1px solid;
 }
<div class="square"></div>
J.Joe
  • 644
  • 2
  • 7
  • 20

7 Answers7

6

You can animate the background-position:

.square {
  width: 300px;
  height: 300px;
  background: linear-gradient(90deg, yellow 50%, blue 0);
  background-size: 200% 100%;
  background-position: 100% 0;
  border: 1px solid;
  animation: slideBG 2s linear forwards;
}
@keyframes slideBG {
  0% {
    background-position: 100% 0;
  }
  100% {
    background-position: 0 0;
  }
}
<div class="square"></div>

Or, as @Harry pointed out, you can use steps() to maintain the "stepped" transition that your javascript version produces:

.square {
  width: 300px;
  height: 300px;
  background: linear-gradient(90deg, yellow 50%, blue 0);
  background-size: 200% 100%;
  background-position: 100% 0;
  border: 1px solid;
  animation: slideBG 2s steps(10, end) forwards;
}
@keyframes slideBG {
  to {
    background-position: 0 0;
  }
}
<div class="square"></div>
Turnip
  • 35,836
  • 15
  • 89
  • 111
  • 3
    This is the best option in my opinion. Using `steps()` function (`steps(10,end)`) instead of linear would make it closer to the demo in question. – Harry May 24 '16 at 12:37
2

Yes, it's possible. You can make the .square element blue, and ::after pseudo-element yellow, and then animate the width of ::after:

@keyframes animation {
  from {
    width: 0;
  }
  to {
    width: 300px;
  }
}
.square {
  width: 300px;
  height: 300px;
  background-color: blue;
  border: 1px solid;
}
.square::after {
  content: "";
  display: block;
  width: 300px;
  height: 300px;
  background-color: yellow;
  animation: animation 1s;
}
<div class="square"></div>
Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
1

You can use css animation and you need to set animation-fill-mode: forwards; to retain the final animation style otherwise it will rollback to the initial style.

animation-fill-mode: forwards -The target will retain the computed values set by the last keyframe encountered during execution.(Taken from here)

.square {
  width: 300px;
  height: 300px;
  background: linear-gradient(90deg, yellow 0%, blue 0);
  border: 1px solid;
  animation: anim 2s;
  animation-fill-mode: forwards; /* retain the css applied by animation */
}
@keyframes anim {
  0% {    background: linear-gradient(90deg, yellow 0%, blue 0);  }
  10% {    background: linear-gradient(90deg, yellow 10%, blue 0);  }
  20% {    background: linear-gradient(90deg, yellow 20%, blue 0);  }
  30% {    background: linear-gradient(90deg, yellow 30%, blue 0);  }
  40% {    background: linear-gradient(90deg, yellow 40%, blue 0);  }
  50% {    background: linear-gradient(90deg, yellow 50%, blue 0);  }
  60% {    background: linear-gradient(90deg, yellow 60%, blue 0);  }
  70% {    background: linear-gradient(90deg, yellow 70%, blue 0);  }
  80% {    background: linear-gradient(90deg, yellow 80%, blue 0);  }
  90% {    background: linear-gradient(90deg, yellow 90%, blue 0);  }
  100% {    background: linear-gradient(90deg, yellow 100%, blue 0);  }
}
<div class="square"></div>
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
  • 2
    Just a word of caution - Don't use `background` (with gradients or images) inside keyframes. Firefox will ignore them. This snippet won't work in it. You can see more details here - http://stackoverflow.com/questions/35994521/background-image-in-keyframe-does-not-display-in-firefox-or-internet-explorer/36005661#36005661 – Harry May 24 '16 at 12:42
  • 1
    Apart form the issue mentioned by Harry, this solution is kind of clumsy. Just imagine you have 100 or more keyframes instead of 10 here... – J.Joe May 24 '16 at 12:55
0

Try something like this

.contain{
  width:400px;
  height:400px;
  border:solid 1px black;
  background-color:blue;
  position:relative;
  }

.overcontain{
  width:100%;
  height:100%;
  background-color:yellow;
  animation:anime 2s linear;
  position:absolute;
  }

@keyframes anime{
  0%{width:0%;}
  100%{width:100%;}
  }
<div class="contain">
  <div class="overcontain"></div>
</div>
Alexis
  • 5,681
  • 1
  • 27
  • 44
0

It can be done with CSS only

.square{
    width:300px;
    height:300px;
    background:linear-gradient(90deg, yellow 0%, blue 0);
    border:1px solid;
    animation-name: slide;
    animation-duration: 4s;
}
@keyframes slide {
  0% { background:linear-gradient(90deg, yellow 0%, blue 0); }
  10% { background:linear-gradient(90deg, yellow 10%, blue 0); }
  20% { background:linear-gradient(90deg, yellow 20%, blue 0); }
  /* and so on ... */
  100% { background:linear-gradient(90deg, yellow 100%, blue 0); }
}

http://codepen.io/anon/pen/pyMYWz?editors=1100#anon-signup

Ahmad Alfy
  • 13,107
  • 6
  • 65
  • 99
0

Edit: Others has beaten me and answered while I was typing this, but since I included a link to a documentation that nobody else mentioned I'm going to post this anyway.


You can create animations using only CSS3 with the @keyframes rules and animation-* properties.

See http://www.w3schools.com/css/css3_animations.asp for reference.

Here is a little snippet:

<!DOCTYPE html>
<html>
<head>
<style> 
.square{
    width:100px;
    height:100px;
    background:linear-gradient(90deg, yellow 0%, blue 0%);
    border:1px solid;
    animation-name: example;
    animation-duration: 4s;
}

@keyframes example {
    0%   {background:linear-gradient(90deg, yellow 0%, blue 0%)}
    25%  {background:linear-gradient(90deg, yellow 25%, blue 0%)}
    50%  {background:linear-gradient(90deg, yellow 50%, blue 0%)}
    75%  {background:linear-gradient(90deg, yellow 75%, blue 0%)}
    100% {background:linear-gradient(90deg, yellow 100%, blue 0%)}
}
</style>
</head>
<body>

<div class="square"></div>

</body>
</html>

Note: There is a mess regarding vendors with these properties/rules and due that I couldn't get it working (tried it on Firefox 44). And to keep it simple I used only the default sintax. I hope it can shed some light on this at least.

Edit: Possibly I couldn't get it working due the fact mentioned in comments here.

Shadow
  • 29
  • 1
  • 9
0

You can just set how many steps you want to realize.

        .square{
            width:300px;
            height:300px;
            background:blue;
            border:1px solid;
            position: relative;
        }
        .square:before{
            content: '';
            display: block;
            position: absolute;
            background: yellow;
            display:block;
            left: 0;
            top:0;
            bottom:0;
            right: 100%;
            -webkit-animation: play 2s steps(10);
            -moz-animation: play 2s steps(10);
             -ms-animation: play 2s steps(10);
              -o-animation: play 2s steps(10);
                 animation: play 2s steps(10);
        }
        @-webkit-keyframes play {
           from { right: 100%; }
             to { right: 0px; }
        }

        @-moz-keyframes play {
           from { right: 100%; }
             to { right: 0px; }
        }

        @-ms-keyframes play {
           from { right: 100%; }
             to { right: 0px; }
        }

        @-o-keyframes play {
           from { right: 100%; }
             to { right: 0px; }
        }
<div class="square"></div>
Snowky
  • 1