CSS animation-iteration-count Property
This property defines how many times an animation cycle should play before it comes to a halt.
| infinite | Causes the animation to repeat forever without stopping. |
| <number> | A specific number of times the animation cycle plays, where 1 is the default and decimal values like 0.5 are allowed. |
Code Examples
A basic example showing a box that pulses three times and then stops.
<style>
.pulse-box {
width: 100px;
height: 100px;
background: #3498db;
animation-name: pulse;
animation-duration: 1s;
animation-iteration-count: 3;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.1); }
100% { transform: scale(1); }
}
</style>
<div class="pulse-box"></div>An advanced example using a loading spinner that runs infinitely until a user clicks a button to limit the remaining iterations.
<style>
.loader {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #e74c3c;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<div id="myLoader" class="loader"></div>
<button onclick="stopLoader()">Stop Loading</button>
<script>
function stopLoader() {
const el = document.getElementById("myLoader");
el.style.animationIterationCount = "2";
console.log("The loader will now stop after 2 more cycles.");
}
</script>Pro Tip
You can use JavaScript to listen for the animationiteration event to perform logic every time a cycle completes, or the animationend event to trigger a new state once your specific iteration count has been reached. This is great for chain-reacting animations in a complex UI.
Deep Dive
Think of this property as the repeat button on a media player. If you set it to 1, the track plays once and stops. If you set it to infinite, it loops until the user closes the page or the element is removed. A unique aspect is that it accepts decimal values. For instance, a value of 0.5 will play exactly half of your keyframes and then stop. When you have multiple animations assigned to one element, you can provide a comma-separated list of counts to map to each animation name respectively. This property works in tandem with animation-direction; if the direction is set to alternate, one full iteration consists of the animation running forward once and then backward once.
Best Practices
For most user interface feedback, like a shaking button or a notification pulse, stick to small whole numbers like 2 or 3. Use infinite sparingly, mainly for background decorative elements or loading indicators. Always ensure that if an animation stops, the final state of the element makes sense for the layout, usually by pairing this with the animation-fill-mode property.
Common Pitfalls
A common mistake is using a value of 0 thinking it will reset something, but it actually prevents the animation from running at all. Also, beginners often forget that if they use a non-integer value like 1.5, the element might stop in a visually awkward position mid-transition. If you find your animation isn't looping, check that you haven't misspelled infinite or accidentally applied a count of 1 in a shorthand property later in the CSS.
Accessibility
Constant movement can be a major distraction or even a health trigger for users with vestibular disorders. Use the prefers-reduced-motion media query to set the count to 1 or 0 for those users. Avoid using infinite for any element that contains important reading text, as it makes the content much harder to consume.
Dev Data Table: animation-iteration-count property
| default | 1 |
| animatable | no |
| inherited | no |
| experimental | no |
| year_intro | 2009 |
| year_standard | 2013 |
| js_syntax_1 | object.style.animationIterationCount = "3"; |
| js_syntax_2 | object.style.setProperty("animation-iteration-count", "infinite"); |
| js_note | When using JavaScript to manipulate this property, remember that the value is treated as a string, even when providing a numeric count. |
| browsers | { "Chrome": 43, "Edge": 12, "Firefox": 16, "Safari": 9, "Opera": 30, "Chrome Android": 43, "Safari on iOS": 9, "Samsung Internet": "4.0", "Opera Mobile": 30 } |