Chapter 2: Interactions & Animations (1.B)
Exam topic 1.B: Create dynamic experiences while prioritizing performance and accessibility.
Exam topic 1.B: Create dynamic experiences while prioritizing performance and accessibility.
Key terms: Triggers, actions, motion timing, easing, scroll effects, motion settings, motion considerations.
Weight: 9% of the exam (about 4–5 questions)
Look at the wording of the topic: while prioritizing performance and accessibility. The exam isn’t checking whether you can make things move. It checks whether you can make things move responsibly. The official sample question for this topic (“what should you prioritize for production readiness?” → test performance and ensure motion does not interfere with accessibility) shows exactly where the exam puts the weight.
2.1 The mental model: triggers → actions → targets
Every Webflow interaction has three parts:
- Trigger: when something happens (a click, hover, scroll position, page load).
- Actions: what happens, arranged on a timeline (move, fade, scale…).
- Target: which elements the actions apply to (the trigger element, all elements with a class, children, siblings…).
Webflow has been moving to a new interactions system powered by GSAP, after it acquired GreenSock. The concepts below (triggers, actions, timelines, easing, scroll-linked progress, targeting) apply to both the classic interactions panel and the GSAP-based one. Learn the concepts; the panel layout may change.
2.2 Triggers
Element triggers
| Trigger | Typical use |
|---|---|
| Mouse click (tap) | Accordions, toggles, custom modals. Often has a first click and a second click |
| Mouse hover | Card lift, image zoom. Not available on touch devices |
| Mouse move over element | Tilt/parallax following the cursor |
| Scroll into view | Reveal content as it enters the viewport (fires once or every time) |
| While scrolling in view | Animation progress tied to the element’s position in the viewport |
| Component-specific | Navbar open/close, Dropdown open/close, Tab change, Slider change |
Page triggers
| Trigger | Typical use |
|---|---|
| Page load (page start / page finished) | Intro sequences, preloaders |
| Page scrolled (scroll up / down) | Hide the navbar on scroll down, show it on scroll up |
| While page is scrolling | Progress bars, page-wide parallax |
| Mouse move in viewport | Cursor followers, background parallax |
Two kinds of animation
- Event-based (time-driven): a trigger fires and a timeline plays over a duration (click → open in 300ms).
- Scroll- or mouse-linked (progress-driven): the timeline is mapped to 0–100% progress of the scroll or cursor position. There’s no duration; the user’s scroll is the playhead. A smoothing setting adds inertia.
You need to know which kind a scenario calls for. “Reveal once when visible” is Scroll into view. “Rotate as the user scrolls through the section” is While scrolling in view.
2.3 Actions and the timeline
Common actions: Move, Scale, Rotate, Skew (transforms), Opacity, Size, Filter (blur, etc.), Background/Border/Text colour, Display, and plugin actions for Lottie, Spline and Rive.
Timeline concepts
- Delay: when the action starts on the timeline. Staggering delays (0, 100ms, 200ms) creates cascades.
- Duration: how long it runs.
- Initial state: the value before the animation plays (e.g.
opacity: 0; translateY: 2rem). Webflow renders initial states into the published HTML as inline styles on the target elements, so elements don’t flash at their final state before the interactions JavaScript runs. - Reusable interactions: one interaction (e.g. “Fade up on scroll”) applied to many elements by class means one definition to maintain.
Targeting: the most-tested detail
When an interaction targets a class, by default it affects every element on the page with that class. That’s the classic bug where clicking one FAQ opens all of them. The fix is to scope the target:
| Option | Effect |
|---|---|
| Only children with this class | Only matching elements inside the trigger element |
| Sibling elements with this class | Matching elements next to the trigger |
| Parent element with this class | Matching ancestor |
| Element (specific) | One exact element: not reusable |
Scope interactions relative to the trigger and apply them to a class. One interaction then works for every FAQ item, card or tab, including CMS-generated items.
2.4 Motion timing and easing
Duration guidelines
| Interaction | Typical duration |
|---|---|
| Micro-interactions (hover, toggles) | 150–250ms |
| Small UI transitions (dropdown, accordion) | 200–350ms |
| Larger movements (modals, panels) | 300–500ms |
| Page intro sequences | up to ~1s total. Never block content for long |
If an interaction feels sluggish, it usually is. Users repeat UI interactions many times, and long durations become frustrating.
Easing
Easing describes how speed changes over the duration:
- Ease-out (fast start, slow end): best for elements entering, because the UI responds immediately.
- Ease-in (slow start, fast end): suits elements leaving.
- Ease-in-out: elements moving from one place to another on screen.
- Linear: almost only for scroll-linked animations (where the user’s scroll already gives natural easing) or continuous loops like spinners.
- Custom cubic-bézier / spring curves give a brand its own feel.
2.5 Scroll effects
- Reveal on scroll (Scroll into view): set an offset so the animation starts once the element is a bit inside the viewport, and decide whether it plays once or every time. For content reveals, “once” is usually better.
- Parallax (While scrolling in view): move layers at different rates. Keep the distances small. Large parallax movement is a common trigger for vestibular discomfort.
- Sticky + scroll-linked: a sticky container (
position: sticky) with a tall parent produces “scrollytelling” sections. Remember thatposition: stickystops working if any ancestor hasoverflow: hidden. - Avoid scroll-jacking (overriding native scroll speed or direction). It breaks expectations, accessibility tools and trackpad momentum.
2.6 Performance: animate the cheap properties
Browsers render in stages: style → layout → paint → composite.
| Property animated | Cost | Why |
|---|---|---|
transform (move, scale, rotate) |
✅ Cheap | Composite only; can run on the GPU |
opacity |
✅ Cheap | Composite only |
filter (blur) |
⚠️ Medium | Paint-heavy on large areas |
background-color, color, box-shadow |
⚠️ Paint | Repaints every frame |
width, height, top, left, margin, padding |
❌ Expensive | Triggers layout of the page every frame |
Rules:
- Use Move instead of animating
marginortop. Use Scale instead of animatingwidth/heightwhere the effect allows it. - Don’t animate dozens of elements at once on scroll, especially with blur.
- Lottie: keep files small, avoid huge embedded raster images, and don’t autoplay many Lotties above the fold.
- Test on a real mid-range phone and use DevTools → Performance (CPU throttling) to find dropped frames.
- Layout shift: animations that move content into place (instead of fading in a space that’s already reserved) can hurt CLS. Animate with transforms inside reserved space.
- Don’t hide your LCP element behind an intro animation. If the hero heading or image starts at
opacity: 0and fades in after JavaScript runs, Largest Contentful Paint gets later. Keep the LCP element visible immediately.
2.7 Accessibility and motion considerations
Reduced motion
Some users set “Reduce motion” in their OS because animation can cause dizziness, nausea or distraction (vestibular disorders, migraine, ADHD). Browsers expose this as the media query prefers-reduced-motion: reduce.
A production build should respect it:
- Use Webflow’s motion settings for reduced motion where your interactions panel offers them. The GSAP-based interactions system has options for this.
- Where the panel can’t handle it, add a reduced-motion fallback in custom code, e.g.:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
(CSS like this covers CSS transitions and animations. JavaScript-driven interactions need their own check, window.matchMedia('(prefers-reduced-motion: reduce)'), or the platform’s motion setting.)
Reduced motion doesn’t mean no change. Swap large movement for a simple fade or an instant state change.
WCAG criteria to know
| Criterion | What it means for interactions |
|---|---|
| 2.2.2 Pause, Stop, Hide | Auto-moving content lasting > 5s (carousels, marquees, looping video) needs a way to pause it |
| 2.3.1 Three Flashes | Nothing flashes more than 3 times per second |
| 2.3.3 Animation from Interactions (AAA) | Motion triggered by interaction can be disabled |
| 2.1.1 Keyboard | Anything that works on click must work with the keyboard |
| 4.1.2 Name, Role, Value | Custom toggles must expose their state (e.g. aria-expanded) |
Interaction-specific accessibility traps
- Hover-only content: unreachable on touch and keyboard. Pair hover with focus, or use click.
- Custom accordions/modals built with Div Blocks and click triggers aren’t keyboard accessible by default. Use real
<button>elements, or addrole="button",tabindex="0",aria-expandedand keyboard handling. Modals also need focus trapping and Esc to close. Webflow’s native components (Dropdown, Tabs, Navbar) already handle much of this, which is a strong reason to prefer them. - Display: none vs. opacity: 0: an element faded to
opacity: 0is still focusable and read by screen readers. When hiding something completely, end the animation with Display: none (and start with Display: block/flex when showing it).
2.8 Breakpoint behaviour
Interactions can be enabled or disabled per breakpoint. A cursor-follow effect or a complex desktop scroll sequence is often better turned off on mobile, where there’s no cursor and less CPU. Disabling it for those breakpoints beats building a duplicate mobile layout.
2.9 When to use custom code
Use Webflow’s interactions for most motion. Reach for custom JavaScript or GSAP code when you need logic the panel can’t express: physics, data-driven animation, canvas/WebGL, or animations that must re-initialise after content is injected dynamically. “Custom JavaScript for every animation” is a wrong answer on the exam, because it hurts maintainability and makes the site harder for other team members to edit.
2.10 Production checklist
- ☐ Only
transformandopacityanimated wherever possible. - ☐ Interactions applied by class, scoped to children/siblings, and reusable.
- ☐ LCP element visible without waiting for an animation.
- ☐ Reduced-motion preference respected.
- ☐ No essential content behind hover only.
- ☐ Custom toggles keyboard-accessible with correct ARIA state.
- ☐ Hidden states end with
display: none. - ☐ Heavy effects disabled on mobile breakpoints where they add little.
- ☐ Tested on a real phone and with CPU throttling.
Practice questions: Interactions & Animations
Q1 A page has 12 FAQ items built from the same structure. Clicking any question should open only its own answer. The answer elements share the class faq_answer. How should the interaction be targeted?
Show answer
Answer: b. Apply the trigger to the class of the FAQ item and target Only children with this class. One reusable interaction then works for every item, including future CMS items, and each click opens only its own answer. (a) a plain class target opens every faq_answer on the page. (c) 12 interactions is unmaintainable and breaks as soon as an item is added. (d) doesn’t meet the requirement.
Q2 (Multi-select) Which properties are the best choices for smooth, performant animation? (Choose two.)
Show answer
Answer: a and b. Transforms and opacity are handled in the composite stage and don’t trigger layout or paint, so they’re cheapest to animate. (c) margin-top and (d) width force the browser to recalculate layout every frame, which causes jank.
Q3 A section should rotate an illustration gradually as the user scrolls through it, reversing if they scroll back up. Which trigger fits?
Show answer
Answer: b. While scrolling in view maps animation progress to the element’s position in the viewport, so the rotation follows the scroll and reverses with it. (a) Scroll into view fires a timed animation once (or each time) when the element appears; it isn’t tied to scroll position. (c) and (d) aren’t scroll-linked.
Q4 A hero heading (the page’s LCP element) fades in from opacity: 0 over 1.2s on page load. Lighthouse reports a poor LCP. What’s the best fix?
Show answer
Answer: b. LCP measures when the largest content element is rendered. An element at opacity: 0 waiting for JavaScript delays that. Keep it visible and animate secondary elements, or use a subtle transform that doesn’t hide it. (a) makes it worse. (c) the hero is above the fold, so a scroll trigger doesn’t solve anything. (d) images can also be the LCP element; that just moves the problem.
Q5 Which easing is most appropriate for a dropdown panel entering the screen?
Show answer
Answer: c. Ease-out starts fast and settles gently, so the UI feels responsive as the panel enters. (b) ease-in starts slowly, which feels laggy for entrances; it suits exits. (a) linear feels mechanical outside scroll-linked contexts. (d) exaggerated overshoot is distracting for routine UI.
Q6 (Multi-select) A landing page has scroll-linked parallax, a looping marquee and many reveal animations. Which steps make it production-ready from an accessibility standpoint? (Choose three.)
Show answer
Answer: a, b and c. These map to reduced-motion support, WCAG 2.2.2 (Pause, Stop, Hide) and WCAG 2.3.1 (Three Flashes). (d) larger parallax distance increases vestibular risk, the opposite of what’s needed.
Q7 A custom modal is hidden by fading to opacity: 0 at the end of a close interaction. Keyboard users report that Tab moves focus into invisible links. What’s the fix?
Show answer
Answer: b. opacity: 0 hides an element visually only. It stays in the layout, stays focusable and stays exposed to screen readers. Ending with display: none removes it from the accessibility tree and the tab order. (a) and (c) don’t remove focusability. (d) is unrelated.
Q8 A cursor-following “magnetic” effect and a heavy desktop scroll sequence cause jank on phones and are pointless without a mouse. What’s the most maintainable approach?
Show answer
Answer: b. Webflow interactions can be turned off per breakpoint, which is the native, maintainable solution. (a) duplicates content and doubles maintenance. (c) adds fragile custom code; user-agent sniffing is unreliable. (d) shorter durations don’t fix CPU cost or the lack of a cursor.
Q9 Which scenario most justifies custom code instead of the native interactions panel?
Show answer
Answer: c. Physics, data-driven logic and re-initialising after dynamic DOM changes go beyond what the native panel can express, so custom code (e.g. GSAP) is justified. (a), (b) and (d) are standard native interactions. Writing custom code for them adds maintenance cost with no benefit, the “custom JavaScript for every animation” distractor from the official samples.
Q10 Elements briefly appear at their final position and then jump to their initial state when the page loads. What is the most relevant concept?
Show answer
Answer: a. This “flash of final state” is what initial states prevent. When an interaction defines an initial state, Webflow can output it as an inline style in the published HTML, so the element starts in its pre-animation state before scripts run. The other options don’t relate to load-time rendering.
Q11 (Multi-select) A custom accordion uses Div Blocks with click triggers. Which changes improve accessibility? (Choose two.)
Show answer
Answer: a and b. A real button (or the equivalent role and tabindex) makes the toggle focusable and keyboard-operable, and aria-expanded tells assistive technology whether the panel is open (WCAG 2.1.1, 4.1.2). (c) removing focus outlines fails WCAG 2.4.7 Focus Visible. (d) hover is unavailable on touch and keyboard.
Q12 A reveal animation on 40 cards uses Move + Opacity + a blur filter at the same time, and scrolling drops frames on mid-range Android devices. What’s the best first change?
Show answer
Answer: a. Blur filters are paint-heavy, and animating them on 40 elements is the likely cause. Transform + opacity give nearly the same look at a fraction of the cost. (b) more elements means more work. (c) easing doesn’t change rendering cost. (d) a 2-second stagger per card makes the experience slow and doesn’t fix the per-frame cost.