Shopify Theme Magic: How to Add a 'Floating' Product Image Animation (Ritual Theme & Beyond)

Hey there, fellow store owners! As someone who spends a lot of time diving into the Shopify community forums, I often come across discussions that really highlight the clever ways you're all pushing the boundaries of your stores. One thread recently caught my eye, started by a user named ABdev1, who was grappling with a pretty cool challenge: how to add an "always-on" 3D float effect to product images within their featured collection sections on the Ritual theme.

ABdev1 wasn't looking for a hover effect, mind you, but a continuous, subtle animation that would make their product images gently "float" on the page. They’d tried everything, even consulting AI tools like Perplexity, but were hitting a wall, specifically with errors related to @keyframes in their custom CSS. This is a common sticking point, and it’s exactly the kind of puzzle the community loves to solve! Here’s what ABdev1 was aiming for:

Screenshot of product images in a featured collection

The Nitty-Gritty: Why Was This Tricky?

The core of ABdev1's problem, as Mateo-Penida quickly pinpointed, was that Shopify’s "Custom CSS" fields within individual sections don't always play nice with advanced CSS rules like @keyframes. These rules are essential for defining the steps of an animation, telling an element how to move, transform, or change over time. When ABdev1 tried to paste the full animation code directly into their section's Custom CSS, they ran into errors, like the ones seen here:

Screenshot showing CSS errors in the custom CSS field regarding @keyframes

Initially, Mateo-Penida provided some excellent CSS, complete with a beautiful 3D float animation using translateY and rotateX/Y values, and suggested adding it to the theme's main CSS file, typically base.css. This approach works because base.css is where global styles live, and it fully supports @keyframes. Here’s a snippet of that animation definition:

@keyframes float3d {
  0%, 100% { transform: translateY(0px) rotateX(2deg) rotateY(2deg); }
  25% { transform: translateY(-6px) rotateX(-2deg) rotateY(3deg); }
  50% { transform: translateY(-10px) rotateX(2deg) rotateY(-2deg); }
  75% { transform: translateY(-4px) rotateX(-1deg) rotateY(1deg); }
}

The challenge with putting all the code, including the animation application (e.g., .product-media__image { animation: float3d 4s ease-in-out infinite; }) into base.css is that it applies the effect globally to *all* matching elements across your entire store. As Maximus3 wisely pointed out, this might not be what you want if you only need the effect on specific sections. Maximus3 then offered a way to target specific sections within base.css using their unique Shopify section IDs, which is a great advanced technique for granular control:

#shopify-section-template--20099090317391__product_list_NgyDci .product-media__image,
#shopify-section-template--20099090317391__product_list_77Happ .product-media__image,
#shopify-section-template--20099090317391__product_list_Pt9BB8 .product-media__image {
  animation: float3d 4s ease-in-out infinite;
  will-change: transform;
}

@keyframes float3d {
  0%   { transform: translateY(0%); }
  50%  { transform: translateY(-4%); }
  100% { transform: translateY(0%); }
}

While editing base.css works, it's generally best practice to avoid directly modifying core theme files if there’s a more flexible option. Why? Because when your theme gets an update, you might lose your changes or run into conflicts. This is where tim_tairli's brilliant "split CSS" solution comes into play, offering a way to get the best of both worlds without touching the theme's core code files!

The Smart Solution: Split Your CSS for Flexibility

tim_tairli's approach is super elegant because it respects Shopify's structure and avoids direct theme file edits. The trick is to split your CSS: put the problematic @keyframes rule in a "Custom Liquid" section, and the animation application in the section-specific "Custom CSS" field. This works because the "Custom Liquid" section acts like a mini

This defines the animation steps. You can adjust the translateY percentages to control how much the image "floats" up and down. Mateo-Penida's version also included rotateX and rotateY for a more pronounced 3D tilt, so feel free to experiment:


  • Save your changes in the theme customizer.
  • Apply the Animation to Specific Sections Using Custom CSS
    Now that the animation is defined globally (via Custom Liquid), you can tell specific elements to use it.
    • Navigate to the specific "Featured Collection" section (or any section with product images) where you want the float effect.
    • In the section's settings, look for the "Custom CSS" field.
    • Paste the following code there:
      .product-media__image {
        animation: float3d 4s ease-in-out infinite;
        will-change: transform;
      }
      

      This code targets the actual product image element (.product-media__image is a common selector for this in many Shopify themes, including Ritual). The animation: float3d 4s ease-in-out infinite; line tells it to use the float3d animation you just defined, run it for 4 seconds, use an ease-in-out timing, and repeat infinitely. The will-change: transform; is a performance optimization hint for browsers.

      If you find this selector doesn't work, you might need to inspect your specific theme's elements. As Mateo-Penida suggested, right-click a product image in your theme preview, choose "Inspect," and look for the class on the tag. For featured collections, .section-resource-list img.product-media__image was also a strong candidate.

      Also, Maximus3 mentioned that if you want the effect on the entire image wrapper instead of just the image, you could try .card-gallery instead of .product-media__image.

    • Save your changes for that section.
  • Check Your Work and Publish
    Preview your duplicated theme to see the animated product images. If everything looks good, you can then publish this duplicated theme to make it live! Remember to do a hard refresh (Ctrl + Shift + R on Windows, Cmd + Shift + R on Mac) if you're not seeing changes immediately.
  • This method gives you the flexibility to apply the unique 3D float animation to specific sections without complicating your main theme files. It's a fantastic example of how combining different Shopify customization tools – Custom Liquid for global CSS definitions and Custom CSS for targeted application – can lead to powerful and maintainable results. Big shoutout to tim_tairli for sharing this clever workaround, and to Mateo-Penida and Maximus3 for their excellent debugging and alternative solutions that helped us all understand the nuances!

    Share:

    Start with the tools

    Explore migration tools

    See options, compare methods, and pick the path that fits your store.

    Explore migration tools