{"id":48758,"date":"2022-02-07T16:00:48","date_gmt":"2022-02-07T14:00:48","guid":{"rendered":"https:\/\/themeisle.com\/blog\/?p=48758"},"modified":"2025-07-22T14:31:19","modified_gmt":"2025-07-22T11:31:19","slug":"css-animations-tutorial","status":"publish","type":"post","link":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/","title":{"rendered":"CSS Animations Tutorial: Complete Guide for Beginners"},"content":{"rendered":"\n<p>This is a full syntax guide and interactive CSS animations tutorial for beginners. Use it as reference to learn the different parts of the CSS animations spec.<\/p>\n\n\n\n<p>Browser performance has come a long way. It used to be a lot more challenging to add interactive animations to web pages due to the potential for rendering and performance issues. But nowadays, CSS animations can be used much more freely and the syntax is generally much easier to learn compared to CSS features like grid or flexbox.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>There are different features that are part of the W3C CSS animation specification. Some easier to use than others. This CSS keyframe animations tutorial will go through all the syntax, including each of the different properties. I\u2019ll include interactive demos to help you grasp what\u2019s possible with CSS animations.<\/p>\n\n\n\n\t\t<div class='ti-tweet-clear'><\/div>\n\t\t\t<div class='ti-tweet_wrapper'>\n\t\t    \t<div class='ti-tweet_text'>\n\t\t    \t\t<a href='https:\/\/twitter.com\/share?text=%23CSS+animations+%23tutorial%3A+complete+guide+for+beginners+%F0%9F%90%9D&via=themeisle&related=themeisle&url=https:\/\/themeisle.com\/blog\/css-animations-tutorial\/' target='_blank' rel='nofollow'>#CSS animations #tutorial: complete guide for beginners \ud83d\udc1d<\/a>\n\t\t    \t<\/div>\n\t\t    \t<div class='ti-tweet_sharebtn'>\n\t\t    \t<a href='https:\/\/twitter.com\/share?text=%23CSS+animations+%23tutorial%3A+complete+guide+for+beginners+%F0%9F%90%9D&via=themeisle&related=themeisle&url=https:\/\/themeisle.com\/blog\/css-animations-tutorial\/' target='_blank' rel='nofollow'>Click To Tweet \n\t\t    \t\t<span><\/span>\n\t\t    \t<\/a>\n\t\t    <\/div>\n\t\t<\/div>\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">The @keyframes syntax<\/h2>\n\n\n\n<p>Every CSS animation has two parts to it: One or more <code>animation-*<\/code> properties along with a set of animation keyframes that are defined using the <code>@keyframes<\/code> at-rule. Let\u2019s take a look in detail at what goes into building a <code>@keyframes<\/code> rule set.<\/p>\n\n\n\n<p>The syntax looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@keyframes moveObject {\n  0% {\n    transform: translateX(0);\n  }\n\n  50% {\n     transform: translateX(300px);\n  }\n\n  100% {\n    transform: translateX(300px) scale(1.5);\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>As shown here, the <code>@keyframes<\/code> at-rule includes three basic parts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The <code>@keyframes<\/code> rule followed by a custom animation name<\/li>\n\n\n\n<li>A set of curly braces wrapping all the keyframes<\/li>\n\n\n\n<li>One or more keyframes, each with a percentage followed by a rule set surrounded by curly braces<\/li>\n<\/ul>\n\n\n\n<p>In this first example of our CSS animations tutorial, I\u2019ve defined my animation with the name <code>moveObject<\/code>. This can be any name I want, is case sensitive, and must abide by the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/CSS\/custom-ident\" target=\"_blank\" rel=\"noopener\">custom identifier<\/a> rules in CSS. This custom name must match the name used in the <code>animation-name<\/code> property (discussed later).<\/p>\n\n\n\n<p>In my example, you\u2019ll notice I used percentages to define each of the keyframes in my animation. If my animation includes keyframes that equal <code>0%<\/code> and <code>100%<\/code>, I can alternatively use the <code>from<\/code> and <code>to<\/code> keywords:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>@keyframes moveObject {\n  from {\n    transform: translateX(0);\n  }\n\n  50% {\n     transform: translateX(300px);\n  }\n\n  to {\n    transform: translateX(300px) scale(1.5);\n  }\n}\n<\/code><\/pre>\n\n\n\n<p>The following interactive CodePen uses the above syntax in a live example:<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the @keyframes At-rule\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/BamBEyZ?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"420\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/BamBEyZ\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the @keyframes At-rule<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n\n<p>In the demo, I\u2019ve included a button that resets the animation. I\u2019ll explain later why this is needed. But for now, just know that this animation includes three keyframes that represent steps in this animation sequence: the start, the 50% step, and the end (i.e., 0%, 50%, and 100%). Each of these uses what\u2019s called a keyframe selector along with curly braces to define the properties at that step.<\/p>\n\n\n\n<p>Some things to note about the <code>@keyframes<\/code> syntax:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You can put the keyframe rule sets in any order you want, and the browser will still run them in the order determined by their percentage<\/li>\n\n\n\n<li>You can omit the 0% and 100% keyframes and the browser will automatically determine these by the existing styles on the element being animated<\/li>\n\n\n\n<li>If there are duplicate keyframes with different rule sets (e.g., two keyframes for 20% with a different transform value), the browser uses the last one<\/li>\n\n\n\n<li>You can define multiple keyframes in a single keyframe selector with a comma: <code>10%, 30% { ... }<\/code><\/li>\n\n\n\n<li>The <code>!important<\/code> keyword nullifies any property value so it should not be used on a property inside a keyframe rule set<\/li>\n<\/ul>\n\n\n\n<p>\ud83d\udc49 Now that you have a good understanding of the <code>@keyframes<\/code> syntax in this CSS animation tutorial, let\u2019s take a look at the different animation properties that are defined on the element being animated.<\/p>\n\n\n\n<p><strong>The animation properties that we&#8217;re going to cover:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#the-animation-name-property\">The <em>animation-name<\/em> property<\/a><\/li>\n\n\n\n<li><a href=\"#the-animation-duration-property\">The <em>animation-duration<\/em> property<\/a><\/li>\n\n\n\n<li><a href=\"#the-animation-timing-function-property\">The <em>animation-timing-function<\/em> property<\/a><\/li>\n\n\n\n<li><a href=\"#the-animation-iteration-count-property\">The <em>animation-iteration-count<\/em> property<\/a><\/li>\n\n\n\n<li><a href=\"#the-animation-direction-property\">The <em>animation-direction<\/em> property<\/a><\/li>\n\n\n\n<li><a href=\"#the-animation-play-state-property\">The <em>animation-play-state<\/em> property<\/a><\/li>\n\n\n\n<li><a href=\"#the-animation-delay-property\">The <em>animation-delay<\/em> property<\/a><\/li>\n\n\n\n<li><a href=\"#the-animation-fill-mode-property\">The <em>animation-fill-mode<\/em> property<\/a><\/li>\n\n\n\n<li><a href=\"#the-animation-shorthand-property\">The <em>animation<\/em> shorthand property<\/a><\/li>\n\n\n\n<li><a href=\"#applying-multiple-animations-to-a-single-element\">Applying multiple animations to a single element<\/a><\/li>\n<\/ul>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-name-property\">The <em>animation-name<\/em> property<\/h2>\n\n\n\n<p>As mentioned, every CSS animation you create has to have a name that appears in the <code>@keyframes<\/code> syntax. This name has to be the same name defined using the <code>animation-name<\/code> property.<\/p>\n\n\n\n<p>Using the CSS from the previous demo, the syntax looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-name: moveObject;\n}\n<\/code><\/pre>\n\n\n\n<p>Again, the custom name that I\u2019ve defined has to also exist as a name for a <code>@keyframes<\/code> at-rule \u2014 otherwise this name will do nothing. You can think of this like a function call in JavaScript. The function itself would be the <code>@keyframes moveObject {}<\/code> portion of the code, while the function call is <code>animation-name: moveObject<\/code>.<\/p>\n\n\n\n<p>Some things to keep in mind about <code>animation-name<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The initial value for <code>animation-name<\/code> is <code>none<\/code>, which means no keyframes are active. This can be used as a sort of \u2018toggle\u2019 to deactivate an animation.<\/li>\n\n\n\n<li>Your chosen name is case-sensitive and can include letters, numbers, underscores, and hyphens.<\/li>\n\n\n\n<li>First character in the name must be a letter or a hyphen, but only a single hyphen.<\/li>\n\n\n\n<li>The name can\u2019t be a reserved word like <code>unset<\/code>, <code>initial<\/code>, or <code>inherit<\/code>.<\/li>\n<\/ul>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-duration-property\">The <em>animation-duration<\/em> property<\/h2>\n\n\n\n<p>The <code>animation-duration<\/code> property, no surprise, defines the amount of time an animation takes to run once from start to end. This value can be specified in seconds or milliseconds, as shown below:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-duration: 2s;\n}\n<\/code><\/pre>\n\n\n\n<p>The above would be the equivalent to the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-duration: 2000ms;\n}\n<\/code><\/pre>\n\n\n\n<p>You can see the <code>animation-duration<\/code> property in action in the following CodePen demo. In this demo, you can choose how long you want the animation to last. Try entering various values in either seconds or milliseconds, then use the \u201cAnimate the Box\u201d button to run the animation.<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the animation-duration Property\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/rNYNBwM?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"505\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/rNYNBwM\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the animation-duration Property<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n\n<p>If you use a small number along with <code>ms<\/code> for the unit, you may not even notice any movement. Try setting a higher number if you&#8217;re using milliseconds.<\/p>\n\n\n\n<p>Some notes on using <code>animation-duration<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Negative values are invalid<\/li>\n\n\n\n<li>The unit must be included, even if the duration is set to <code>0s<\/code> (the initial value)<\/li>\n\n\n\n<li>You can use fractional values (e.g., <code>0.8s<\/code>)<\/li>\n<\/ul>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-timing-function-property\">The <em>animation-timing-function<\/em> property<\/h2>\n\n\n\n<p>The <code>animation-timing-function<\/code>, which is not as obvious in its meaning as the previous two properties, is used to define the manner in which the CSS animation progresses. That might not be the clearest explanation, but the syntax might help clarify.<\/p>\n\n\n\n<p>The declaration looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-timing-function: linear;\n}\n<\/code><\/pre>\n\n\n\n<p>This property accepts the following keyword values:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>ease<\/code> (the initial value)<\/li>\n\n\n\n<li><code>ease-in<\/code><\/li>\n\n\n\n<li><code>ease-out<\/code><\/li>\n\n\n\n<li><code>ease-in-out<\/code><\/li>\n\n\n\n<li><code>linear<\/code><\/li>\n\n\n\n<li><code>step-start<\/code><\/li>\n\n\n\n<li><code>step-end<\/code><\/li>\n<\/ul>\n\n\n\n<p>Most of the values are relatively easy to grasp by their names, but you can see how they differ by using the following interactive demo:<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the animation-timing-function Keywords\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/wvPvwYV?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"517\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/wvPvwYV\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the animation-timing-function Keywords<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n\n<p>Use the select input to choose one of the seven keyword values. Note that the <code>ease-*<\/code> values \u2018ease\u2019 the animation in various ways. A linear value is consistent all the way through.<\/p>\n\n\n\n<p>The <code>animation-timing-function<\/code> property also accepts the following functions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>cubic-bezier()<\/code> &#8211; Accepts as arguments four number values, separated by commas<\/li>\n\n\n\n<li><code>steps()<\/code> &#8211; Accepts as arguments two values, a number and a \u201cjump term,\u201d separated by a comma<\/li>\n<\/ul>\n\n\n\n<p>The keyword values <code>step-start<\/code> and <code>step-end<\/code> are equivalent to the values <code>steps(1, jump-start)<\/code> and <code>steps(1, jump-end)<\/code>, respectively.<\/p>\n\n\n\n<p>As for <code>cubic-bezier()<\/code>, the following interactive demo might help you understand the function a little better:<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the cubic-bezier() Function\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/mdqddON?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"495\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/mdqddON\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the cubic-bezier() Function<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n\n<p>Notice the demo lets you set the four arguments in the <code>cubic-bezier()<\/code> function. Two of the arguments can be negative, and two are constrained to decimal values between 0 and 1. For a decent explanation of how these types of timing functions work, you can check out <a href=\"https:\/\/www.quackit.com\/css\/functions\/css_cubic-bezier_function.cfm\" target=\"_blank\" rel=\"noopener\">this article<\/a> or <a href=\"https:\/\/cubic-bezier.com\/\" target=\"_blank\" rel=\"noopener\">this interactive tool<\/a>.<\/p>\n\n\n\n<p>The <code>steps()<\/code> function, on the other hand, accepts two arguments:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An integer representing equal \u201cstops\u201d along a single cycle of the animation.<\/li>\n\n\n\n<li>An optional keyword called a \u201cjumpterm\u201d that determines whether the animation \u201cholds\u201d at specific intervals<\/li>\n<\/ul>\n\n\n\n<p>Again, an interactive demo should help you grasp how these jumpterms work:<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the steps() Function\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/VwrwMXX?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"414\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/VwrwMXX\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the steps() Function<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n\n<p>Try selecting an integer along with a jumpterm (or try it with no jumpterm) to see how the different keywords differ with different integer values. Apparently negative integers are permitted but I don\u2019t see any difference between 0 and any negative value.<\/p>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-iteration-count-property\">The <em>animation-iteration-count<\/em> property<\/h2>\n\n\n\n<p>In some cases, you\u2019ll be happy if an animation runs once, but sometimes you want an animation to run multiple times. The <code>animation-iteration-count<\/code> property lets you do this by accepting a positive number representing the number of times you want the animation to run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-iteration-count: 3;\n}\n<\/code><\/pre>\n\n\n\n<p>The initial value for <code>animation-iteration-count<\/code> is <code>1<\/code> but you can also use the keyword <code>infinite<\/code> (self-explanatory) or use a fractional value. A fractional value will run the animation part way through on the fractional run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-iteration-count: 3.5;\n}\n<\/code><\/pre>\n\n\n\n<p>The above code runs through the animation three and a half times. That is, three full iterations followed by one final iteration that stops exactly halfway through.<\/p>\n\n\n\n<p>This property is most useful when used in conjunction with the <code>animation-direction<\/code> property (discussed next), because an animation that runs from the beginning only is not extremely useful if it runs more than once.<\/p>\n\n\n\n<p>You can try the demo below which allows you to select a fractional value for the iteration count, so you can see the effect:<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the animation-iteration-count Property\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/qBVBozG?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"451\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/qBVBozG\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the animation-iteration-count Property<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-direction-property\">The <em>animation-direction<\/em> property<\/h2>\n\n\n\n<p>As mentioned above in this CSS animations tutorial, the <code>animation-direction<\/code> property works nicely in conjunction with <code>animation-iteration-count<\/code>. The <code>animation-direction<\/code> property allows you to define which direction you want the animation to play. The syntax looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-direction: alternate;\n}\n<\/code><\/pre>\n\n\n\n<p>You can set the value as one of four keywords:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>normal<\/code> &#8211; The animation plays forwards on the first iteration (the default)<\/li>\n\n\n\n<li><code>reverse<\/code> &#8211; Animation plays backwards on the first iteration<\/li>\n\n\n\n<li><code>alternate<\/code> &#8211; The animation plays forwards on the first iteration then alternates on subsequent iterations<\/li>\n\n\n\n<li><code>alternate-reverse<\/code> &#8211; Same as <code>alternate<\/code> but plays backwards on the first iteration<\/li>\n<\/ul>\n\n\n\n<p>You can try out the different values with different iteration counts using the interactive demo below:<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the animation-direction Property\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/PoOoaXL?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"480\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/PoOoaXL\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the animation-direction Property<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-play-state-property\">The <em>animation-play-state<\/em> property<\/h2>\n\n\n\n<p>The <code>animation-play-state<\/code> property is not extremely useful in a static CSS environment but might come in handy when writing animations that are interactive via JavaScript or even <a href=\"https:\/\/themeisle.com\/blog\/css\/\">CSS<\/a>.<\/p>\n\n\n\n<p>This property accepts two values: <code>running<\/code> or <code>paused<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-direction: paused;\n}\n<\/code><\/pre>\n\n\n\n<p>By default, any given animation is in the \u201crunning\u201d state. But you can use JavaScript to toggle the property\u2019s value. You could even feasibly use an interactive CSS feature like <code>:hover<\/code> or <code>:focus<\/code> to change the animation to a \u201cpaused\u201d state, which essentially freezes the animation wherever it is in the current iteration.<\/p>\n\n\n\n<p>The interactive demo below has an animation running infinitely with two buttons to \u201cpause\u201d and \u201cresume\u201d the animation.<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the animation-play-state Property\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/LYOYBWg?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"442\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/LYOYBWg\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the animation-play-state Property<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-delay-property\">The <em>animation-delay<\/em> property<\/h2>\n\n\n\n<p>Some animations are designed to start animating immediately, whereas others could benefit from a slight delay before the first iteration. The <code>animation-delay<\/code> property allows you to accomplish this.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-delay: 4s;\n}\n<\/code><\/pre>\n\n\n\n<p>Like other time-based values, you can set the <code>animation-delay<\/code> to a value using seconds or milliseconds. You can also use fractional values.<\/p>\n\n\n\n<p>It\u2019s important to note that the delay occurs only on the first iteration, not each iteration. You can try this out using the interactive demo below:<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the animation-delay Property\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/vYWYajo?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"476\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/vYWYajo\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the animation-delay Property<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n\n<p>The demo gives you the option to change the iteration value as well as the delay, so you can see that the delay doesn\u2019t affect any subsequent iterations \u2013 only the first.<\/p>\n\n\n\n<p>An interesting way of using this property is with a negative value. For example, using the demo above, try setting the <code>animation-delay<\/code> to <code>-0.5s<\/code>. You\u2019ll notice the negative delay works almost like going forwards in a time machine \u2013 the animation begins part way through rather than at the beginning.<\/p>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-fill-mode-property\">The <em>animation-fill-mode<\/em> property<\/h2>\n\n\n\n<p>The final longhand property that I\u2019ll cover in this CSS animations tutorial is one that I used in the previous demo. You\u2019ll notice that when the animation stops the final iteration, the box remains where it is. This is accomplished using <code>animation-fill-mode<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-fill-mode: forwards;\n}\n<\/code><\/pre>\n\n\n\n<p>This property sets how an animation applies styles to the targeted element before and after its execution. That\u2019s a little hard to grasp conceptually, so I\u2019ll cover the meaning of each value; then you can compare the values using the interactive demo.<\/p>\n\n\n\n<p>This property accepts the following four keyword values:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>none<\/code> &#8211; The default, no styles applied before or after execution<\/li>\n\n\n\n<li><code>forwards<\/code> &#8211; Retains all styles applied in the last keyframe of the animation<\/li>\n\n\n\n<li><code>backwards<\/code> &#8211; More or less the reverse of the previous value, it retains styles applied to the animation as soon as it begins execution but before the animation begins<\/li>\n\n\n\n<li><code>both<\/code> &#8211; Retains styles for both <code>forwards<\/code> and <code>backwards<\/code><\/li>\n<\/ul>\n\n\n\n<p>The final demo in this CSS animations tutorial will make things a little clearer, but this one might take a lot of playing around before you really get what it does and how it achieves it.<\/p>\n\n\n\n<iframe style=\"width: 100%;\" scrolling=\"no\" title=\"CSS Animations: the animation-fill-mode Property\" src=\"https:\/\/codepen.io\/impressivewebs\/embed\/ZEaEMgg?default-tab=result\" loading=\"lazy\" allowtransparency=\"true\" allowfullscreen=\"true\" height=\"528\" frameborder=\"no\">\nSee the Pen <a href=\"https:\/\/codepen.io\/impressivewebs\/pen\/ZEaEMgg\" target=\"_blank\" rel=\"noopener nofollow\">CSS Animations: the animation-fill-mode Property<\/a> by Louis Lazaris on CodePen.\n<\/iframe>\n\n\n\n<p><em>For convenience, I&#8217;ve added all the demos into <a href=\"https:\/\/codepen.io\/collection\/xKZEaN\" target=\"_blank\" rel=\"noopener\">a single CodePen Collection<\/a>.<\/em><\/p>\n\n\n\n<p>You\u2019ll notice that the demo lets you adjust the fill mode, delay, direction, and number of iterations, as all of these can have an effect on the appearance. I\u2019ve also added a different background color to the animated box in the first keyframe, which again helps to make the fill mode values a little more clear. If you still don\u2019t quite get how <code>animation-fill-mode<\/code> works, you can check out <a href=\"https:\/\/www.sitepoint.com\/understanding-css-animation-fill-mode-property\/\" target=\"_blank\" rel=\"noopener nofollow\">an older article<\/a> I wrote that discusses <code>animation-fill-mode<\/code> in-depth.<\/p>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-animation-shorthand-property\">The <em>animation<\/em> shorthand property<\/h2>\n\n\n\n<p>I\u2019ve covered eight different properties in this CSS animation tutorial for beginners and I encourage you to use the long hand. This will make it easier for you to see the explicit values set.<\/p>\n\n\n\n<p>Once you have a good understanding of each of the properties, you have the option to use the <code>animation<\/code> shorthand property, which lets you define all the longhand properties in a single declaration.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation: moveObject 2s ease-in-out 3 reverse running 1.3s forwards;\n}\n<\/code><\/pre>\n\n\n\n<p>In all honesty, that\u2019s a lot of information in a single line. I would recommend using the shorthand if the declaration doesn\u2019t include all the properties, but maybe only three or four of them.<\/p>\n\n\n\n<p>If you do use the shorthand, you can put the values in any order you want, but note the following rules:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The first value that defines time is the <code>animation-duration<\/code>; any subsequent time value is the <code>animation-delay<\/code>.<\/li>\n\n\n\n<li>If there is a conflict between a keyword and the <code>animation-name<\/code>, the keyword value will take precedence if it appears first.<\/li>\n\n\n\n<li>Any omitted values will fall back to their initial state, as with any CSS shorthand property.<\/li>\n<\/ul>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"applying-multiple-animations-to-a-single-element\">Applying multiple animations to a single element<\/h2>\n\n\n\n<p>One final feature it\u2019s good to be aware of is that you have the option to apply multiple animations to a single object by comma-separating the animations.<\/p>\n\n\n\n<p>Here\u2019s an example using the shorthand:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation: moveObject 2s ease-in-out, fadeBox 3s linear;\n}\n<\/code><\/pre>\n\n\n\n<p>Here, I\u2019ve defined two different animations that would map to two different sets of keyframes, but would apply to the same object. That same code could be written in longhand as:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.box {\n  animation-name: moveObject, fadeBox;\n  animation-duation: 2s, 3s;\n  animation-timing-function: ease-in-out, linear;\n}\n<\/code><\/pre>\n\n\n\n<p>Notice how each property includes two values separated by commas. In this instance, the shorthand would almost definitely be easier to read and maintain.<\/p>\n\n\n<div class=\"su-divider su-divider-style-dotted\" style=\"margin:40px 0;border-width:1px;border-color:#999999\"><a href=\"#\" style=\"color:#999999\">Go to top<\/a><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping up this CSS animations tutorial<\/h2>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:60%\">\n<p>If you\u2019re a CSS beginner and this CSS animations tutorial was your first dip into experimenting with moving stuff on web pages, I hope the lesson was comprehensive enough. You might even be able to incorporate <a href=\"https:\/\/wpshout.com\/css-variables\/\" target=\"_blank\" rel=\"noopener\">CSS variables<\/a> with animations to make them even more powerful.<\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:40%\">\n\t\t<div class='ti-tweet-clear'><\/div>\n\t\t\t<div class='ti-tweet_wrapper'>\n\t\t    \t<div class='ti-tweet_text'>\n\t\t    \t\t<a href='https:\/\/twitter.com\/share?text=%23CSS+animations+%23tutorial%3A+complete+guide+for+beginners+%F0%9F%90%9D&via=themeisle&related=themeisle&url=https:\/\/themeisle.com\/blog\/css-animations-tutorial\/' target='_blank' rel='nofollow'>#CSS animations #tutorial: complete guide for beginners \ud83d\udc1d<\/a>\n\t\t    \t<\/div>\n\t\t    \t<div class='ti-tweet_sharebtn'>\n\t\t    \t<a href='https:\/\/twitter.com\/share?text=%23CSS+animations+%23tutorial%3A+complete+guide+for+beginners+%F0%9F%90%9D&via=themeisle&related=themeisle&url=https:\/\/themeisle.com\/blog\/css-animations-tutorial\/' target='_blank' rel='nofollow'>Click To Tweet \n\t\t    \t\t<span><\/span>\n\t\t    \t<\/a>\n\t\t    <\/div>\n\t\t<\/div>\n<\/div>\n<\/div>\n\n\n\n<p>\ud83d\udc49 One final warning: Use animation in moderation and remember that some web users might be negatively affected by blinking colors and other fast-moving objects.<\/p>\n\n\n<div class=\"su-note\"  style=\"border-color:#e5e1b2;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\"><div class=\"su-note-inner su-u-clearfix su-u-trim\" style=\"background-color:#FFFBCC;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\">\n\n\n\n<p>With practice, the syntax and the concepts for building CSS animations will stick with you and you\u2019ll definitely benefit from fiddling around with the code in the different demos.<\/p>\n\n\n<\/div><\/div>\n\n\n<style>.ticss-d144f107 strong{font-weight: 700;\n    letter-spacing: -0.2px;\n    line-height: 1.2;\n    display: inline-block;}<\/style>\n\n\n<div class=\"wp-block-columns speed-guide has-white-color has-text-color has-background has-link-color wp-elements-2f81f6c5526477b5b4d52d1ca4513949 is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\" style=\"background-color:#4267cf\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:40%\">\n<figure class=\"wp-block-image size-medium\"><img data-opt-id=30701221  fetchpriority=\"high\" decoding=\"async\" width=\"300\" height=\"300\" src=\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:300\/h:300\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png\" alt=\"speed guide\" class=\"wp-image-113040\" srcset=\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:300\/h:300\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 300w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:1024\/h:1024\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 1024w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:150\/h:150\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 150w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:768\/h:768\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 768w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:50\/h:50\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 50w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:240\/h:240\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 240w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:397\/h:397\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 397w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:600\/h:600\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 600w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:148\/h:148\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 148w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:195\/h:195\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 195w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:135\/h:135\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 135w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:1080\/h:1080\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 1200w, https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:1080\/h:1080\/q:mauto\/f:best\/dpr:2\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2025\/09\/e2ce20299a807336c68c2e029640adaa1.png 2x\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p class=\"has-text-align-center ticss-58e79f2f\" style=\"font-size:14px\"><strong>FREE GUIDE<\/strong><\/p>\n\n\n\n<p class=\"ticss-d144f107\" style=\"font-size:25px\"><strong>4 Essential Steps to Speed Up Your&nbsp;WordPress Website<\/strong><\/p>\n\n\n\n<p class=\"ticss-3b627beb\">Follow the simple steps in our 4-part mini series and reduce your loading times by 50-80%.&nbsp;\ud83d\ude80<\/p>\n\n\n<p><div class=\"frm_forms  with_frm_style frm_style_themeisle\" id=\"frm_form_4_container\" data-token=\"c4c81c24bdb79c507973b64107966d8d\">\n<form enctype=\"multipart\/form-data\" method=\"post\" class=\"frm-show-form  frm_pro_form \" id=\"form_site-speed-guide-below-post\" data-token=\"c4c81c24bdb79c507973b64107966d8d\">\n<div class=\"frm_form_fields \">\n<fieldset>\n<legend class=\"frm_screen_reader\">Site Speed Guide - Below Post<\/legend>\r\n\r\n<div class=\"frm_fields_container\">\n<input type=\"hidden\" name=\"frm_action\" value=\"create\" \/>\n<input type=\"hidden\" name=\"form_id\" value=\"4\" \/>\n<input type=\"hidden\" name=\"frm_hide_fields_4\" id=\"frm_hide_fields_4\" value=\"\" \/>\n<input type=\"hidden\" name=\"form_key\" value=\"site-speed-guide-below-post\" \/>\n<input type=\"hidden\" name=\"item_meta[0]\" value=\"\" \/>\n<input type=\"hidden\" id=\"frm_submit_entry_4\" name=\"frm_submit_entry_4\" value=\"4ba3cb1e2c\" \/><input type=\"hidden\" name=\"_wp_http_referer\" value=\"\/blog\/wp-json\/wp\/v2\/posts\/48758\" \/><input type=\"hidden\" name=\"item_meta[18]\" id=\"field_6px6q2\" value=\"\/blog\/wp-json\/wp\/v2\/posts\/48758\"  data-frmval=\"\/blog\/wp-json\/wp\/v2\/posts\/48758\"   \/>\n<div id=\"frm_field_15_container\" class=\"frm_form_field form-field  frm_required_field frm_none_container\">\r\n\t<label for=\"field_6px6q\" id=\"field_6px6q_label\" class=\"frm_primary_label\">Your Email\r\n\t\t<span class=\"frm_required\" aria-hidden=\"true\">*<\/span>\r\n\t<\/label>\r\n\t<input type=\"email\" id=\"field_6px6q\" name=\"item_meta[15]\" value=\"\"  autocomplete=\"email\"  placeholder=\"your@email.com\" data-reqmsg=\"Your Email cannot be blank.\" aria-required=\"true\" data-invmsg=\"Your Email is invalid\" aria-invalid=\"false\"  \/>\r\n\t\r\n\t\r\n<\/div>\n<div id=\"frm_field_17_container\" class=\"frm_form_field form-field  frm_none_container vertical_radio\">\r\n\t<div  id=\"field_6px6q3_label\" class=\"frm_primary_label\">Subscribe to our newsletter\r\n\t\t<span class=\"frm_required\" aria-hidden=\"true\"><\/span>\r\n\t<\/div>\r\n\t<div class=\"frm_opt_container\" aria-labelledby=\"field_6px6q3_label\" role=\"group\">\t\t<div class=\"frm_checkbox\" id=\"frm_checkbox_17-0\">\t\t\t<label  for=\"field_6px6q3-0\">\n\t\t\t<input type=\"checkbox\" name=\"item_meta[17][]\" id=\"field_6px6q3-0\" value=\"true\"  data-invmsg=\"Subscribe to our newsletter is invalid\" aria-invalid=\"false\"   \/> Subscribe to our newsletter<\/label><\/div>\n<\/div>\r\n\t\r\n\t\r\n<\/div>\n<div id=\"frm_field_14_container\" class=\"frm_form_field form-field \">\r\n\t<div class=\"frm_submit frm_flex\">\r\n<button class=\"frm_button_submit frm_final_submit\" type=\"submit\"   formnovalidate=\"formnovalidate\">FREE ACCESS<\/button>\r\n\r\n\r\n\r\n<\/div>\r\n<\/div>\n\t<input type=\"hidden\" name=\"item_key\" value=\"\" \/>\n\t\t\t<div id=\"frm_field_24_container\">\n\t\t\t<label for=\"field_8g19i\" >\n\t\t\t\tIf you are human, leave this field blank.\t\t\t<\/label>\n\t\t\t<input  id=\"field_8g19i\" type=\"text\" class=\"frm_form_field form-field frm_verify\" name=\"item_meta[24]\" value=\"\"  \/>\n\t\t<\/div>\n\t\t<input name=\"frm_state\" type=\"hidden\" value=\"tGKtIG19U6wyYcew8uBttaSbuwg+U7j4BBqUmDnuwlwwF9M0QAXa6pd1+Qu8+H8p\" \/><\/div>\n<\/fieldset>\n<\/div>\n\n<p style=\"display: none !important;\" class=\"akismet-fields-container\" data-prefix=\"ak_\"><label>&#916;<textarea name=\"ak_hp_textarea\" cols=\"45\" rows=\"8\" maxlength=\"100\"><\/textarea><\/label><input type=\"hidden\" id=\"ak_js_1\" name=\"ak_js\" value=\"134\"\/><script>document.getElementById( \"ak_js_1\" ).setAttribute( \"value\", ( new Date() ).getTime() );<\/script><\/p><\/form>\n<\/div>\n<\/p>\n<\/div>\n<\/div>\n\n","protected":false},"excerpt":{"rendered":"Browser performance has come a long way in the past 10 years. It used to be a lot more challenging to add interactive animations to web pages due to the potential for rendering and performance issues. But nowadays, CSS animations can be used much more freely and the syntax is generally much easier to learn compared to CSS features like grid or flexbox. Here is a full syntax guide and interactive CSS animations tutorial for beginners. Use it as reference to learn the different parts of the CSS animations spec.","protected":false},"author":65,"featured_media":112470,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_stopmodifiedupdate":false,"_modified_date":"","_themeisle_gutenberg_block_has_review":false,"footnotes":""},"categories":[273],"tags":[],"hashtags":[],"class_list":["post-48758","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-resources"],"wppr_data":{"cwp_meta_box_check":"No"},"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.8 (Yoast SEO v26.1.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>CSS Animations Tutorial: Complete Guide for Beginners<\/title>\n<meta name=\"description\" content=\"Here&#039;s a CSS animations tutorial for beginners that breaks down all the different properties, how to write keyframes, and where to start.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"CSS Animations Tutorial: Complete Guide for Beginners\" \/>\n<meta property=\"og:description\" content=\"Here&#039;s a CSS animations tutorial for beginners that breaks down all the different properties, how to write keyframes, and where to start.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Themeisle Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-02-07T14:00:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-07-22T11:31:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2180\" \/>\n\t<meta property=\"og:image:height\" content=\"1090\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Louis Lazaris\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@LouisLazaris\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Louis Lazaris\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/\"},\"author\":{\"name\":\"Louis Lazaris\",\"@id\":\"https:\/\/themeisle.com\/blog\/#\/schema\/person\/7214be14a40c764c30ce803b2abf6e66\"},\"headline\":\"CSS Animations Tutorial: Complete Guide for Beginners\",\"datePublished\":\"2022-02-07T14:00:48+00:00\",\"dateModified\":\"2025-07-22T11:31:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/\"},\"wordCount\":2660,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/themeisle.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg\",\"articleSection\":[\"Resources\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/\",\"url\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/\",\"name\":\"CSS Animations Tutorial: Complete Guide for Beginners\",\"isPartOf\":{\"@id\":\"https:\/\/themeisle.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg\",\"datePublished\":\"2022-02-07T14:00:48+00:00\",\"dateModified\":\"2025-07-22T11:31:19+00:00\",\"description\":\"Here\\\\'s a CSS animations tutorial for beginners that breaks down all the different properties, how to write keyframes, and where to start.\",\"breadcrumb\":{\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#primaryimage\",\"url\":\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg\",\"contentUrl\":\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg\",\"width\":2180,\"height\":1090,\"caption\":\"CSS animations tutorial\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Blog\",\"item\":\"https:\/\/themeisle.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CSS Animations Tutorial: Complete Guide for Beginners\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/themeisle.com\/blog\/#website\",\"url\":\"https:\/\/themeisle.com\/blog\/\",\"name\":\"Themeisle Blog\",\"description\":\"WordPress Tutorials and Reviews for Beginners and Advanced\",\"publisher\":{\"@id\":\"https:\/\/themeisle.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/themeisle.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/themeisle.com\/blog\/#organization\",\"name\":\"VertiStudio\",\"alternateName\":\"Vertigo Studio SA\",\"url\":\"https:\/\/themeisle.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/themeisle.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2024\/02\/VertiStudio_logo1.png\",\"contentUrl\":\"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2024\/02\/VertiStudio_logo1.png\",\"width\":718,\"height\":156,\"caption\":\"VertiStudio\"},\"image\":{\"@id\":\"https:\/\/themeisle.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/themeisle.com\/blog\/#\/schema\/person\/7214be14a40c764c30ce803b2abf6e66\",\"name\":\"Louis Lazaris\",\"description\":\"Louis Lazaris is a front-end developer, author, writer, and speaker who has been working in the web development industry since 2000. He has authored or co-authored books on front-end technologies and has worked as a technical editor for top publishers like Manning, Smashing Magazine, and SitePoint. He worked with agencies and large companies in past roles before he started freelancing in 2009.\",\"sameAs\":[\"https:\/\/lazarpress.com\/\",\"https:\/\/www.linkedin.com\/in\/louis-lazaris-815b9015\/\",\"https:\/\/x.com\/LouisLazaris\",\"https:\/\/www.youtube.com\/user\/ImpressiveWebs\"],\"url\":\"https:\/\/themeisle.com\/blog\/author\/louis-l\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"CSS Animations Tutorial: Complete Guide for Beginners","description":"Here&#039;s a CSS animations tutorial for beginners that breaks down all the different properties, how to write keyframes, and where to start.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/","og_locale":"en_US","og_type":"article","og_title":"CSS Animations Tutorial: Complete Guide for Beginners","og_description":"Here&#039;s a CSS animations tutorial for beginners that breaks down all the different properties, how to write keyframes, and where to start.","og_url":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/","og_site_name":"Themeisle Blog","article_published_time":"2022-02-07T14:00:48+00:00","article_modified_time":"2025-07-22T11:31:19+00:00","og_image":[{"width":2180,"height":1090,"url":"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg","type":"image\/jpeg"}],"author":"Louis Lazaris","twitter_card":"summary_large_image","twitter_creator":"@LouisLazaris","twitter_misc":{"Written by":"Louis Lazaris","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#article","isPartOf":{"@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/"},"author":{"name":"Louis Lazaris","@id":"https:\/\/themeisle.com\/blog\/#\/schema\/person\/7214be14a40c764c30ce803b2abf6e66"},"headline":"CSS Animations Tutorial: Complete Guide for Beginners","datePublished":"2022-02-07T14:00:48+00:00","dateModified":"2025-07-22T11:31:19+00:00","mainEntityOfPage":{"@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/"},"wordCount":2660,"commentCount":0,"publisher":{"@id":"https:\/\/themeisle.com\/blog\/#organization"},"image":{"@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg","articleSection":["Resources"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/","url":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/","name":"CSS Animations Tutorial: Complete Guide for Beginners","isPartOf":{"@id":"https:\/\/themeisle.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg","datePublished":"2022-02-07T14:00:48+00:00","dateModified":"2025-07-22T11:31:19+00:00","description":"Here\\'s a CSS animations tutorial for beginners that breaks down all the different properties, how to write keyframes, and where to start.","breadcrumb":{"@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/themeisle.com\/blog\/css-animations-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#primaryimage","url":"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg","contentUrl":"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2022\/02\/CSS-animations-tutorial.jpg","width":2180,"height":1090,"caption":"CSS animations tutorial"},{"@type":"BreadcrumbList","@id":"https:\/\/themeisle.com\/blog\/css-animations-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Blog","item":"https:\/\/themeisle.com\/blog\/"},{"@type":"ListItem","position":2,"name":"CSS Animations Tutorial: Complete Guide for Beginners"}]},{"@type":"WebSite","@id":"https:\/\/themeisle.com\/blog\/#website","url":"https:\/\/themeisle.com\/blog\/","name":"Themeisle Blog","description":"WordPress Tutorials and Reviews for Beginners and Advanced","publisher":{"@id":"https:\/\/themeisle.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/themeisle.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/themeisle.com\/blog\/#organization","name":"VertiStudio","alternateName":"Vertigo Studio SA","url":"https:\/\/themeisle.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/themeisle.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2024\/02\/VertiStudio_logo1.png","contentUrl":"https:\/\/mllj2j8xvfl0.i.optimole.com\/cb:c5QE.37290\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/themeisle.com\/blog\/wp-content\/uploads\/2024\/02\/VertiStudio_logo1.png","width":718,"height":156,"caption":"VertiStudio"},"image":{"@id":"https:\/\/themeisle.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/themeisle.com\/blog\/#\/schema\/person\/7214be14a40c764c30ce803b2abf6e66","name":"Louis Lazaris","description":"Louis Lazaris is a front-end developer, author, writer, and speaker who has been working in the web development industry since 2000. He has authored or co-authored books on front-end technologies and has worked as a technical editor for top publishers like Manning, Smashing Magazine, and SitePoint. He worked with agencies and large companies in past roles before he started freelancing in 2009.","sameAs":["https:\/\/lazarpress.com\/","https:\/\/www.linkedin.com\/in\/louis-lazaris-815b9015\/","https:\/\/x.com\/LouisLazaris","https:\/\/www.youtube.com\/user\/ImpressiveWebs"],"url":"https:\/\/themeisle.com\/blog\/author\/louis-l\/"}]}},"_links":{"self":[{"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/posts\/48758","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/users\/65"}],"replies":[{"embeddable":true,"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/comments?post=48758"}],"version-history":[{"count":23,"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/posts\/48758\/revisions"}],"predecessor-version":[{"id":112472,"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/posts\/48758\/revisions\/112472"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/media\/112470"}],"wp:attachment":[{"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/media?parent=48758"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/categories?post=48758"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/tags?post=48758"},{"taxonomy":"hashtags","embeddable":true,"href":"https:\/\/themeisle.com\/blog\/wp-json\/wp\/v2\/hashtags?post=48758"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}