CSS3 animation won't stop on the last frame - css

I've got an issue where my sprite-sheet animation won't stop on the final frame - I've changed the animation-iteration-count to '1' and also changed the animation-fill-mode to 'forwards', but it doesn't appear to be working.
The animation doesn't revert back to the first frame either, it runs to the end, and then jumps back to the first frame in the last row of the sprite sheet.
So I feel like I'm almost there, but maybe I'm missing something?
I've put together an example here to demonstrate.
.container {
width: 64px;
height: 64px;
position: relative;
}
#-webkit-keyframes spritex {
0% {
background-position-x: 0%;
background-position-y: 0%;
}
20% {
background-position-x: -500%;
background-position-y: 0%;
}
20.01% {
background-position-x: 0%;
background-position-y: -100%;
}
40% {
background-position-x: -500%;
background-position-y: -100%;
}
40.01% {
background-position-x: 0%;
background-position-y: -200%;
}
60% {
background-position-x: -500%;
background-position-y: -200%;
}
60.01% {
background-position-x: 0%;
background-position-y: -300%;
}
80% {
background-position-x: -500%;
background-position-y: -300%;
}
80.01% {
background-position-x: 0%;
background-position-y: -400%;
}
99.99% {
background-position-x: -500%;
background-position-y: -400%;
}
100% {
background-position-x: -500%;
background-position-y: -400%;
}
}
.sprite {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url(http://i296.photobucket.com/albums/mm182/CodeH4x0r/explosion17.png);
background-size: 500% 500%;
-webkit-animation: spritex 3s steps(5) 1;
-webkit-animation-fill-mode: forwards;
animation: spritex 3s steps(5) 1;
animation-fill-mode: forwards;
}
}
<div class="container">
<div class="sprite"></div>
</div>
(View in Codepen)

Your positions are not correct.
The correct positions shouldn't get higher than 100%.
This are the correct ones
.container {
width: 64px;
height: 64px;
position: relative;
}
#-webkit-keyframes spritex {
0% {
background-position-x: 0%;
background-position-y: 0%;
}
20% {
background-position-x: 100%;
background-position-y: 0%;
}
20.01% {
background-position-x: 0%;
background-position-y: 25%;
}
40% {
background-position-x: 100%;
background-position-y: 25%;
}
40.01% {
background-position-x: 0%;
background-position-y: 50%;
}
60% {
background-position-x: 100%;
background-position-y: 50%;
}
60.01% {
background-position-x: 0%;
background-position-y: 75%;
}
80% {
background-position-x: 100%;
background-position-y: 75%;
}
80.01% {
background-position-x: 0%;
background-position-y: 100%;
}
100% {
background-position-x: 100%;
background-position-y: 100%;
}
}
.sprite {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url(http://i296.photobucket.com/albums/mm182/CodeH4x0r/explosion17.png);
background-size: 500% 500%;
-webkit-animation: spritex 3s steps(4) 1;
-webkit-animation-fill-mode: forwards;
animation: spritex 3s steps(4) 1;
animation-fill-mode: forwards;
}
}
<div class="container">
<div class="sprite"></div>
</div>

