I want to use hover effects such as the ones in this tutorial, but to my dismay the effect does not work responsively. There are also problems at different zoom levels and in Firefox as you will see in these screenshots. (Here is a codepen that illustrates the problem).
100% Zoom in Chrome:
90% in Chrome:
And in Firefox the effect does not work at all.
On hover in Chrome (rotating dotted line):
On hover in Firefox (no dotted line):
How can I get the effect to work responsively? Both across browsers and at different zoom levels.
Here are some code snippets that illustrate the method:
<div class="hi-icon-wrap hi-icon-effect-4 hi-icon-effect-4b">
<div class="icon-text">Product</div>
</div>
CSS:
.hi-icon-effect-4b .hi-icon:hover {
-webkit-transition: box-shadow 0.2s;
-moz-transition: box-shadow 0.2s;
transition: box-shadow 0.2s;
}
.hi-icon-effect-4b .hi-icon:hover:after {
-webkit-animation: spinAround 9s linear infinite;
-moz-animation: spinAround 9s linear infinite;
animation: spinAround 9s linear infinite;
}
#-webkit-keyframes spinAround {
from {
-webkit-transform: rotate(0deg)
}
to {
-webkit-transform: rotate(360deg);
}
}
#-moz-keyframes spinAround {
from {
-moz-transform: rotate(0deg)
}
to {
-moz-transform: rotate(360deg);
}
}
#keyframes spinAround {
from {
transform: rotate(0deg)
}
to {
transform: rotate(360deg);
}
}
Play with the codepen here. Thanks for your ideas!
Here is an attemp to solve it.
I avoid using borders, and handle everything with backgrounds: some for the stripes, another one to hide-reveal the effect, and another one to mask the inner circle.
Now it is responsive (the size of the border is the padding, that can be set as a percentage), and works ok in FF.
The backgrounds have different colors so that it is easy to see which is each one, and the rotation is delayed also to make it easier to see what is happening
But now it is failing in IE ....
Hopefully somebody can solve this
.hi-icon {
width: 100px;
height: 100px;
position: relative;
font-size: 50px;
padding: 50px;
border-radius: 50%;
}
.hi-icon:after {
content: "";
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
padding: 3%;
border-radius: 50%;
background-image: linear-gradient(lightgray, lightgray),
linear-gradient(transparent 30%, red 70%),
linear-gradient(45deg, blue 0%, blue 25%, transparent 25%, transparent 50%, blue 50%, blue 75%, transparent 75%, transparent 100%),
linear-gradient(-45deg, green 0%, green 25%, transparent 25%, transparent 50%, green 50%, green 75%, transparent 75%, transparent 100%),
linear-gradient(225deg, blue 0%, blue 25%, transparent 25%, transparent 50%, blue 50%, blue 75%, transparent 75%, transparent 100%),
linear-gradient(135deg, blue 0%, blue 25%, transparent 25%, transparent 50%, blue 50%, blue 75%, transparent 75%, transparent 100%);
background-position: center center,bottom center,top left,bottom left,bottom right,top right;
background-size: 100% 100%,100% 1000%,50% 50%,50% 50%,50% 50%,50% 50%;
background-clip: content-box,border-box,border-box,border-box,border-box,border-box;
background-repeat:no-repeat;
transition: background-position 1s;
z-index: -1;
}
.hi-icon:hover:after {
background-position: center center,top center,top left,bottom left,bottom right,top right;
animation: rotate 3s linear infinite 1s;
}
#keyframes rotate {
0% {transform: rotate(0deg);}
100% {transform: rotate(360deg);}
}
<div class="hi-icon">TEST</div>
This is a firefox Bug. Check out some other options here. If you want the exact same hover effect.
Related
I want to move my gradient that has multiple colors smoothly but the problem is that the animation is not smooth. It just changes its position at every step.
<style>
.animated {
width: 300px;
height: 300px;
border: 1px solid black;
animation: gra 5s infinite;
animation-direction: reverse;
-webkit-animation: gra 5s infinite;
-webkit-animation-direction: reverse;
animation-timing-function: linear;
-webkit-animation-timing-function: linear;
}
#keyframes gra {
0% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(21%, #ff670f), color-stop(56%, #ffffff), color-stop(88%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 21%, #ffffff 56%, #0eea57 88%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 21%, #ffffff 56%, #0eea57 88%);
}
50% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(10%, #ff670f), color-stop(40%, #ffffff), color-stop(60%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 10%, #ffffff 40%, #0eea57 60%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 10%, #ffffff 40%, #0eea57 60%);
}
100% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(5%, #ff670f), color-stop(10%, #ffffff), color-stop(40%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 5%, #ffffff 10%, #0eea57 40%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 5%, #ffffff 10%, #0eea57 40%);
}
}
</style>
<div class="animated">
<h1>Hello</h1>
</div>
Is it possible to accomplish without using jQuery?
My jsfiddle link is https://jsfiddle.net/bAUK6
Please try this code:
#gradient
{
height:300px;
width:300px;
border:1px solid black;
font-size:30px;
background: linear-gradient(130deg, #ff7e00, #ffffff, #5cff00);
background-size: 200% 200%;
-webkit-animation: Animation 5s ease infinite;
-moz-animation: Animation 5s ease infinite;
animation: Animation 5s ease infinite;
}
#-webkit-keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
#-moz-keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
#keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
<html>
<div id="gradient">
Hello
</div>
</html>
Dynamic implementation of Dave's answer:
:root{
--overlay-color-1: #ff0000;
--overlay-color-2: #0000ff;
--anim-duration: 2s;
}
#gradient {
opacity: 0.8;
background: none;
}
#gradient:after,
#gradient:before {
content: '';
display: block;
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
#gradient:before {
background: linear-gradient(135deg, var(--overlay-color-2) 0%, var(--overlay-color-1) 100%);
animation: OpacityAnim var(--anim-duration) ease-in-out 0s infinite alternate;
}
#gradient:after {
background: linear-gradient(135deg, var(--overlay-color-1) 0%, var(--overlay-color-2) 100%);
animation: OpacityAnim var(--anim-duration) ease-in-out calc(-1 * var(--anim-duration)) infinite alternate;
}
#keyframes OpacityAnim {
0%{opacity: 1.0}
100%{opacity: 0.0}
}
<div id="gradient"></div>
Using CSS variables it's now a trivial task.
Here is a basic example (hover to see the result)
#property --a{
syntax: '<angle>';
inherits: false;
initial-value: 90deg;
}
#property --l{
syntax: '<percentage>';
inherits: false;
initial-value: 10%;
}
#property --c{
syntax: '<color>';
inherits: false;
initial-value: red;
}
.box {
/* needed for firefox to have a valid output */
--a:80deg;
--l:10%;
--c:red;
/**/
cursor:pointer;
height:200px;
transition:--a 0.5s 0.1s,--l 0.5s,--c 0.8s;
background:linear-gradient(var(--a), var(--c) var(--l),blue,var(--c) calc(100% - var(--l)));
}
.box:hover {
--a:360deg;
--l:40%;
--c:green;
}
<div class="box"></div>
More details here: https://dev.to/afif/we-can-finally-animate-css-gradient-kdk
How about this:
Set the body margin and padding to 0. Set an html rule to 100% height (higher than 100% may be required).
Set the body to the end state for the gradient.
Create an empty div with a background which is the start state for the gradient. Give the empty div 100% height.
Give both the body and the empty div a background-attachment: fixed;
Create a wrapper for your body content.
Set the empty div to position: fixed;
Set the wrapper to position: relative;
Give both a z-index, the wrapper being higher.
Create an animation that will change the opacity of the empty div from 1 to 0 over the desired time. Add animation-fill-mode:forwards; to the div rule so the animation stays where it ends.
It's not as sexy as a real animated gradient shift, but it's as simple as you can get with CSS only and keyframes, I think.
Here is another way. The following has the static gradient containing all phases of the animation, which is then moved inside the outer element. This allows to perform animation smoothly (as the topic suggests), because the only animation here is the element position.
Please note that for the sake of performance the gradient element left unchanged. Although the question was to animate the gradient, moving the background does practically the same thing, while the performance wins!
.animated {
width: 300px;
height: 300px;
overflow: hidden;
position: relative;
border: 1px solid black;
}
.innerGradient {
z-index: -1;
width: 300%;
height: 300%;
position: absolute;
animation: gra 5s infinite;
-webkit-animation: gra 5s infinite;
background: linear-gradient(135deg, #ff670f 0%, #ff670f 20%, #ffffff 50%, #0eea57 80%, #0eea57 100%);
background: -webkit-linear-gradient(135deg, #ff670f 0%, #ff670f 20%, #ffffff 50%, #0eea57 80%, #0eea57 100%);
}
#keyframes gra {
0% { left: -200%; top: -200%; }
50% { left: 0%; top: 0%; }
100% { left: -200%; top: -200%; }
}
<div class="animated">
<h1>Hello</h1>
<div class="innerGradient"></div>
</div>
I applied a drop-shadow filter on my clip-path, while the shadow works well on white background, it does not work at all on a darker one (example below) -
It just looks like some weird lines instead of a blurred shadow, The shadow is a bit darker then the background, making the shadow completly black makes it work at the start of the shadow but to the end it has these lines once again.
The code:
body {
margin: 0;
overflow-x: hidden;
height: 2000px;
}
body .headerText {
position: absolute;
top: 50vh;
left: 40vw;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
font-size: 8vh;
z-index: 10;
color: white;
mix-blend-mode: exclusion;
}
body .headerWrap {
position: fixed;
filter: drop-shadow(-30px -30px 60px #363636) drop-shadow(-30px -30px 90px #414141);
-webkit-filter: drop-shadow(-30px -30px 60px #363636) drop-shadow(-30px -30px 90px #414141);
}
body .headerWrap header {
position: fixed;
width: 100vw;
height: 100vh;
background-color: #2e2e2e;
-webkit-clip-path: polygon(0% 0%, 40% 0%, 28% 100%, 0% 100%);
clip-path: polygon(0% 0%, 40% 0%, 28% 100%, 0% 100%);
-webkit-animation: rotate 1s 1;
animation: rotate 1s 1;
-webkit-animation-play-state: paused;
animation-play-state: paused;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-delay: calc(var(--scroll) * -3s);
animation-delay: calc(var(--scroll) * -3s);
}
#-webkit-keyframes rotate {
to {
-webkit-clip-path: polygon(0% 0%, 20% 0%, 14% 100%, 0% 100%);
clip-path: polygon(0% 0%, 20% 0%, 14% 100%, 0% 100%);
}
}
#keyframes rotate {
to {
-webkit-clip-path: polygon(0% 0%, 20% 0%, 14% 100%, 0% 100%);
clip-path: polygon(0% 0%, 20% 0%, 14% 100%, 0% 100%);
}
}
body .landing {
width: 100vw;
height: 100vh;
background-color: white;
}
body .content {
width: 100vw;
height: 200vh;
background-color: #424242;
}
<html lang="en">
<head>
</head>
<body>
<div class="headerText"><h1>Hello bruddas</h1></div>
<div class="headerWrap">
<header></header>
</div>
<script>
window.addEventListener('scroll', () => {
document.body.style.setProperty('--scroll',window.pageYOffset / (document.body.offsetHeight - window.innerHeight));
}, false);
</script>
<div class="landing"></div>
<div class="content"></div>
</body>
Answer
The shadow works fine on both colors.
You can barely (or not...) see it, but it's there.
The lines are in fact the shadow.
The problem here, is the low amount of colors rendered by the screen due to the low contrast between the darkest and lightest colors (for the dark one).
Screens have a limited amount of colors. It also depends on the screen type and settings, sometimes you can easily see it (and it's ugly), sometimes you can barely notice that behavior (you just see a smooth gradient).
Example
Here is an example:
Notice I used the same shadow for both sides.
You should be able to see the lines on darker tones (the top of the left side, and all the right side). Maybe you cannot see the lines at all, again, it depends on the output device and settings.
I would like the moving overlay triangle in this fiddle to stretch its animation to fit the forest image. The problem as you see now is that it creates whitespace at the top and its moving the triangle instead of stretching it. If anyone got a smart solution please comment.
i tried modifying these values but can't get it working properly.
border-left: 47.5vw solid transparent;
border-right: 47.5vw solid transparent;
border-top: 95vh solid rgba(255, 255, 255, 0.2);
It doesn't work, because you have 95vw (2x 47.5) width of border(left/right), 95vh of border top and you just move it down with translate. I think that better way is to manipulate border-width in animation
#keyframes bounce {
0%, 20%, 50%, 80%, 100% {
border-left-width: 47.5vw;
border-right-width: 47.5vw;
left: 2.5vw;
border-top-width:95vh;
top: -5vh;
}
40% {
border-left-width: 50vw;
border-right-width: 50vw;
left: 0;
border-top-width: 100vh;
top: 0vh;
}
}
https://jsfiddle.net/2j29b9d4/
Just change the "bounce" animation. Add scale property.
.bounce {
-webkit-animation-name: bounce;
animation-name: bounce;
}
#-webkit-keyframes bounce {
0%, 20%, 50%, 80%, 100% {
-webkit-transform: translateY(0) scale(1);
}
40% {
-webkit-transform: translateY(10vh) scale(2);
}
}
#keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0) scale(1);
}
40% {
transform: translateY(10vh) scale(2);
}
}
https://jsfiddle.net/fbnwj3ag/5/
I want to move my gradient that has multiple colors smoothly but the problem is that the animation is not smooth. It just changes its position at every step.
<style>
.animated {
width: 300px;
height: 300px;
border: 1px solid black;
animation: gra 5s infinite;
animation-direction: reverse;
-webkit-animation: gra 5s infinite;
-webkit-animation-direction: reverse;
animation-timing-function: linear;
-webkit-animation-timing-function: linear;
}
#keyframes gra {
0% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(21%, #ff670f), color-stop(56%, #ffffff), color-stop(88%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 21%, #ffffff 56%, #0eea57 88%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 21%, #ffffff 56%, #0eea57 88%);
}
50% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(10%, #ff670f), color-stop(40%, #ffffff), color-stop(60%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 10%, #ffffff 40%, #0eea57 60%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 10%, #ffffff 40%, #0eea57 60%);
}
100% {
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%, #ff670f), color-stop(5%, #ff670f), color-stop(10%, #ffffff), color-stop(40%, #0eea57));
background: -webkit-linear-gradient(-45deg, #ff670f 0%, #ff670f 5%, #ffffff 10%, #0eea57 40%);
background: linear-gradient(135deg, #ff670f 0%, #ff670f 5%, #ffffff 10%, #0eea57 40%);
}
}
</style>
<div class="animated">
<h1>Hello</h1>
</div>
Is it possible to accomplish without using jQuery?
My jsfiddle link is https://jsfiddle.net/bAUK6
Please try this code:
#gradient
{
height:300px;
width:300px;
border:1px solid black;
font-size:30px;
background: linear-gradient(130deg, #ff7e00, #ffffff, #5cff00);
background-size: 200% 200%;
-webkit-animation: Animation 5s ease infinite;
-moz-animation: Animation 5s ease infinite;
animation: Animation 5s ease infinite;
}
#-webkit-keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
#-moz-keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
#keyframes Animation {
0%{background-position:10% 0%}
50%{background-position:91% 100%}
100%{background-position:10% 0%}
}
<html>
<div id="gradient">
Hello
</div>
</html>
Dynamic implementation of Dave's answer:
:root{
--overlay-color-1: #ff0000;
--overlay-color-2: #0000ff;
--anim-duration: 2s;
}
#gradient {
opacity: 0.8;
background: none;
}
#gradient:after,
#gradient:before {
content: '';
display: block;
position: absolute;
top: 0; bottom: 0; left: 0; right: 0;
}
#gradient:before {
background: linear-gradient(135deg, var(--overlay-color-2) 0%, var(--overlay-color-1) 100%);
animation: OpacityAnim var(--anim-duration) ease-in-out 0s infinite alternate;
}
#gradient:after {
background: linear-gradient(135deg, var(--overlay-color-1) 0%, var(--overlay-color-2) 100%);
animation: OpacityAnim var(--anim-duration) ease-in-out calc(-1 * var(--anim-duration)) infinite alternate;
}
#keyframes OpacityAnim {
0%{opacity: 1.0}
100%{opacity: 0.0}
}
<div id="gradient"></div>
Using CSS variables it's now a trivial task.
Here is a basic example (hover to see the result)
#property --a{
syntax: '<angle>';
inherits: false;
initial-value: 90deg;
}
#property --l{
syntax: '<percentage>';
inherits: false;
initial-value: 10%;
}
#property --c{
syntax: '<color>';
inherits: false;
initial-value: red;
}
.box {
/* needed for firefox to have a valid output */
--a:80deg;
--l:10%;
--c:red;
/**/
cursor:pointer;
height:200px;
transition:--a 0.5s 0.1s,--l 0.5s,--c 0.8s;
background:linear-gradient(var(--a), var(--c) var(--l),blue,var(--c) calc(100% - var(--l)));
}
.box:hover {
--a:360deg;
--l:40%;
--c:green;
}
<div class="box"></div>
More details here: https://dev.to/afif/we-can-finally-animate-css-gradient-kdk
How about this:
Set the body margin and padding to 0. Set an html rule to 100% height (higher than 100% may be required).
Set the body to the end state for the gradient.
Create an empty div with a background which is the start state for the gradient. Give the empty div 100% height.
Give both the body and the empty div a background-attachment: fixed;
Create a wrapper for your body content.
Set the empty div to position: fixed;
Set the wrapper to position: relative;
Give both a z-index, the wrapper being higher.
Create an animation that will change the opacity of the empty div from 1 to 0 over the desired time. Add animation-fill-mode:forwards; to the div rule so the animation stays where it ends.
It's not as sexy as a real animated gradient shift, but it's as simple as you can get with CSS only and keyframes, I think.
Here is another way. The following has the static gradient containing all phases of the animation, which is then moved inside the outer element. This allows to perform animation smoothly (as the topic suggests), because the only animation here is the element position.
Please note that for the sake of performance the gradient element left unchanged. Although the question was to animate the gradient, moving the background does practically the same thing, while the performance wins!
.animated {
width: 300px;
height: 300px;
overflow: hidden;
position: relative;
border: 1px solid black;
}
.innerGradient {
z-index: -1;
width: 300%;
height: 300%;
position: absolute;
animation: gra 5s infinite;
-webkit-animation: gra 5s infinite;
background: linear-gradient(135deg, #ff670f 0%, #ff670f 20%, #ffffff 50%, #0eea57 80%, #0eea57 100%);
background: -webkit-linear-gradient(135deg, #ff670f 0%, #ff670f 20%, #ffffff 50%, #0eea57 80%, #0eea57 100%);
}
#keyframes gra {
0% { left: -200%; top: -200%; }
50% { left: 0%; top: 0%; }
100% { left: -200%; top: -200%; }
}
<div class="animated">
<h1>Hello</h1>
<div class="innerGradient"></div>
</div>
I am trying to put a 100% color ribbon into the header of my website, similar to: http://mightyslider.com/
The color ribbon in the header is using simple css style that has all the info, colors, div position etc. I can create a color ribbon similar to this but it does not animate? Is there something out there jquery or CSS3 that is similar to it?
html:
<div id="header-colors"></div>
css:
#header-colors {
animation-delay: 0s;
animation-direction: reverse;
animation-duration: 15s;
animation-iteration-count: infinite;
animation-name: header-colors;
animation-timing-function: linear;
background-image: -moz-linear-gradient(left center , #f5aa00 0px, #f5aa00 12.5%, #55c5e9 12.5%, #55c5e9 25%, #6b3a78 25%, #6b3a78 37.5%, #9e1c32 37.5%, #9e1c32 50%, #0768bf 50%, #0768bf 62.5%, #629db1 62.5%, #629db1 75%, #f5aa00 75%, #f5aa00 87.5%, #55c5e9 87.5%, #55c5e9 100%);
background-size: 100% auto;
height: 10px;
left: 0;
position: absolute;
width: 100%;
}
Any help is appreciated.
It works fine?
Look at this jsfiddle I just made.
http://jsfiddle.net/89BuE/2/
HTML:
CSS:
#header-colors {
position: absolute;
top: 0;
left: 0;
height: 10px;
width: 100%;
background-image:-webkit-gradient(linear,0 50%,100% 50%,color-stop(0,#e75239),color-stop(12.5%,#e75239),color-stop(12.5%,#ff961c),color-stop(25%,#ff961c),color-stop(25%,#ffcc27),color-stop(37.5%,#ffcc27),color-stop(37.5%,#fce62f),color-stop(50%,#fce62f),color-stop(50%,#cde35b),color-stop(62.5%,#cde35b),color-stop(62.5%,#82cc33),color-stop(75%,#82cc33),color-stop(75%,#41bece),color-stop(87.5%,#41bece),color-stop(87.5%,#049cdb),color-stop(100%,#049cdb));
background-image:-moz-gradient(linear,0 50%,100% 50%,color-stop(0,#e75239),color-stop(12.5%,#e75239),color-stop(12.5%,#ff961c),color-stop(25%,#ff961c),color-stop(25%,#ffcc27),color-stop(37.5%,#ffcc27),color-stop(37.5%,#fce62f),color-stop(50%,#fce62f),color-stop(50%,#cde35b),color-stop(62.5%,#cde35b),color-stop(62.5%,#82cc33),color-stop(75%,#82cc33),color-stop(75%,#41bece),color-stop(87.5%,#41bece),color-stop(87.5%,#049cdb),color-stop(100%,#049cdb));
background-image: gradient(linear,0 50%,100% 50%,color-stop(0,#e75239),color-stop(12.5%,#e75239),color-stop(12.5%,#ff961c),color-stop(25%,#ff961c),color-stop(25%,#ffcc27),color-stop(37.5%,#ffcc27),color-stop(37.5%,#fce62f),color-stop(50%,#fce62f),color-stop(50%,#cde35b),color-stop(62.5%,#cde35b),color-stop(62.5%,#82cc33),color-stop(75%,#82cc33),color-stop(75%,#41bece),color-stop(87.5%,#41bece),color-stop(87.5%,#049cdb),color-stop(100%,#049cdb));
-webkit-animation: headercolors 15s linear 0s infinite;
animation: headercolors 15s linear 0s infinite;
}
#-webkit-keyframes headercolors {
from {
background-position:0 bottom;
}
to {
background-position:1600px bottom;
}
}
#keyframes headercolors {
from {
background-position:0 bottom;
}
to {
background-position:1600px bottom;
}
}
Basically the gradient background is treated as an image and you can simple move it by using background-position.
You need to specify a background image larger than the width, and then animate the position
CSS
#header-colors {
animation-direction: reverse;
animation: header-colors infinite 15s linear;
-webkit-animation: header-colors infinite 15s linear;
background-image: linear-gradient(to left, #f5aa00 0px, #f5aa00 12.5%, #55c5e9 12.5%, #55c5e9 25%, #6b3a78 25%, #6b3a78 37.5%, #9e1c32 37.5%, #9e1c32 50%, #0768bf 50%, #0768bf 62.5%, #629db1 62.5%, #629db1 75%, #f5aa00 75%, #f5aa00 87.5%, #55c5e9 87.5%, #55c5e9 100%);
background-size: 200% auto;
height: 20px;
left: 0;
position: absolute;
width: 100%;
}
#-webkit-keyframes header-colors {
0% {background-position-x: 0%;}
100% {background-position-x: 100%;}
}
#keyframes header-colors {
0% {background-position-x: 0%;}
100% {background-position-x: 100%;}
}
demo
Note: right now, it will jump at the end of the animation. To avoid that, you need to set 2 identical cycles of the color strips in the background image (so that one part overlaps the other at th end of the animation
In Firefox, background-position-x is not working. change this to make it work
#keyframes header-colors {
0% {background-position: 0% 0px;}
100% {background-position: 100% 0px;}
}