Logo
Home
Resources

Product

Custom Workflow

Resources

Blog
Youtube
Template
Home
>
Product
>
Template Top
>
detail

Hubspot CMS:How to Control Scroll-Linked Animations Without Code

Enhancing the user experience (UX) of a website requires dynamic visual effects that trigger as content appears. This article explains how to use HubSpot CMS "Custom Modules" to allow editors to freely control element animations directly from the edit screen, without requiring any programming knowledge.

Demo Video

Over view
Code

Detail

Enhancing the user experience (UX) of a website requires dynamic visual effects that trigger as content appears. This article explains how to use HubSpot CMS "Custom Modules" to allow editors to freely control element animations directly from the edit screen, without requiring any programming knowledge.

1. Objectives

The goal of this module is to centrally manage "which element," "how," and "when" to animate via the HubSpot page editor, without manually adding specific CSS classes.  

  • Operational Efficiency: Simply select elements like H1 tags or images from a dropdown list to complete the setup.  
  • Design Consistency: Define common animations (slide, fade, popup) across the site to maintain a unified brand identity.
  • Performance Optimization: Utilizes the "Intersection Observer API" to execute animations efficiently only when an element enters the viewport.  

2. Potential Use Cases

  • Hero Area Effects: Create a strong first impression by having the main copy float up from the bottom when a visitor arrives.
  • Visual Guidance via Scrolling: Improve completion rates by sliding in important diagrams or supplemental text from the left or right as the user reads down the page.
  • Emphasizing Calls to Action: Add "Pop-up" movements to contact buttons or banners to encourage clicks.
  • Sequential Display of Multiple Elements: Use the "Delay" setting to stagger the appearance of multiple card-style layouts for a rhythmic visual effect.  

3. Implementation and Configuration Steps

Step 1: Create a New Module

  1. Navigate to [Marketing] > [Files and Templates] > [Design Manager] in HubSpot.
  2. Right-click in the file tree and select [New file].
  3. Select [Module] as the file type and check the locations where it will be used (Landing pages, Blogs, etc.).
  4. Name the module (e.g., animation_controller) and create it.

Step 2: Apply the Code

Copy and paste the code provided in the technical specifications into the respective sections of the module editor:

  • fields.json: Defines selectors, animation types, directions, duration, and delay.  
  • HTML/HubL: Handles the loop processing to pass editor inputs to the JavaScript.  
  • CSS: Defines the animation styles using @keyframes.  
  • JavaScript: Contains the logic for scroll detection via the IntersectionObserver.  

Step 3: Place on a CMS Page

  1. Open the [Page Editor] where you want to apply animations.
  2. Search for your module in the left panel and drag it anywhere on the page (e.g., near the footer).

Step 4: Detailed Animation Settings

Configure specific movements within the "anim_settings" panel of the placed module:  

  • Target Selector: Select the target element (e.g., h2, img) from the dropdown.  
  • Animation Type (anim_type): Choose from "slide-in," "fade-in," "pop-up," etc.  
  • Direction and Timing:
    • direction: Specify the starting direction (e.g., "down" to move from top to bottom).  
    • duration: Enter the seconds for the animation to complete (e.g., 1s).  
    • delay: Enter the wait time before the movement starts once the element is in view.  

4. How the Detection and Execution Work

  • Automatic Exclusion: Elements within headers or footers are automatically excluded by the script to avoid disrupting the core UX.  
  • One-Time Execution: Animations trigger when 10% of the element enters the viewport; once executed, the observer stops to minimize page load.  
  • No-Code Operation: Once placed, you can animate the entire site without writing a single line of additional code.

Module Source Code

Create a "New Module" in the HubSpot Design Manager and paste the following code into each respective section.

1. fields.json

This is the field definition. It consists of a repeater field (Items) and style setting fields (Styles).

[
 {
  "children": [
   {
    "choices": [
     [ "h1", "H1" ], [ "h2", "H2" ], [ "h3", "H3" ], [ "h4", "H4" ],
     [ "h5", "H5" ], [ "h6", "H6" ], [ "p", "p" ], [ "span", "span" ],
     [ "div", "div" ], [ "li", "list" ], [ "img", "image" ], [ "setion", "section" ]
    ],
    "display": "select",
    "display_width": null,
    "id": "6b6e5314-9832-c18b-b7f1-e5ab1052fabb",
    "label": "target_selector",
    "locked": false,
    "multiple": false,
    "name": "target_selector",
    "preset": null,
    "reordering_enabled": true,
    "required": false,
    "type": "choice"
   },
   {
    "choices": [
     [ "slide-in", "slide-in" ], [ "slide-out", "slide-out" ],
     [ "scale-up", "scale-up" ], [ "wave", "wave" ],
     [ "bounce", "bounce" ], [ "scale-down", "scale-down" ], [ "pop-up", "pop-up" ]
    ],
    "display": "select",
    "display_width": null,
    "id": "d604cb29-9753-6dc8-fd76-e5828e86f0d2",
    "label": "anim_type",
    "locked": false,
    "multiple": false,
    "name": "anim_type",
    "preset": null,
    "reordering_enabled": true,
    "required": false,
    "type": "choice"
   },
   {
    "choices": [
     [ "down", "上から" ], [ "up", "下から" ],
     [ "left", "左から" ], [ "right", "右から" ], [ "none", "なし" ]
    ],
    "display": "select",
    "display_width": null,
    "id": "a7c1f435-7a80-f31b-5c9e-b827edf28bc8",
    "label": "direction",
    "locked": false,
    "multiple": false,
    "name": "direction",
    "preset": null,
    "reordering_enabled": true,
    "required": false,
    "type": "choice"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "c15cf622-810b-0753-bc04-211167da8095",
    "label": "duration",
    "locked": false,
    "name": "duration",
    "required": false,
    "step": 1,
    "type": "number"
   },
   {
    "display": "text",
    "display_width": null,
    "id": "72e19799-ddd8-060f-4955-5ecdcd781bd9",
    "label": "delay",
    "locked": false,
    "name": "delay",
    "required": false,
    "step": 1,
    "type": "number"
   }
  ],
  "default": [],
  "display_width": null,
  "expanded": false,
  "group_occurrence_meta": null,
  "id": "f1529db5-e7c4-bba2-3b9a-e69444442236",
  "label": "anim_settings",
  "locked": false,
  "name": "anim_settings",
  "occurrence": {},
  "required": false,
  "tab": "CONTENT",
  "type": "group"
 }
]