There are actually two problems here. First, you have an off-by-one error with the step function. The starting position shouldn't be included in number of steps passed to the step function.
From MDN:
steps(4, end)
The second problem is that you seem to have an incorrect idea of what percentage values in background-position represent. Again, from MDN:
The background-position CSS property sets the initial position,
relative to the background position layer defined by background-origin
for each defined background image.
[...]
Percentages refer to the size of the background positioning area minus
size of background image; size refers to the width for horizontal
offsets and to the height for vertical offsets
In this case, the "size of the background positioning area" is the size of the entire sprite sheet, and the "size of background image" is the size of one image in that sheet. So what that means in this case is that 100% is equal to the width of exactly 4 spaces in the sprite sheet (5 - 1), and therefore 25% is equal to the width of exactly one space in the sprite sheet.
This means that background-position-x: -500%; background-position-y: -400%; isn't where you think it is. That's why the sprite being displayed at the end of the animation is wrong.
So putting all this knowledge together, we end up with this:
.container {
width: 64px;
height: 64px;
position: relative;
}
#-webkit-keyframes spritex {
0% {
background-position-x: 0%;
background-position-y: 0%;
}
20% {
background-position-x: 100%;
background-position-y: 0%;
}
20.01% {
background-position-x: 0%;
background-position-y: 25%;
}
40% {
background-position-x: 100%;
background-position-y: 25%;
}
40.01% {
background-position-x: 0%;
background-position-y: 50%;
}
60% {
background-position-x: 100%;
background-position-y: 50%;
}
60.01% {
background-position-x: 0%;
background-position-y: 75%;
}
80% {
background-position-x: 100%;
background-position-y: 75%;
}
80.01% {
background-position-x: 0%;
background-position-y: 100%;
}
99.99% {
background-position-x: 100%;
background-position-y: 100%;
}
100% {
background-position-x: 100%;
background-position-y: 100%;
}
}
.sprite {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url(http://i296.photobucket.com/albums/mm182/CodeH4x0r/explosion17.png);
background-size: 500% 500%;
-webkit-animation: spritex 3s steps(4) 1;
-webkit-animation-fill-mode: forwards;
animation: spritex 3s steps(4) 1;
animation-fill-mode: forwards;
}
<div class="container">
<div class="sprite"></div>
</div>
(View in Codepen)

Related

read sprite css always in fullscreen size?

I try to animate a sprite with auto fullscreen size
but I don't know how can I do to read this sprite always in fullscreen (i.e. 100% of width and height of screen, and auto adapte if resizing)
any idea to autosize sprite ?
#-moz-keyframes play {
0% {
background-position: 0%;
}
100% {
background-position: 100%;
}
}
#-webkit-keyframes play {
0% {
background-position: 0%;
}
100% {
background-position: 100%;
}
}
#keyframes play {
0% {
background-position: 0%;
}
100% {
background-position: 100%;
}
}
#loader
{
position: fixed;
z-index: 999999999999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-repeat: no-repeat;
background-position: 0 0;
background-image: url(https://image.ibb.co/hCqoYz/preloader_bg_bw2.png);
background-size: 1100% 100%;
background-repeat: no-repeat;
-webkit-animation: play 2s infinite steps(11);
-moz-animation: play 2s infinite steps(11);
-o-animation: play 2s infinite steps(11);
animation: play 2s infinite steps(11);
}
<div id="loader"></div>
You're almost there!
There should be steps(10) as the start position is not a step actually.
BTW, z-index: 999999999999 looks paranoid to me =)).
#keyframes play {
100% {
background-position: 100%;
}
}
#loader
{
position: absolute;
z-index: 9;
top: 0; right:0;
bottom:0; left: 0;
background-position: 0 0;
background-image: url(https://image.ibb.co/hCqoYz/preloader_bg_bw2.png);
background-size: 1100% 100%;
background-repeat: no-repeat;
animation: play 1s infinite steps(10);
}
<div id="loader"></div>
Update
Question bonus:
#keyframes play {
99.99% {
background-position: 120%;
background-image: url(https://image.ibb.co/hCqoYz/preloader_bg_bw2.png);
}
100% {
background-image: none;
z-index: -1;
}
}
#loader {
position: fixed;
z-index: 9;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-position: 0 0;
background-image: url(https://image.ibb.co/hCqoYz/preloader_bg_bw2.png);
background-size: 1100% 100%;
background-repeat: no-repeat;
animation: play 2s steps(12) forwards;
}
body {
background: url(https://picsum.photos/640/480) 50% 50% /cover
<div id="loader"></div>

how to animate this css in 50% width of the window

hy guys this is a simple css background animation script everything is working fine but now i want to Set this background in 50% of the width of the window i tried a several way but i am not able to do this and now i am totally frustrated ... any kind of suggestion will help in my project thnx in advance.
<style>
body {
width: 100wh;
height: 90vh;
color: #fff;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
-webkit-animation: Gradient 15s ease infinite;
-moz-animation: Gradient 15s ease infinite;
animation: Gradient 15s ease infinite;
}
#-webkit-keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
#-moz-keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
#keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
h1,
h6 {
font-family: 'Open Sans';
font-weight: 300;
text-align: center;
position: absolute;
top: 45%;
right: 0;
left: 0;
}
</style>
<body>
<h1>Pure CSS3 Animated Gradient Background</h1>
</body>
</head>
Added an extra div with css properties
width: 50%;
height: 100%;
position: absolute;
left: 0;
top: 0;
to achieve 50% width and 100% height.
body {
width: 100wh;
height: 90vh;
color: #fff;;
}
.width-50 {
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
-webkit-animation: Gradient 15s ease infinite;
-moz-animation: Gradient 15s ease infinite;
animation: Gradient 15s ease infinite;
width: 50%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
#-webkit-keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
#-moz-keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
#keyframes Gradient {
0% {
background-position: 0% 50%
}
50% {
background-position: 100% 50%
}
100% {
background-position: 0% 50%
}
}
h1,
h6 {
font-family: 'Open Sans';
font-weight: 300;
text-align: center;
position: absolute;
top: 45%;
right: 0;
left: 0;
}
<body>
<div class="width-50">
<h1>Pure CSS3 Animated Gradient Background</h1>
</div>
</body>

Fixed Background Image Causing Unwanted Repositioning in iOS Safari?

I have a fixed background image within a div that will not display consistently in mobile Safari. It displays fine when a page is refreshed, but the main issue arises when I try to prompt backward and forward to other site pages, which causes the browser to reposition the background's origin point awkwardly.
Note: The first image shows the background image displaying correctly, while the second image displays the transform-origin shift that occurs upon navigating back/forward in the Safari mobile browser, (the main issue).
Here's a snippet, for further reference:
body,
html {
height: 100%;
width: 100%;
background-size: cover;
background-repeat: no-repeat;
}
body {
background: white;
margin: 0;
padding: 0;
border: 0;
outline: 0;
z-index: -2;
}
.sitebg {
background: url("http://maxpixel.freegreatpicture.com/static/photo/1x/Seamless-Repeating-Tiling-Tile-able-Tileable-1889447.jpg");
background-repeat: repeat;
background-position: center;
background-size: 720px 720px;
-webkit-animation: 180s rotatebg infinite linear;
-moz-animation: 180s rotatebg infinite linear;
-o-animation: 180s rotatebg infinite linear;
-ms-animation: 180s rotatebg infinite linear;
animation: 180s rotatebg infinite linear;
width: 750px;
height: 750px;
position: fixed;
top: 50%;
left: 50%;
}
.sitebg-parent {
position: absolute;
height: 100%;
width: 100%;
margin: auto;
padding: 0;
overflow: hidden;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
}
#-webkit-keyframes rotatebg {
0% {
-webkit-transform: rotate(0deg) translate(-50%, -50%);
-webkit-transform-origin: top left;
}
100% {
-webkit-transform: rotate(360deg) translate(-50%, -50%);
-webkit-transform-origin: top left;
}
}
#keyframes rotatebg {
0% {
transform: rotate(0deg) translate(-50%, -50%);
transform-origin: top left;
}
100% {
transform: rotate(360deg) translate(-50%, -50%);
transform-origin: top left;
}
}
<body>
<div class="sitebg-parent">
<div class="sitebg"></div>
</div>
</body>
Please try the code below.
I've slightly changed your code and removed unnecessary and ivalid css rules.
html, body {
height: 100%; width: 100%;
margin: 0; padding: 0;
}
.sitebg {
position: absolute;
top: 50%; left: 50%;
width: 2000px; height: 2000px;
margin: -1000px 0 0 -1000px;
background: url("http://s3.gomedia.us/wp-content/uploads/2008/06/skullbg-green.gif");
transform-origin: 50% 50%;
-webkit-animation: 180s rotatebg infinite linear;
animation: 180s rotatebg infinite linear;
}
.sitebg-parent {
position: absolute; z-index: -1;
top: 0; right: 0; bottom: 0; left: 0;
overflow: hidden;
}
#-webkit-keyframes rotatebg {
0% {-webkit-transform: rotateZ(0deg)}
100% {-webkit-transform: rotateZ(360deg)}
}
#keyframes rotatebg {
0% {transform: rotateZ(0deg)}
100% {transform: rotateZ(360deg)}
}
<body>
<div class="sitebg-parent">
<div class="sitebg"></div>
</div>
</body>

