{"id":20018,"date":"2019-01-08T12:30:24","date_gmt":"2019-01-08T12:30:24","guid":{"rendered":"https:\/\/www.heartinternet.uk\/blog\/?p=20018"},"modified":"2019-01-08T12:30:24","modified_gmt":"2019-01-08T12:30:24","slug":"the-developers-guide-to-native-web-animation","status":"publish","type":"post","link":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/","title":{"rendered":"The developer\u2019s guide to native web animation"},"content":{"rendered":"<p>Animation on the web has come a long way. At first we used Flash to create websites, which were all fun and interactive, then we got to fancy JavaScript libraries, and now the web platform offers us a selection of native animation tools. But with all the new choices it gets harder to decide which ones to use, so we\u2019re going to dive deeper into native animation options currently available and what the differences are.<\/p>\n<h3>CSS animations and transitions<\/h3>\n<p>The simplest and most popular option is CSS animation and transitions. With its declarative nature CSS offers a basic way to add some animations to elements directly in your CSS.<\/p>\n<p>CSS transitions are a good use case for animation, when you want to go from one state A to another state B. Here is a little example of a menu animation:<\/p>\n<p data-height=\"265\" data-theme-id=\"0\" data-slug-hash=\"bQvVmo\" data-default-tab=\"html,result\" data-user=\"lisilinhart\" data-pen-title=\"Menu Left\" data-preview=\"true\" class=\"codepen\">See the Pen <a href=\"https:\/\/codepen.io\/lisilinhart\/pen\/bQvVmo\/\">Menu Left<\/a> by Lisi (<a href=\"https:\/\/codepen.io\/lisilinhart\">@lisilinhart<\/a>) on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/p>\n<p><script async src=\"https:\/\/static.codepen.io\/assets\/embed\/ei.js\"><\/script><\/p>\n<p>Whenever the menu on the left is hovered, its transform property is set to <code>transform: translate(0%);<\/code>. When it\u2019s not hovered, it\u2019s set to <code>transform: translateX(-90%);<\/code>. Then on the idle not-hovered state we\u2019re setting a transition on our transform property <code>transition: transform 0.45s cubic-bezier(0.39, 0.575, 0.565, 1);<\/code>. So our menu is going from state <em>90% to the left<\/em> to <em>0% in the center<\/em>.<\/p>\n<p>CSS animations on the other hand allow us to create animations with more complex animation states. So if you want to animate from State A to State B to State C to State D, etc. These kind of animations are perfect for simple loading animations. Here\u2019s another little example:<\/p>\n<p data-height=\"265\" data-theme-id=\"0\" data-slug-hash=\"xQWwox\" data-default-tab=\"css,result\" data-user=\"lisilinhart\" data-pen-title=\"Loading\" data-preview=\"true\" class=\"codepen\">See the Pen <a href=\"https:\/\/codepen.io\/lisilinhart\/pen\/xQWwox\/\">Loading<\/a> by Lisi (<a href=\"https:\/\/codepen.io\/lisilinhart\">@lisilinhart<\/a>) on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/p>\n<p><script async src=\"https:\/\/static.codepen.io\/assets\/embed\/ei.js\"><\/script><\/p>\n<p>On our element that we want to be animated we define the animation to load <code>animation: pulse both 1.2s infinite linear;<\/code>. This tells the animation to run with a speed of 1.2s, infinitely, a linear easing function and an fill-mode of both. If you\u2019re not familiar with the syntax, take a look at <a href=\"https:\/\/cssreference.io\/animations\/\">Animations <\/a><a href=\"https:\/\/cssreference.io\/animations\/\">in CSS<\/a> on <a href=\"https:\/\/cssreference.io\/\">cssreference.io<\/a> and explore what all the keywords mean. The actual definition of our animation happens with the <code>@keyframes<\/code> pulse definition. Essentially, we have three states in our animation:<\/p>\n<ol>\n<li>Scaled to almost zero and not <code>visible opacity: 0<\/code>. With the ease-out-sine timing function <code>animation-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1<\/code>) we\u2019re telling the animation to come in slowly and then speed up until we reach the next state.<\/li>\n<li>Scaled to its actual size and visible with a timing function of linear to make it slower in the middle of the animation.<\/li>\n<li>Scaled up to 1.4 times its size and fading to not visible with an ease-in-sine function to make it disappear slowly and then speeding up to the end of the animation.<\/li>\n<\/ol>\n<pre><code>@keyframes pulse {\n  0% {\n    transform: rotate(45deg) scale3d(0.1, 0.1, 0.1);\n      opacity: 0;\n      animation-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1);\n  }\n\n  50% {\n    transform: rotate(45deg) scale3d(1, 1, 1);\n      opacity: 1;\n    animation-timing-function: linear;\n  }\n\n  100% {\n    transform: rotate(45deg) scale3d(1.4, 1.4, 1.4);\n    opacity: 0;\n      animation-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715);\n  }\n}<\/code><\/pre>\n<p>A great bonus for CSS transitions and animations are that they can run independently from your JavaScript and are able to be hardware accelerated over your GPU. Good use cases for both are: Simple animations with up to three different stages, loading spinners, and animations triggered on <code>:hover<\/code> and <code>:focus<\/code>. However, if you want to create more complex animations that have lots of different stages, this is fairly hard to do in CSS, since you would need to write a lot of CSS code that\u2019s perfectly timed together.<\/p>\n<h3>The Web Animations API<\/h3>\n<p>This is where the Web Animations API (short WAAPI) comes in, a more powerful, native alternative to CSS animation. Similar to CSS animations the WAAPI can run animations on the compositor thread, so independently from your JavaScript, and it can also hardware accelerate animations over the GPU. Furthermore, it gives you controls and callback to handle your animations after they were created. Let\u2019s take a look at an example:<\/p>\n<p data-height=\"265\" data-theme-id=\"0\" data-slug-hash=\"JeLGqN\" data-default-tab=\"js,result\" data-user=\"lisilinhart\" data-pen-title=\"Waapi\" data-preview=\"true\" class=\"codepen\">See the Pen <a href=\"https:\/\/codepen.io\/lisilinhart\/pen\/JeLGqN\/\">Waapi<\/a> by Lisi (<a href=\"https:\/\/codepen.io\/lisilinhart\">@lisilinhart<\/a>) on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/p>\n<p><script async src=\"https:\/\/static.codepen.io\/assets\/embed\/ei.js\"><\/script><\/p>\n<p>We have a counter that\u2019s counting down from 10, and we want to speed up the animation the closer the countdown gets to 0. To create animations with the Web Animations API, we first have to get an element we want to animate with <code>document.querySelector<\/code>, then we need to call the <code>.animate()<\/code> function on this element. This returns an animation object with certain controls and callbacks, which we\u2019re going to use later. To create an animation, the .animate function takes the following parameters:<\/p>\n<ol>\n<li>A keyframes array or object with the different stages of the animation.<\/li>\n<li>A timings object with the different timing options on how fast and how often the animation should run.<\/li>\n<\/ol>\n<p>In the example below we have two keyframes: from visible and scaled to 60% to half visible and scaled to its full size. For the timing we defined it to run half a second with a linear easing, no delay and 100 iterations. Again these keywords are almost the same keywords we use in CSS animations.<\/p>\n<pre><code>const clock = document.querySelector('.countdown');\nconst countdownAnimation = clock.animate([\n  {opacity: 1, transform: 'scale(.6)'},\n  {opacity: .5, transform: 'scale(1)'}\n], {\n  duration: 500,\n  easing: 'linear',\n  delay: 0,\n  iterations: 100,\n  direction: 'alternate',\n  fill: 'forwards'\n});<\/code><\/pre>\n<p>To speed up the animation, we make use of the control on our <code>countdownAnimation<\/code> object, which is returned by the <code>.animate<\/code> function in the code snippet above. We\u2019re setting an interval that\u2019s counting down our numbers, and as long as our number is bigger than 0, we\u2019re increasing our <code>countdownAnimation.playbackRate<\/code> up to a maximum of 6. If our counter is finished, we\u2019re calling the <code>countdownAnimation.finish()<\/code> control function to stop our animation and clear the interval.<\/p>\n<pre><code>const interval = setInterval(function() {\n  time = time - 1;\n  clock.textContent = time;\n  if (time > 0) {\n    countdownAnimation.playbackRate = Math.min(countdownAnimation.playbackRate * 1.15, 6);\n  } else {\n    countdownAnimation.finish();\n        clearInterval(interval);\n  }\n}, 1000);<\/code><\/pre>\n<p>Since we\u2019re defining our animations in JavaScript, we get a lot more control and can create more complex and interactive animations. If we had done the following example in CSS, we would have needed multiple elements, which would have needed to be timed perfectly together. Doing it with the WAAPI makes the code a lot more readable. The only downside to the WAAPI at the moment is the missing full browser support . If we take a look at the <a href=\"https:\/\/caniuse.com\/#feat=web-animation\">Can I <\/a><a href=\"https:\/\/caniuse.com\/#feat=web-animation\">Use<\/a> numbers, Firefox, Chrome and Safari are getting good support, but Edge hasn&#8217;t yet implemented the API, so it&#8217;s going to take a little bit longer until your animations run everywhere. The general advice for browser support with the Web Animations API is to fall back to no animations if the browser doesn&#8217;t support them. There is a <a href=\"https:\/\/github.com\/web-animations\/web-animations-js\">polyfill<\/a>, if you really need full browser support, but not everyone recommends using it.<\/p>\n<h3>JavaScript and CSS Variables<\/h3>\n<p>The third popular option for web animation are CSS Variables in combination with JavaScript. Many developers love this approach to animation, because it allows you to define your complex calculations in JavaScript. You then specify which element gets animated and which of its CSS properties is changed in CSS. JavaScript in combination with CSS Variables is especially great for creating reactive animations.<\/p>\n<p>Since CSS Variables are inherited by their parent, this allows us to define a variable on a parent element and make use of this variable in all child elements. This is great because we don\u2019t need excessive DOM manipulation and only define the variable on the parent once.<\/p>\n<p>Let\u2019s have a look at an example:<\/p>\n<p data-height=\"265\" data-theme-id=\"0\" data-slug-hash=\"pQLyOR\" data-default-tab=\"html,result\" data-user=\"lisilinhart\" data-pen-title=\"Javascript &#038; CSS Variables\" data-preview=\"true\" class=\"codepen\">See the Pen <a href=\"https:\/\/codepen.io\/lisilinhart\/pen\/pQLyOR\/\">Javascript &#038; CSS Variables<\/a> by Lisi (<a href=\"https:\/\/codepen.io\/lisilinhart\">@lisilinhart<\/a>) on <a href=\"https:\/\/codepen.io\">CodePen<\/a>.<\/p>\n<p><script async src=\"https:\/\/static.codepen.io\/assets\/embed\/ei.js\"><\/script><\/p>\n<p>First we need to get the element we want to set our variable on. This will be the parent element, with all the child elements that we want to animate inside. We\u2019re defining a <code>raf<\/code> variable to be able to call a function for continuous animation optimisation called <code>requestAnimationFrame<\/code>.<\/p>\n<pre><code>const parent = document.querySelector('#app');\nlet raf; <\/code><\/pre>\n<p>Then we\u2019re adding a <code>mousemove<\/code> listener on our document. So whenever the mouse is moved in our document, a new event is fired. When that event is fired, we\u2019re calling our update function with the <code>requestAnimationFrame<\/code> function that\u2019s provided by the browser. Essentially, this tells the browser that we\u2019re updating an animation and that the provided function should be called before the browser performs the next repaint. The <code>requestAnimationFrame<\/code> is widely used for improved performance on continuous animation updates.<\/p>\n<pre><code>document.addEventListener('mousemove', (e) => {\n  raf = raf || requestAnimationFrame(() => update(e));\n});<\/code><\/pre>\n<p>Then we\u2019re defining our actual update function. Here we\u2019re calculating our <code>e.clientX<\/code> pixel value in proportion to the window width. The calculation returns an <code>x<\/code> value of <code>-1<\/code> when the mouse is on the left hand side of the document, a value of <code>0<\/code> when it\u2019s in the centre and a value of <code>1<\/code>, when it\u2019s on the right.<\/p>\n<p>Finally we\u2019re setting our variable on our parent element with the <code>setProperty('--x', x )<\/code> function. In the end we\u2019re setting our <code>raf<\/code> function to null, to be able to call <code>requestAnimationFrame<\/code> again.<\/p>\n<pre><code>function update(e){\n    const x =  ((e.clientX \/ window.innerWidth) - 0.5) * 2;\n  parent.style.setProperty('--x', x );\n  raf = null;\n}<\/code><\/pre>\n<p>This is all the JavaScript we need for our reactive animations, now let\u2019s have a look at the CSS. To be able to animate one of the child elements, we\u2019re going to change their transform and opacity properties. For the first item we\u2019re changing the rotation according to mouse position. The mouse value is already set on the parent <code>#app<\/code> element via JavaScript and accessible via CSS over the <code>var(\u2014x)<\/code> selector. Since our X Value is between -1 and 1, depending on where the mouse currently is at, we need to multiply this value with degrees. So with <code>rotate(calc(var(--x) * 360deg))<\/code> we\u2019re rotating our element 360 degrees clockwise or anticlockwise depending on if you\u2019re moving your mouse left or right. Similar calculations are made with the other elements. Since we set X to a sensible value, it\u2019s easy to multiply it with different units like <code>px<\/code> or <code>deg<\/code> or <code>%<\/code>, whatever you need for your transformation.<\/p>\n<pre><code>.item-one {\n        transform: rotate(calc(var(--x) * 360deg));\n}<\/code><\/pre>\n<p>Using CSS Variables this way allows us to avoid excessive DOM Manipulation, because we only need to set the variable on the parent once, thus making it accessible to all child elements.<\/p>\n<p>They also allow us to animate different transform properties independently. So for example rotating an element independently from its translation, by animating a rotation variable. Using JavaScript to do calculations allows us to use more complex easings, like a bouncing easing or react to DOM events. Generally, CSS Variables and JavaScript go really well together.<\/p>\n<h3>JavaScript animations<\/h3>\n<p>I\u2019m not going to dive deep into JavaScript animation, because there are a lot of JavaScript libraries for all the different animation needs.<\/p>\n<p>Have a look at <a href=\"https:\/\/web-animation.github.io\/\">Web-animation toolkit<\/a> and choose the right library for what you want to animate. Generally, libraries are a great choice if you want to animate SVG, since there are still a lot of browser inconsistencies if you do more complex SVG animation natively. There are also amazing libraries like <a href=\"https:\/\/threejs.org\/\">three.js<\/a> for 3D WebGL animation or other 2D renderers like <a href=\"http:\/\/www.pixijs.com\/\">PixiJS<\/a>.<\/p>\n<p>In general I\u2019d recommended first trying to solve simpler animations with CSS or the Web Animations API, before going for a JavaScript library.<\/p>\n<p>However, if you need to create very animation-heavy websites, animation tools like <a href=\"https:\/\/greensock.com\/gsap\">GSAP<\/a> can be very useful, since you get amazing, performant, cross-browser consistent results in a short amount of time. It\u2019s not a tiny library, though, so consider beforehand if the code overhead is worth adding to your project.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With so many options available, it can be hard to choose the right tool for a native animation jobs. In this guide we explore the options and the difference between them, making it easier for you to pick the one you need.<\/p>\n","protected":false},"author":2,"featured_media":20031,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,24],"tags":[],"class_list":{"0":"post-20018","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-guest-posts","8":"category-web-design"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>The developer\u2019s guide to native web animation - Heart Internet<\/title>\n<meta name=\"description\" content=\"Want to create native web animations but don&#039;t know which tool to use? This guide will help you understand your options so you make the right choice.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"The developer\u2019s guide to native web animation - Heart Internet\" \/>\n<meta property=\"og:description\" content=\"Want to create native web animations but don&#039;t know which tool to use? This guide will help you understand your options so you make the right choice.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/\" \/>\n<meta property=\"og:site_name\" content=\"Heart Internet\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/heartinternet\/\" \/>\n<meta property=\"article:published_time\" content=\"2019-01-08T12:30:24+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1150\" \/>\n\t<meta property=\"og:image:height\" content=\"766\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Eliot Chambers-Ostler\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@heartinternet\" \/>\n<meta name=\"twitter:site\" content=\"@heartinternet\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Eliot Chambers-Ostler\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/\"},\"author\":{\"name\":\"Eliot Chambers-Ostler\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28\"},\"headline\":\"The developer\u2019s guide to native web animation\",\"datePublished\":\"2019-01-08T12:30:24+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/\"},\"wordCount\":1749,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg\",\"articleSection\":[\"Guest Posts\",\"Web Design\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/\",\"name\":\"The developer\u2019s guide to native web animation - Heart Internet\",\"isPartOf\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg\",\"datePublished\":\"2019-01-08T12:30:24+00:00\",\"description\":\"Want to create native web animations but don't know which tool to use? This guide will help you understand your options so you make the right choice.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#primaryimage\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg\",\"width\":1150,\"height\":766,\"caption\":\"imac on desk\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.heartinternet.uk\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"The developer\u2019s guide to native web animation\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/heartblog.victory.digital\/#website\",\"url\":\"https:\/\/heartblog.victory.digital\/\",\"name\":\"Heart Internet\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/heartblog.victory.digital\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\",\"name\":\"Heart Internet\",\"url\":\"https:\/\/heartblog.victory.digital\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp\",\"width\":992,\"height\":252,\"caption\":\"Heart Internet\"},\"image\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/heartinternet\/\",\"https:\/\/x.com\/heartinternet\",\"https:\/\/www.linkedin.com\/company\/heart-internet-ltd\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28\",\"name\":\"Eliot Chambers-Ostler\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg\",\"caption\":\"Eliot Chambers-Ostler\"},\"url\":\"https:\/\/www.heartinternet.uk\/blog\/author\/eliot-chambers-ostler\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"The developer\u2019s guide to native web animation - Heart Internet","description":"Want to create native web animations but don't know which tool to use? This guide will help you understand your options so you make the right choice.","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:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/","og_locale":"en_GB","og_type":"article","og_title":"The developer\u2019s guide to native web animation - Heart Internet","og_description":"Want to create native web animations but don't know which tool to use? This guide will help you understand your options so you make the right choice.","og_url":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/","og_site_name":"Heart Internet","article_publisher":"https:\/\/www.facebook.com\/heartinternet\/","article_published_time":"2019-01-08T12:30:24+00:00","og_image":[{"width":1150,"height":766,"url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg","type":"image\/jpeg"}],"author":"Eliot Chambers-Ostler","twitter_card":"summary_large_image","twitter_creator":"@heartinternet","twitter_site":"@heartinternet","twitter_misc":{"Written by":"Eliot Chambers-Ostler","Estimated reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#article","isPartOf":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/"},"author":{"name":"Eliot Chambers-Ostler","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28"},"headline":"The developer\u2019s guide to native web animation","datePublished":"2019-01-08T12:30:24+00:00","mainEntityOfPage":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/"},"wordCount":1749,"commentCount":0,"publisher":{"@id":"https:\/\/heartblog.victory.digital\/#organization"},"image":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#primaryimage"},"thumbnailUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg","articleSection":["Guest Posts","Web Design"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/","url":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/","name":"The developer\u2019s guide to native web animation - Heart Internet","isPartOf":{"@id":"https:\/\/heartblog.victory.digital\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#primaryimage"},"image":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#primaryimage"},"thumbnailUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg","datePublished":"2019-01-08T12:30:24+00:00","description":"Want to create native web animations but don't know which tool to use? This guide will help you understand your options so you make the right choice.","breadcrumb":{"@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#primaryimage","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/12\/imac-on-desk.jpg","width":1150,"height":766,"caption":"imac on desk"},{"@type":"BreadcrumbList","@id":"https:\/\/www.heartinternet.uk\/blog\/the-developers-guide-to-native-web-animation\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.heartinternet.uk\/blog\/"},{"@type":"ListItem","position":2,"name":"The developer\u2019s guide to native web animation"}]},{"@type":"WebSite","@id":"https:\/\/heartblog.victory.digital\/#website","url":"https:\/\/heartblog.victory.digital\/","name":"Heart Internet","description":"","publisher":{"@id":"https:\/\/heartblog.victory.digital\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/heartblog.victory.digital\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/heartblog.victory.digital\/#organization","name":"Heart Internet","url":"https:\/\/heartblog.victory.digital\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp","width":992,"height":252,"caption":"Heart Internet"},"image":{"@id":"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/heartinternet\/","https:\/\/x.com\/heartinternet","https:\/\/www.linkedin.com\/company\/heart-internet-ltd"]},{"@type":"Person","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28","name":"Eliot Chambers-Ostler","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/image\/","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg","caption":"Eliot Chambers-Ostler"},"url":"https:\/\/www.heartinternet.uk\/blog\/author\/eliot-chambers-ostler\/"}]}},"_links":{"self":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts\/20018","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/comments?post=20018"}],"version-history":[{"count":0,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts\/20018\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/media\/20031"}],"wp:attachment":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/media?parent=20018"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/categories?post=20018"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/tags?post=20018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}