Skip to article

Add animations to your WordPress site

Add Motion to a WordPress site for high-performance animations on any theme.

Motion lets you add custom animations to your WordPress site.

Many WordPress themes have built-in animations, but they often lack customisation options. Some also rely on older libraries like jQuery, which can affect performance and SEO.

By using Motion, you gain:

  • Flexibility: You're not limited to the theme's in-built options (if any). You can design any animation you want using any of Motion's APIs like scroll and timeline sequencing.

  • Performance: Motion is built on the latest browser APIs for hardware accelerated performance.

  • Improved SEO: Motion's tiny animate() function is just 3.2kb, and the rest of the library is small too. This leads to better SEO scores.

Motion is also free and open source!

Do I need an animation plugin?

No. WordPress animation plugins add a visual builder, but they also add their own scripts and styles to every page, and you're limited to the effects the plugin author chose.

With Motion, you add one small script and write the exact animation you want. The only plugin you need is one that lets you add a script tag safely, and you might already have one installed.

Installation

Adding custom scripts can be tricky in WordPress. We recommend using a plugin like WPCode (formerly "Insert Headers and Footers"), as it lets you add custom JS tags in a safe way, without blocking theme updates or hacking around with PHP code.

Once the plugin is installed, you can open Code Snippets > Header & Footer in the WordPress admin panel.

Here, in the Footer section, add:

<script type="module">
  import { animate } from "https://cdn.jsdelivr.net/npm/motion@14.11.1/+esm"

  // Your animation code here
  animate("h1", { opacity: [0, 1] })
</script>

You can replace 14.11.1 here with whichever version you want to install. The latest published version can be found on the npm package page.

This script contains all the Motion imports, but you can also achieve even greater filesize savings if you want to use just the mini version of the animate function, which is just 3.2kb, by importing from https://cdn.jsdelivr.net/npm/motion@14.11.1/mini/+esm:

<script type="module">
  import { animate } from "https://cdn.jsdelivr.net/npm/motion@14.11.1/mini/+esm"

  // Your animation code here
  animate("h1", { opacity: [0, 1] })
</script>

Selecting elements

In order to animate elements, we need to select them first.

We can select them generically using a tag selector, like "a" for selecting all the links on a page. For instance we can use animate and press to scale links in and out when they're pressed and released:

<script type="module">
  import { animate, press } from "https://cdn.jsdelivr.net/npm/motion@14.11.1/+esm"

  press("a", (element) => {
    animate(element, { scale: 0.7 })

    return () => animate(element, { scale: 1 })
  })
</script>

Or we can be more specific, by adding a class to the element we want to animate. In the block editor, select the block, open the Advanced panel in the block settings sidebar, and type a name into Additional CSS class(es).

animate(".my-class", { rotate: [0, 20, 0] }, { duration: 0.4 })

Animate on scroll

The most common WordPress animation is fading elements in as they scroll into view. Motion's inView function detects when an element enters the viewport, so we can animate it then.

First, add a class like reveal to the blocks you want to animate. Then add this to the Footer section:

<style>
  .reveal { opacity: 0; }
</style>

<script type="module">
  import { animate, inView } from "https://cdn.jsdelivr.net/npm/motion@14.11.1/+esm"

  inView(".reveal", (element) => {
    animate(
      element,
      { opacity: [0, 1], y: [40, 0] },
      { type: "spring", duration: 0.8, bounce: 0 }
    )
  })
</script>

Each element animates once, the first time it scrolls into view. inView is built on the browser's Intersection Observer API, so it doesn't slow down scrolling.

For effects that track the scroll position itself, like progress bars and parallax, use scroll:

<script type="module">
  import { animate, scroll } from "https://cdn.jsdelivr.net/npm/motion@14.11.1/+esm"

  scroll(animate(".progress-bar", { scaleX: [0, 1] }))
</script>

Custom scripts

By importing scripts directly from this URL, you're importing everything, even the bits of Motion you're not using. But, one of the great things about Motion is it's tree-shakable. This means you can use a bundler like Vite or Rollup to only include the bits you use.

In fact, this is a good practice for all of your WordPress custom code. It will ensure you package everything into one neat bundle and only package the bits you need.

For example, if you only wanted to use the animate function, you could replace the above code with this:

import { animate } from "motion"

animate("header", { opacity: 1 })

Building this with Rollup, uploading to a CDN, and then including with an async JS tag will boost SEO scores even further:

<script async src="https://yourdomain.com/my-script.js"></script>

Next

Now that you have Motion running in your WordPress site, you can follow our quick start guide to start making more complex animations.

For effects that would take a plugin plus a lot of custom code, like split text and typewriter animations, Motion+ gives you ready-made functions, along with a vault of premium examples to copy into your site.