Why does this not animate?

I am trying to move a background but it seems quite stuck.
How can I move it?
body {
background-color: black !important;
}
#background_div {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: -1;
width: 100%;
height: 100%;
background-image: url("http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg");
background-position: center;
background-repeat: no-repeat;
animation-name: background_animation;
}
#keyframes background_animation {
0% {
transform: translate(0%, -100%) scale(4, 4);
}
25% {
transform: translate(100%, 0%) scale(5, 5);
}
50% {
transform: translate(50%, 100%) scale(6, 6);
}
100% {
transform: translate(0%, -100%) scale(4, 4);
}
}
<div id="background_div"></div>
https://jsfiddle.net/5he2otzL/
The problem in your case is that you've set only the animation-name to #background_div but have not set any value for the animation-duration. The default value for animation-duration is 0s and that for the animation-fill-mode is none. So, as per the spec, the animation has no visible effect.
Below is the extract from the specs: (emphasis is mine).
If the <time> is 0s, like the initial value, the keyframes of the animation have no effect, but the animation itself still occurs instantaneously. Specifically, start and end events are fired; if animation-fill-mode is set to backwards or both, the first frame of the animation, as defined by animation-direction, will be displayed during the animation-delay. Then the last frame of the animation, as defined by animation-direction, will be displayed if animation-fill-mode is set to forwards or both. If animation-fill-mode is set to none then the animation has no visible effect.
Once you set some value other than 0s to animation-duration property, the animation works fine.
body {
background-color: black !important;
}
#background_div {
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: -1;
width: 100%;
height: 100%;
background-image: url("http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg");
background-position: center;
background-repeat: no-repeat;
animation-name: background_animation;
animation-duration: 2s; /* set this */
}
#keyframes background_animation {
0% {
transform: translate(0%, -100%) scale(4, 4);
}
25% {
transform: translate(100%, 0%) scale(5, 5);
}
50% {
transform: translate(50%, 100%) scale(6, 6);
}
100% {
transform: translate(0%, -100%) scale(4, 4);
}
}
<div id="background_div"></div>
body {
background-color: black !important;
}
#background_div {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: -1;
width: 100%;
height: 100%;
background-image: url("http://www.codeproject.com/KB/GDI-plus/ImageProcessing2/img.jpg");
background-position: center;
background-repeat: no-repeat;
-webkit-animation: background_animation 5s infinite; /* Chrome, Safari, Opera */
animation: background_animation 5s infinite;
}
#keyframes background_animation {
0% {
transform: translate(0%,-100%) scale(4,4);
}
25% {
transform: translate(100%,0%) scale(5,5);
}
50% {
transform: translate(50%,100%) scale(6,6);
}
100% {
transform: translate(0%,-100%) scale(4,4);
}
}
Fixed it for you hope it helps,
Easy reads:
http://www.w3schools.com/cssref/css3_pr_animation.asp
https://jsfiddle.net/5he2otzL/

