Classic Interactions
|
This content was generated with the assistance of AI and should be verified against the official Webflow documentation before being relied on in production. This sub-section’s Webflow bibliography lists the reference material consulted while preparing these pages. |
This page was checked against the Webflow Help Center, the Webflow updates feed and the Webflow developer documentation on 2026-10-28. Webflow is a hosted service without version numbers, so a panel name or a limitation can change between two visits. Classic Interactions are available in the Designer of every plan; custom code, which the re-initialisation section needs, requires a paid plan, and the official pages disagree on whether the paid plan is of the Workspace or of the site, so check both before relying on it. Nothing on this page applies to Interactions with GSAP, which are covered in Interactions with GSAP.
Classic Interactions, also called IX2 after the engine’s internal name, are the animation system that Webflow offered from 2016 until Interactions with GSAP became the default for new sites in July 2025. They remain in the product for two reasons: millions of published sites use them, and a few features have not yet moved to the newer engine. A designer who inherits a site, follows a book or a tutorial written before 2025, or needs a navbar or slider event will meet them, so this page explains what they are, how they are built, what Webflow writes into the page, and when to keep, leave or replace them.
The running example is the Fernbrook Gardens site, a fictitious botanical garden. Fernbrook’s older home page was built in 2021 with Classic Interactions: the hero heading fades in when the page loads, the "Rare plants" cards rise into view as the visitor scrolls, a header hides when scrolling down, and the mobile menu slides in when the hamburger button is pressed. The new events pages use Interactions with GSAP. The two coexist on one site, and the rest of this page is about what that coexistence costs.
What Classic Interactions are
An interaction in Classic is made of a trigger and one or more animations. The mental model is a two-state machine with a transition between them, which is the method the requester’s book teaches in its animation chapters: decide the initial state of an element, decide its final state, and let Webflow animate the transition between the two. Webflow writes the initial state when the page is ready, so the element starts hidden or displaced, and then plays the animation when the trigger fires.
The vocabulary of the Classic panel is the following.
| Term | Meaning |
|---|---|
Trigger |
The event that starts an animation: a click, a hover, a page load, an element scrolling into view, scrolling through a page, a component event of the navbar, dropdown, tabs or slider |
Action |
A timed or scroll-controlled animation made of steps (move, scale, rotate, skew, fade, size, background colour, transition, display, style, plugin or custom value) |
Start state |
The "initial state" of each target that is applied before the animation plays |
Easing and duration |
How long a step lasts and the speed curve it follows |
Affect |
The target of a step: the trigger element itself, a class, or a single element (a tag, an ID or a combo class) |
Element triggers
An element trigger belongs to one element in the Navigator and fires from what the visitor does to that element. The Classic Interactions panel lists the following element triggers.
-
Mouse click (tap). Has a first click and a second click, which lets one button open and close something. It is a tap on touch screens.
-
Mouse hover. Has a hover in and a hover out. On a touch screen a hover in plays on tap and the hover out when something else is tapped, so a hover-only interaction is fragile and the content must also be reachable by tap.
-
Scroll into view. Fires when the element enters the viewport and, if it is set up, when it leaves. The panel offers an offset to decide how far into the viewport the element must be, and whether the animation plays once or every time.
-
Scroll while in view. A scroll-controlled animation tied to the element’s position as it crosses the viewport.
-
Mouse move over element. Moves things according to the pointer position inside an element.
-
Tabs, dropdown, navbar and slider component triggers. The built-in components can raise an event when they open, close or change, which the next sections cover.
The first decision when building one is the target. A click on a card can affect the card itself, but it can also affect a different element: the hamburger button animates the menu panel and the icon lines. The Affect setting is where Classic differs from GSAP: a Classic action can target "this element", a class or a specific element, and the choice decides whether the action keeps working when the structure changes.
Fernbrook’s click interaction on the "Show planting calendar" button illustrates a typical Classic configuration:
Trigger: Mouse click (tap) on class "calendar-toggle"
First click: affect class "calendar-panel"
Size: Height 0 -> auto, 400 ms ease-out
Display: none -> block (applied at the start)
Second click: affect class "calendar-panel"
Size: Height auto -> 0, 300 ms ease-in
Display: block -> none (applied at the end)
The block is a description of settings rather than code, which is why it uses the text language. A single class target is enough for every calendar panel on the page, and the same interaction can be reused on other pages when the trigger element carries the same class.
Page triggers
A page trigger is not tied to an element. Page triggers run in the context of a whole page and are created from the page trigger part of the panel.
-
Page load. Runs when the page has loaded. It is the way to build a hero sequence, and the initial state of the targeted elements is written into the page so that there is no flash of the final state before the animation starts.
-
Page scroll (while scrolling the page). Runs a scroll-controlled animation over the scroll position of the whole page, for example a reading-progress bar, and a trigger can be limited to a section of the page.
The Fernbrook home page hero uses a page load interaction whose sequence is a short, staggered fade and rise: the heading, then the subheading, then the call-to-action button. In Classic the stagger is built by hand, by placing each step on a timeline with a start offset; the newer engine offers a stagger action. A page load animation delays the moment the heading reaches full opacity, so it competes with the Largest Contentful Paint when the animated element is the large text or image. Prefer starting with a visible state or a very short duration for anything that makes up the first screen. The performance trade-offs are in Performance Optimization.
An important property of a page load interaction in Classic is that the initial state is part of the published page: elements that start hidden are hidden by an inline style or class until the engine runs. If scripts fail to load, or are blocked, those elements stay hidden. That is a good reason not to hide any essential content (a form, a price, a navigation link) by means of an initial state.
Timed and scroll-controlled animations
Classic animations come in two kinds, and the kind decides what the timeline means.
Timed animations run for a fixed duration after the trigger fires, whatever the visitor does next. Each step has a duration, a delay and an easing curve, and steps on one timeline can run together or one after another. A timed animation can have a "start" state and, on the second event, a reverse. Most of what visitors notice, such as a fade in, a hover lift or a menu opening, is a timed animation.
Scroll-controlled animations (the "while scrolling in view" and "while scrolling the page" triggers) tie the timeline to the scroll position instead of to a clock. The timeline is shown as a percentage: at 0 per cent the element is at the first position and at 100 per cent at the last, and the animation is run forwards and backwards as the visitor scrolls. They are the Classic way to build the parallax effect of the book’s animation chapters: a background image that moves more slowly than the foreground, a heading that drifts, or a progress bar that fills. Each scroll step has controls for the point in the viewport where it starts and ends, which is a coarse cousin of the start and end of a scroll trigger in the GSAP engine.
Three recipes from the book’s animation chapters are worth stating in the Classic form, because they explain what old tutorials ask the reader to click.
-
Parallax. Put a background layer in a section with
overflow: hidden, give it extra height, and add a "while scrolling in view" animation that moves it on the Y axis by a small percentage across the whole timeline. -
Hide a header on scroll down. Fix the header, then add a scroll-direction animation on the page: when scrolling down, move the header up by its height, and when scrolling up, move it back. Classic offers "scroll up" and "scroll down" triggers on a page for this.
-
Back to top. A button shown only after the visitor has scrolled a screen away, using a "scroll into view" animation on a marker element near the top of the page, and a link to the top of the page for the click.
Each of these is still possible in Classic, and they are rebuilt with the newer engine in Scroll and Page Animations. The CSS ideas behind them, a clipped container and a transform, are explained in HTML and CSS animations.
Scroll-controlled animation has an accessibility consequence that Classic does not address by itself. A visitor whose operating system asks for reduced motion still receives the animation unless the author handles it, whereas Interactions with GSAP has a reduced-motion setting. A Classic interaction that moves large areas should be disabled, or reduced to a fade, for those visitors.
What still requires Classic
Webflow’s comparison article lists the features that are, at the time of checking, available only with Classic Interactions, and the features that are available only with Interactions with GSAP. The Classic-only list is short and is the reason a site can still need the old engine.
| Classic-only capability | What it means for Fernbrook |
|---|---|
Navbar open and close events |
The hamburger menu on mobile, which animates when the Navbar component opens or closes, cannot yet be driven by a GSAP trigger |
Dropdown open and close events |
The "Visit" dropdown that fades its list in needs the Classic dropdown trigger |
Tab change events |
The seasonal "Spring, Summer, Autumn, Winter" tabs on the planting guide animate their content with a tab event |
Slider change events |
The hero slider’s captions animate on each slide change |
Pages on a branch |
Page branching, covered in Page Branching, Releases and Approvals, works with Classic Interactions on those pages and not yet with the new ones |
Interactions on a secondary locale |
The Spanish and German versions of Fernbrook’s pages keep Classic Interactions defined on the primary locale; building new GSAP interactions there is not yet possible (see Localization) |
Component export with DevLink |
DevLink handles the new engine only for component-scoped interactions (see below) |
The comparison article also names a few other differences, such as animating variable values and certain media actions, in the same column; because the articles of the Help Center about those two features have not always agreed with the comparison, check the current page before planning around them.
The practical rule is therefore simple. Start every new interaction with Interactions with GSAP. Use Classic only for a navbar, dropdown, tab or slider event, on a branch, or on a non-primary locale, and for the sites that already have Classic Interactions and are not worth rebuilding. The same features that Classic still owns are summarised, with their dates, in Product Changes and Deprecations.
Switching between systems
Webflow describes the two engines as separate systems. A site that was created before Interactions with GSAP existed, or that already has Classic Interactions, keeps Classic as its interaction system, and a new site starts with the GSAP engine; the comparison article and the introductory article describe the default slightly differently, so open the Interactions panel of the site and look at which system it shows rather than assuming.
The practical consequences for a team that has both are the following.
-
No automatic conversion. An existing Classic interaction is not converted into a GSAP timeline. The concepts translate (initial state, final state, easing, delays), the panels do not. Rebuilding is manual, interaction by interaction.
-
One element, one system. Avoid animating the same element from both systems. Two engines writing transforms and opacity to one element produce results that depend on the order of loading, and a hover state written with CSS transitions on the same element adds a third writer. Choose one owner for each property of each element.
-
Collaboration. Real-time collaboration, covered in Collaboration, Comments and Activity Log, does not work on a site that still has Classic Interactions, which must be converted or removed first.
-
Two runtimes. A page that uses both pays for two scripts. A site that migrates fully to GSAP and removes the last Classic interaction no longer needs the Classic one.
A sensible migration plan for Fernbrook is gradual. Keep the navbar, dropdown, tab and slider interactions in Classic, because nothing else can drive them. Rebuild the scroll animations and page load sequences on the GSAP engine, because that is where the new features are. Remove the Classic copies once the replacement works, and test each page after each change, with the Designer’s preview and on the published staging domain, because a leftover Classic interaction keeps writing styles.
MCP and DevLink limits with Classic
The two developer routes into a Webflow site, the MCP server and DevLink, are both limited with Classic Interactions.
-
The MCP server cannot edit Classic Interactions. An AI agent connected to the Webflow MCP server can read and change many things in the Designer, but the server cannot create or edit Classic Interactions. A request such as "make the hero fade in on load" must be done in the Designer panel, or built with the GSAP engine. The server is described in MCP Server and AI Agents.
-
The Designer API covers only the GSAP engine. According to the developer documentation, it does not read or write Classic Interactions, so the interactions listing returns an empty list on a site that only has Classic ones. A Designer Extension that audits interactions will therefore miss them. See Designer Extensions and the Designer API.
-
DevLink exports little. Component export with DevLink carries the interactions that are scoped to a component and built with the new engine, and the first page-level Classic interaction in some cases; Lottie, Spline and Rive actions are not exported. A React component exported from Fernbrook’s "Rare plant card" will not reproduce a Classic hover animation, and the interaction has to be reimplemented in the target app. The topic is in DevLink Export.
The common consequence is that a design that depends on Classic Interactions is harder to automate, test and move to another stack. If a site is expected to be exported, managed through an agent, or migrated, that is a reason to rebuild its interactions on the new engine or in plain CSS and JavaScript, as explained in Code Export and Portability.
Unofficial re-initialisation calls
Webflow’s script starts the Classic engine once, when the page has loaded. A page that changes its content afterwards, for example by cloning a template element with JavaScript, loading part of a page with AJAX, or swapping pages with a transition library such as Barba.js or Swup, has new elements that the engine has never seen, so their interactions do nothing. Designers have worked around that with a handful of calls on the global Webflow object.
// Fernbrook: after inserting a fetched "Rare plants" card into the page,
// ask the Classic engine to look at the DOM again.
function reinitialiseClassicInteractions() {
if (!window.Webflow || !window.Webflow.require) {
return;
}
try {
const ix2 = window.Webflow.require('ix2');
if (ix2 && typeof ix2.init === 'function') {
ix2.init();
}
} catch (error) {
console.warn('Classic interactions could not be re-initialised', error);
}
}
document.addEventListener('fernbrook:cards-loaded', reinitialiseClassicInteractions);
The calls that circulate in the community are:
-
Webflow.require('ix2').init()asks the Classic engine to start again with the data it already holds and to look for elements that now match. -
Webflow.destroy()stops the Webflow scripts, including the Classic engine and its state, andWebflow.ready()runs the ready handlers again. The patterndestroy,ready, theninitis what most transition-library tutorials use after a page swap. -
Webflow.push(function () { ... })queues a function until Webflow’s runtime is ready, which makes custom code safe to place before the runtime loads.
These calls are not documented in the Webflow Help Center or the developer documentation. They come from forum answers, including a reply from a member of the Webflow staff, which says that the first call should work in most cases and that repeated calls restart the engine and query the DOM again. The same discussion records the limits: there is no way to initialise one interaction on its own, since all events are bound at once; the state of a scroll-controlled interaction can return to its default; and nothing guarantees that the calls will keep working when Webflow changes the runtime. Treat them as a workaround, and:
-
test the result on the published domain, not only in the Designer, because custom code does not run on the Designer canvas;
-
put them in a page-level footer script or a Code Embed, as covered in Custom Code in the Head, Footer and Embeds;
-
wrap them in a guard like the example, so that a missing runtime does not break the page;
-
never use them for Interactions with GSAP, because that engine has its own runtime. The forum threads about re-initialising the newer engine after page transitions are separate and also unofficial, and the approach to custom GSAP code is in Interactions with GSAP.
The related custom-code topics, including the Webflow.push queue, are in Custom Attributes and JavaScript.
The requester’s book, chapters 7 and 8
Chapters 7 and 8 of Ali Rushdan Tariq’s Webflow by Example (Packt, 2021) teach animation. They were written for the Classic panel, which was then the only one, and they remain a clear introduction to the method even though no click path in them matches the current screen.
What carries over:
-
the habit of defining a start state and an end state first and letting the transition fill the middle;
-
the distinction between an animation that is played by an event and one that is driven by scrolling;
-
the three recipes of parallax, a header that hides when the visitor scrolls down and a back-to-top control;
-
the advice to use animation sparingly, with a purpose.
What is outdated:
-
the panel is the Classic panel, with its own names for triggers and actions; a new site shows the Interactions with GSAP panel, which uses trigger, target and action on a timeline;
-
the book’s recipes are one-trigger, one-animation recipes. They can still be built in Classic, and they are simpler to build in the new engine, with scroll start and end markers, scrub and pin;
-
the book does not mention reduced-motion settings, accessibility, performance of animated first-screen content, or the limits that Classic has with MCP, DevLink, branches and localisation, all of which matter on a modern site.
The book is a reasonable second source for the reasoning and a poor source for the clicks. The broader list of differences between older material and today’s product is in Where Older Books and Tutorials Are Outdated.
Generated markup
Classic Interactions leave a small footprint in the HTML. An element that takes part in an interaction as a trigger or as a target receives a data-w-id attribute with a generated identifier, which Webflow’s script uses to find it. The identifiers are random-looking strings and carry no meaning.
<section class="hero">
<h1 data-w-id="00000000-0000-0000-0000-000000000001" style="opacity:0;transform:translate3d(0, 24px, 0)" class="hero-heading">
Fernbrook Gardens
</h1>
<a data-w-id="00000000-0000-0000-0000-000000000002" href="/visit" class="button">Plan your visit</a>
</section>
Three details of that output matter in practice.
-
Identifiers are placeholders in the example. A real site has different values. Their stability across publishes is not documented, so write no CSS selector and no custom script that depends on a particular value. Select by class or by a custom attribute that the designer controls, as described in Custom Attributes and JavaScript.
-
The initial state is written inline. The
styleattribute above is the "start state" of the page load interaction. It is why a blocked script leaves the heading invisible, and why a copy of the published HTML pasted into another tool shows blank sections. -
data-ixis the older system. Pages from the first generation of Webflow interactions, now called IX1, used adata-ixattribute. The attribute is still seen on very old sites, and Webflow’s script handles it, but a new interaction does not add it.
A Collection list item that repeats an element repeats the data-w-id, because the interaction is attached to the shared class structure. This is how one interaction can animate every card of the Fernbrook plant catalogue.
The ix2 data in the published script
The behaviour of every Classic interaction is stored in the published page, not in a separate file that a developer can edit. When a page uses Classic Interactions, Webflow adds an inline script that hands a serialised description of all the interactions to the runtime. The structure observed in published sites looks like this, abridged and with placeholder identifiers:
Webflow.require('ix2').init({
events: {
e: {
id: 'e',
name: '',
animationType: 'custom',
eventTypeId: 'PAGE_START',
action: { id: '', actionTypeId: 'GENERAL_START_ACTION', config: { delay: 0, easing: '', duration: 0, actionListId: 'a', affectedElements: {}, playInReverse: false, autoStopEventId: '' } },
mediaQueries: ['main', 'medium', 'small', 'tiny'],
target: { appliesTo: 'PAGE', styleBlockIds: [] },
config: { loop: false, playInReverse: false, scrollOffsetValue: null, scrollOffsetUnit: null, delay: null, direction: null, effectIn: null },
createdOn: 0
}
},
actionLists: {
a: {
id: 'a',
title: 'Hero load',
actionItemGroups: [],
useFirstGroupAsInitialState: true,
createdOn: 0
}
},
site: {
mediaQueries: [
{ key: 'main', min: 992, max: 10000 },
{ key: 'medium', min: 768, max: 991 },
{ key: 'small', min: 480, max: 767 },
{ key: 'tiny', min: 0, max: 479 }
]
}
});
The abridged object has three parts.
-
eventsholds one entry per trigger. An entry has an event type such as a page start, a click or a scroll into view, a target (a page, or an element identified by itsdata-w-idor by a class), and the media queries in which it is active. -
actionListsholds the timelines. Each list is made of groups of items, and each item has an action type (a move, a fade, a size change), the element it affects, and its values, duration and easing. The flaguseFirstGroupAsInitialStateis the "start state" of the earlier section. -
siteholds the breakpoints that the interactions respect. The interactions of Classic are turned on per breakpoint, and the list of media queries lets one interaction run on desktop and be disabled on mobile.
The consequences for a developer are practical. The data is generated and the format is internal, so editing it by hand is not supported, and the published page will overwrite any change at the next publish. It is readable, which helps to audit what a site animates when the Designer is not available, and it explains why the data increases the size of the page proportionally to the number of interactions. The runtime that interprets it is part of Webflow’s own JavaScript, loaded for every Webflow page, which is why a page with no interactions at all carries no ix2 data and a page that has them carries some kilobytes of it. The security view is simple: the object contains no secrets, only animation settings, and anything in it is public to every visitor.
The Designer API does not expose this data, as covered above. If an audit is needed, view the published source of the page, or export a copy of the site, as described in Code Export and Portability.
Common pitfalls
-
Flash of hidden content. A page load interaction hides its targets until the script runs; on a slow connection the visitor sees blank sections for a moment.
-
Interactions on hidden breakpoints. An interaction is enabled per breakpoint; a menu animation that works on desktop but not on mobile is usually switched off for the smaller breakpoint.
-
Layout shift. Animating width, height or margin instead of transform and opacity makes the browser recalculate layout and can move the content around the animated element.
-
Hover on touch screens. Content that is only revealed on hover cannot be reached by many visitors.
Checklist for an inherited Classic site
-
Open the Interactions panel and list the interactions by trigger; note the ones driven by a navbar, dropdown, tab or slider event, which must stay in Classic.
-
Check which interactions hide content in their initial state, and decide whether the content should stay visible without scripts.
-
Check scroll-controlled interactions for reduced-motion handling.
-
Decide for each remaining interaction whether to keep, rebuild with Interactions with GSAP, or replace with CSS transitions.
-
Look for custom code that calls
Webflow.require('ix2')orWebflow.destroy()and test it after each Webflow update. -
If the team uses real-time collaboration, the MCP server or DevLink, plan the removal of Classic Interactions first.