Build a scroll-driven data story for the web: write one claim per section in a story manifest, choreograph chart states that change as the reader scrolls past a sticky graphic, keep text and visual in lockstep on mobile and desktop, ship reduced-motion, no-JS and no-observer fallbacks so the story reads with animation off, and hold the page to a stated performance budget. Triggers on scrollytelling, scroll-driven story, data story, sticky graphic, scrollama, scroll-triggered chart, or a longform page where charts change on scroll.
./install.sh scrollytelling-data-storyname: scrollytelling_data_story description: Build a scroll-driven data story for the web: write one claim per section in a story manifest, choreograph chart states that change as the reader scrolls past a sticky graphic, keep text and visual in lockstep on mobile and desktop, ship reduced-motion, no-JS and no-observer fallbacks so the story reads with animation off, and hold the page to a stated performance budget. Triggers on scrollytelling, scroll-driven story, data story, sticky graphic, scrollama, scroll-triggered chart, or a longform page where charts change on scroll.
Build a web page where scrolling through short text steps changes one chart in stages, so a reader gets a data argument one claim at a time instead of facing the finished chart all at once.
The failure this skill prevents is drift: text that promises one thing while the chart shows another, a sticky graphic that never sticks on phones, a story that goes blank with JavaScript off, and a page so heavy the chart arrives after the reader has scrolled past it. The fix is order of work. Write the story as a manifest first, choreograph states against that manifest, build the fallback document before the scroll effects, and check the finished page against a budget.
Bundled tools and material:
bin/story_check.py validates a story manifest: one claim per step, a distinct chart state per step, data behind every state, alt text, fallback text, a mobile note per step, named fallbacks, and a critical resource budget. Standard library only.assets/story-manifest.example.json is a complete validated manifest built from NASA GISTEMP v4 annual temperature data.references/story-arc-template.md gives the five beat arc and every manifest field.references/choreography-checklist.md covers sticky structure, triggers, chart states, and failure drills.references/accessibility-fallbacks.md covers reduced motion, no-JS reading, chart text alternatives, and keyboard pass conditions, tied to WCAG criteria.references/worked-example.md builds the example manifest into a page with a native IntersectionObserver skeleton, no library required.references/story-arc-template.md. Default to five steps, stay between three and nine. Each step gets one claim in one sentence of 140 characters or fewer, supporting text of about 90 words or fewer, one chart state described in plain words, the data rows that state shows, alt text that leads with the trend, fallback text with the values in reading order, and a mobile note for that state. Read the claims alone, in order. They must form the whole argument with no chart present. Rewrite until they do.python3 bin/story_check.py <manifest.json>. Fix every FAIL line. Treat WARN lines as edit notes: long stories and long step text are where readers leave. Do not start markup with a failing manifest, because the build will faithfully reproduce the manifest's mistakes.position: sticky and an inset such as top: 0. The chart scrolls into view, sticks while the steps pass, then unsticks at the end of its section, which is the sticky graphic pattern The Pudding documents for Scrollama. Check ancestors for stray overflow values, since an ancestor with overflow: hidden, auto, or scroll becomes the scroll container and can stop the graphic sticking to the viewport. Drive state changes with IntersectionObserver, directly or through Scrollama, which is built on it. Set the trigger near the middle of the viewport: Scrollama defaults its offset to 0.5, and a native observer can get the same effect with a rootMargin that shrinks the root to the middle line. Record the trigger value in the story notes.references/choreography-checklist.md open. Keep the chart, the axis, the scale, and the units fixed across all states unless a change of scale is itself a step's claim and the text says so. Change one thing per step: a highlight, a range, an annotation, a group. Pair every colour change with a label, a direct value, or a marker change. Set each state from the active step index, so fast scrolling and scrolling back up both land on the exact right state without replaying skipped transitions.vh: mobile browsers show and hide their bars while scrolling, the viewport height changes, and triggers jump. Set step heights in px from window.innerHeight on load and on resize instead. Second, keep CSS and JavaScript breakpoints in sync with the same matchMedia query. On small screens, stack the chart above the steps or run it as a shorter sticky band, keep annotations inside the chart area, stack end labels that would collide, and drop any state that depends on hover. Follow each step's mobile note from the manifest.references/accessibility-fallbacks.md. Honour prefers-reduced-motion in CSS and check it in JavaScript through matchMedia: with reduce, states swap with no drawing animation, no parallax, and no self-moving parts, which is how a page meets WCAG 2.3.3 on interaction-triggered animation. Give any auto-moving content a pause, stop, or hide control, per WCAG 2.2.2. Add a fallback order for a missing IntersectionObserver: throttled scroll check, then the recap state as the static default. Never leave content hidden at zero opacity waiting for a trigger.Deliver these, every time:
bin/story_check.py with zero FAIL lines, with source URL, baseline, and unit filled in.publisher key 2e43c913833850e6d80f939677e3de76e806d47785c0f1caaca90f9d18c98e1e
No ratings yet — be the first to rate it.