looping a CSS3 animation with multiple keyframes

I managed to make multiple key-frames in an animation play one after another
http://jsfiddle.net/NuMjW/
but can't make the whole loop, so currently it plays the sequence once and then its done, is there a way to make it loop without using jquery or javascript to restart it after n seconds have passed.
.hi {
width: 48px;
height: 48px;
background-image: url("http://s30.postimg.org/k4qce9z1r/warp.png");
-webkit-animation: play1 0.3s 0s steps(5) forwards, play2 0.3s 0.3s steps(5) forwards, play3 0.3s 0.6s steps(5) forwards; }
#-webkit-keyframes play1 { from { background-position-y: 0px; background-position-x: 0px; }
to { background-position-y: 0px; background-position-x: -240px; } } #-webkit-keyframes play2 { from { background-position-y: -48px; background-position-x: 0px; }
to { background-position-y: -48px; background-position-x: -240px; } } #-webkit-keyframes play3 { from { background-position-y: -96px; background-position-x: 0px; }
to { background-position-y: -96px; background-position-x: -240px; } }
figured it out myself have to merge the animation into one block use short time otherwise the scrolling of the background is visible between rows.
<style>
.hi {
width: 48px;
height: 48px;
background-image: url("warp.png");
-webkit-animation: play1 1s 0s steps(5) infinite;
}
#-webkit-keyframes play1 {
from { background-position-y: 0px; background-position-x: 0px; }
33% { background-position-y: 0px; background-position-x: -240px; }
33.0001% { background-position-y: -48px; background-position-x: 0px; }
66% { background-position-y: -48px; background-position-x: -240px; }
66.0001% { background-position-y: -96px; background-position-x: 0px; }
100% { background-position-y: -96px; background-position-x: -240px; }
}
</style>
<body>
<img src="warp.png" />
<br><br>
<div class="hi"></div>
</body>

Resources