The CSS3 animation will continue running beyond the final frame

I am currently facing an issue with my sprite-sheet animation that is not stopping on the final frame. I have tried changing the animation-iteration-count to '1' and the animation-fill-mode to 'forwards', but unfortunately, it does not seem to be working.

The animation does not reset back to the first frame either; instead, it reaches the end and then abruptly jumps back to the initial frame in the last row of the sprite sheet.

It feels like I am close to resolving the issue, but I must be overlooking something?

To illustrate, I have created a demonstration example below:

.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)

Answer ā„–1

Your current positions are inaccurate. The correct positions should not exceed 100%.

These are the accurate 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>

Answer ā„–2

There appear to be two issues at play here. Firstly, there is an off-by-one error in the step function as the starting position should not be counted within the number of steps given to the function.

According to MDN:

steps(4, end)

The second problem arises from a misunderstanding about how percentage values work in the context of background-position. As explained on 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 scenario, the "size of the background positioning area" corresponds to the dimensions of the entire sprite sheet, while the "size of the background image" pertains to one image within that sheet. Therefore, 100% signifies the width of precisely 4 spaces within the sprite sheet (5 - 1), making 25% equivalent to the width of one space in the sheet.

This implies that

background-position-x: -500%; background-position-y: -400%;
does not indicate the intended location. Consequently, the displayed sprite at the conclusion of the animation appears incorrect.

Combining all this information yields the following solution:

.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%;
  }
  
  // More keyframes...

  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)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Upon launching my static page, the images mysteriously vanish or show up in a substandard resolution

My latest project involves creating a wedding website from scratch. The site features a simple parallax design with an abundance of images. I used only Html, CSS, and a touch of JavaScript to bring it to life. While testing the site on my local server, ev ...

Embedding a stylesheet into an HTML document can be done automatically

Currently, I am working on creating standalone error pages (404/503) as individual HTML files. My server-side setup involves Node.js, but these specific files will be hosted directly in Nginx. One of the challenges I am facing is automatically including a ...

Is it possible to adjust the JavaScript slider effect to transition to a fade effect when the window width drops below 800 pixels?

Is there a way to make my JavaScript slider change its effect from normal to fade when the browser window is less than 800px wide? Any assistance would be greatly appreciated. <ul class="slider"> <li><img src="images/1" alt=" ...

What is the correlation between using em font sizes and disrupting line-height?

I initially set my body element's font-size to 19px, and then started using em units for various elements. Unfortunately, I am experiencing irregularities with line-heights. For example, when I use a font-size of 0.6em, the line height becomes uneven ...

The scripts do not allow the image to be resized

Struggling to resize an image while implementing a hover effect with css and javascript. The code I have so far is: HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equ ...

Is Angular4 preloaded with bootstrap library?

I started a new angular4 project and wrote the code in app.component.html <div class="container"> <div class="row"> <div class="col-md-1">.col-md-1</div> <div class="col-md-1">.col-md-1</div> <div class ...

Ways to incorporate a dynamic HTML form that allows for input elements to be added both horizontally and vertically while maintaining connected lines

Looking to design a form that showcases HTML elements in both vertical and horizontal positions, with lines connecting them as seen in this example: https://i.sstatic.net/jB12f.png. Can anyone offer guidance on how to achieve this? Thanks! ...

Arranging th tags level and at equal height within a datable using HTML and CSS

I am looking to arrange my top headers in a table so that the red square icon is always next to the first span without using absolute positioning. Is there a way to achieve this without using absolute position? table.dataTable thead span.sort-icon { ...

center the form vertically, similar to how you would with text

I am struggling to vertically align my form on my website. Can someone assist me with this issue? I want my form to be vertically aligned in the same way as my text on the website. How can I achieve this? Here is the code snippet I am currently using: ht ...

Mastering the text overflow properties in Bootstrap's list-groupEver wished to control how

I am attempting to apply a text-overflow property to links within a bootstrap list-group. Each list item also includes a bootstrap badge floated to the right. However, when I add the text-overflow property, the link ends up going underneath the badge inste ...

Creating a personalized gradient using Tailwind CSS and Daisy UI framework

Iā€™m attempting to incorporate a unique gradient into my next.js application with the help of Tailwind CSS and Daisy UI. Below is the specific code snippet I plan on using: background: linear-gradient(180deg, rgba(192, 192, 192, 0.04) 0%, rgba(201, 180, ...

Angular reactive form CSS styling that necessitates the form to be both touched and invalid

Utilizing a reactive form for users to update their password. I aim to customize the input boxes to indicate any invalid submissions or errors. input.ng-invalid { border: 1px solid red; } An issue arises where the styling shows even before the user inte ...

Is it possible to display this code through printing rather than using an onclick event?

I have a puzzle website in the works where users select a puzzle to solve. I am looking for a way to display the puzzles directly on the website instead of using pop-up boxes. I am proficient in various coding languages, so any solution will work for me. ...

Guide to extending the bottom border of a DIV to exceed the bottom border of its parent element

I am working on a row of DIVs that resemble menu items. Each item is contained within a parent DIV. When an inside DIV is clicked, it receives the active class. The parent DIV has a 2px grey bottom border, while the active child DIV gets a 6px green bottom ...

Create movement for each individual point on a line that transitions to a new line using three.js

Looking to incorporate a dynamic animation into my project. The animation I envision involves a line transitioning to another line, with some deformation along the way. There is a clear correspondence between the points on both lines that need to be main ...

utilize a variable to insert the image URL into CSS styling

When I retrieve a product image URL from my database, I apply CSS styling to it on the front-end page. However, I need to dynamically pass the product image URL into the CSS that specifies the background image... Here is my current CSS: .product-image .bg ...

Navigate between links by using the Tab key, while excluding certain links from the sequence

On my webpage, I have a main menu, various links in the main content area, and a left menu. The challenge is to make the website accessible for people who are blind... When using the tab button to navigate between links, the order currently goes as follow ...

CSS Element Overlapping Issue in Safari Browser

I am currently developing an audio player for my application that includes a pause/play button, next button, and back button. I have encountered a problem specifically on Safari where the back/pause buttons are overlapping each other. The play/pause button ...

What is the best way to eliminate the border from a dropdown menu in bootstrap?

After copying and pasting a dropdown menu from bootstrap, I decided to experiment with it. Initially, I used the dropdown as a button, but then switched it to anchor tags. However, when I made this change, unwanted borders suddenly appeared and no matter w ...

Clicking on the accordion twice does not alter the position of the arrow

I have implemented an accordion using "up" and "down" arrows. It works well, but when I click on the panel title again, the arrow does not change direction. Here is the issue: In my scenario, I have used "A" and "B" instead of the arrows. When the page l ...