Source Code

HTML
{# アニメーション設定をJavaScriptに渡す #}
<script>
  window.hsAnimConfig = window.hsAnimConfig || [];
  
  {% if module.anim_settings %}
    {% for item in module.anim_settings %}
      window.hsAnimConfig.push({
        selector: "{{ item.target_selector }}",
        type: "{{ item.anim_type }}",
        direction: "{{ item.direction|default('none') }}",
        duration: "{{ item.duration|default(1) }}s",
        delay: "{{ item.delay|default(0) }}s"
      });
    {% endfor %}
  {% endif %}
  
  console.log('HubSpot Animation Config:', window.hsAnimConfig);
</script>
CSS
/* 基本設定 */
.js-anim-ready {
  opacity: 0 !important;
}

/* アニメーション実行中 */
.js-anim-active {
  opacity: 1 !important;
}

/* === スライドイン === */
@keyframes slideInFromTop {
  from { opacity: 0; transform: translateY(-50px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes slideInFromBottom {
  from { opacity: 0; transform: translateY(50px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes slideInFromLeft {
  from { opacity: 0; transform: translateX(-50px); }
  to { opacity: 1; transform: translateX(0); }
}
@keyframes slideInFromRight {
  from { opacity: 0; transform: translateX(50px); }
  to { opacity: 1; transform: translateX(0); }
}

/* === スライドアウト === */
@keyframes slideOutToTop {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(-50px); }
}
@keyframes slideOutToBottom {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(50px); }
}

/* === その他のアニメーション === */
@keyframes scaleUp {
  from { opacity: 0; transform: scale(0.5); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes scaleDown {
  from { opacity: 0; transform: scale(1.5); }
  to { opacity: 1; transform: scale(1); }
}
@keyframes wave {
  0% { opacity: 0; transform: translateX(-20px) rotate(0deg); }
  50% { opacity: 0.5; transform: translateX(10px) rotate(2deg); }
  100% { opacity: 1; transform: translateX(0) rotate(0deg); }
}
@keyframes bounce {
  0% { opacity: 0; transform: translateY(50px); }
  50% { opacity: 1; transform: translateY(-10px); }
  100% { opacity: 1; transform: translateY(0); }
}
@keyframes popUp {
  from { opacity: 0; transform: translateY(20px) scale(0.8); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
Javascript

FAQ

Do I need to place a new module for every element I want to animate?

No, that is not necessary. This module allows you to add settings in a list format within the "anim_settings" panel. You can centrally manage multiple different targets—such as setting H2 tags to slide from the bottom while images pop up with a one-second delay—all within a single module.

Will all elements start moving the moment the page is loaded?

o. The module utilizes the "Intersection Observer API," which detects when an element is at least 10% visible within the viewport. Animations are triggered naturally according to the user's scrolling behavior.

Do I need to manually exclude elements in global areas like headers or footers?

No, they are automatically excluded. To protect the user experience, the script includes a function that automatically identifies elements within headers or footers and excludes them from animation processing. This allows users to focus on animating main content without worrying about affecting global site areas.

Search

Search more

Related Template

Need Customization?

We can customize this sample to match your specific business requirements.

Book Free Consultation

Got a quick dev request?

Put it on Trello!Need a fix for HubSpot, CMS, or GAS? Post it on Trello.

Development Requests Here

HubSpot CMS: Implementing the Data Type Conversion Action

HubSpot CMS: Implementing a Professional "Pricing Table Module"

HubSpot CMS: Implementing the "Login Check & Redirect Module" for Secure Page Access

HubSpot CMS: Implementing the "Carousel Card Module" for Smart Content Organization

HubSpot CMS: Implementation Guide for Video Hero Banners (Video Above-the-Fold)

Company Info
Name : SweetsVillage .Inc
CEO :
‍
Tomoo Motoyama

HomeTemplateCustomWorkflow
Terms & ConditionsPrivacy PolicyContact us

Copyright ©SweetsVillage .Inc

Back To Top Image