Exploded view
The plate from a parts manual, played by the wheel.
Documentation
-
Copy to Webflow
Add Geist and Geist Mono to your site's fonts (Site settings, Fonts, Google Fonts) before pasting: Webflow removes any font your site has not installed. -
Add custom CSS
Custom CSS in WebflowThis CSS already ships inside the Webflow embed, so a pasted section needs nothing added. Paste it yourself, in the page or the site custom code, only if the effect runs on several pages. The tutorial explains where.
See the tutorialThree things belong to the page rather than to the component: the box markeddata-exploded-viewtakes no height of its own, its height being one screen plus the scroll the view takes; no parent of that box may cut its overflow withoverflow: hidden, which stops the block from pinning, so useoverflow-x: clipwhere a parent has to cut; and the box that holds the parts takes nooverflow,filteroropacity, which would put its parts back on one plane. -
Add custom JS
Custom JavaScript in WebflowThis script already ships inside the Webflow embed, settings block included. You paste it yourself, before the closing body tag of the page or the site custom code, only when the effect has to run on several pages, and the tutorial says how to choose.
See the tutorial -
Tune it
How to add a custom attribute in WebflowA custom attribute is a pair, a name and a value, typed in the Settings panel of the element you selected, under Custom attributes. The name is what the script looks for, the value is what it reads. The tutorial shows the panel.
See the tutorialCustom attributesSelect the section on the canvas and open the Settings panel. Under Custom attributes, add a pair: the name on the left, the value on the right.Custom attribute What it does data-exploded-view Marks the box the page scrolls through while the object comes apart, a section or a block inside one; several can follow one another on a page. It takes no value: leave the value field empty. That box is what the stylesheet makes taller by the scroll the view takes, and what carries the settings. Without it on any element of the page, the embed marks the block holding the screen. data-exploded-view-pin Marks the block that stays on screen, a child of the box: the labels and the leaders are placed in it. It takes no value. Without it the engine takes the first block of the box. [ Optional ] data-exploded-view-stage Marks the room the object comes apart in: the open view is scaled to fit it, and it carries the perspective. It takes no value. Without it the engine takes the parent of the object. [ Optional ] data-exploded-view-object Marks the box that holds the parts, and nothing else: it is what turns and what the parts are stacked in. Its class gives it the proportions of the frame the layers were exported at, 1400 by 692 in the preview: set the aspect ratio of that class to your own frame's (in Webflow: Size, Ratio). It takes no value. Without it the engine takes the parent of the first part. [ Optional ] data-exploded-view-part Marks one part of the object. The parts are your own layers, in the order they stack, the first at the back. Each one is a picture on a transparent ground (export every layer of your Figma frame as a PNG, at the size of the whole frame) or any block of the page. Give each part one label, in the same order. Add or remove parts and labels: the view adapts to however many there are. Swap a picture, delete a part with its label or add one of each: the leaders, the numbers and the sides of the labels follow. A picture of another shape than the frame is set whole inside it. In Webflow, the parts being stacked, a click on the canvas always takes the one on top: pick a part in the Navigator, where they are the blocks named Part 1, back, to Part 6, front, inside the box named Object, and replace its image in the Settings panel. Export every layer at the size of the same frame. It takes no value. Two parts are the least. [ Required ] data-exploded-view-anchor="0.32 0.27" On a part, only to place by hand the point its leader starts from: two shares of the part's box, across then down, 0 0 its top left corner and 1 1 its bottom right. Without it the engine finds the point itself, on the part and near the end that faces its label: from the opaque pixels of a picture, from the box of what a block holds, from the lower corner of a block that holds nothing. [ Optional ] data-exploded-view-label Marks the label of a part, in the Navigator a block of the box named Labels, named Label 1 for Part 1: the first label names the first part, the back one, the second the second. With a number, data-exploded-view-label="3", it names that part instead. A part with no label moves and is never named. [ Optional ] data-exploded-view-labels Marks the box that holds the labels, so that it steps aside when the labels are set beside the object. It takes no value. [ Optional ] data-exploded-view-number Inside a label: marks the block of its number. The engine writes the rank of the label in the list there, 01 for the first, over digits or over nothing, so the numbers follow a label added or removed; a text of your own that is not digits stays as typed. It takes the accent colour while its part is the one being named. It takes no value. [ Optional ] data-exploded-view-track Marks a rule the scroll fills: it is scaled across by the place in the scroll. It takes no value. [ Optional ] data-exploded-view-state Written by the engine on the box: closed, moving, open, or still under reduced motion. Never written by hand; it is what the stylesheet reads to pin the block. [ Optional ] data-exploded-view-layout Written by the engine on the box: sides when the labels sit beside the object, list when they stay in the flow of the page. Never written by hand. [ Optional ] data-exploded-view-label-state Written by the engine on each label: on once its part has left its seat, off before. Never written by hand; the stylesheet reads it to bring the label in and out. The engine also writes data-exploded-view-label-side, left or right, and data-exploded-view-current on the label of the part being named. [ Optional ] SettingsEvery setting is a custom attribute too, added the same way and on the same section. An attribute always wins over the defaults written in the code.Attribute Default What it is data-exploded-view-line #f4ece0 Colour of the leaders, the rules that tie a label to its part, and of the point each one starts from. Options: any CSS colour. data-exploded-view-accent #ffab1a Colour of the part being named: its point on the object, and the number of its label when the label has one marked data-exploded-view-number. Options: any CSS colour. data-exploded-view-spread clamp(180px, min(44vh, 60vw), 520px) Distance between the first part and the last once the object is apart, any CSS length. The parts in between share it evenly. data-exploded-view-axis y Direction the parts leave in: x, y or z. Options: y stacks them up the screen, the last part of the markup at the top; x lays them across, the last on the right; z brings them towards the eye, which needs tiltX or tiltY to be seen. A minus sign turns it round: -y, -x, -z. data-exploded-view-depth 0.5 Share of the spread that also comes towards the eye, for x and y: the front parts come nearer and the back ones go further. data-exploded-view-tilt-x 5 Lean of the whole once it is apart, in degrees, around the horizontal: the top goes back. data-exploded-view-tilt-y -14 Turn of the whole once it is apart, in degrees, around the vertical. data-exploded-view-perspective clamp(900px, 110vw, 1800px) Distance of the eye from the stage, any CSS length. data-exploded-view-stagger 0.55 How much one part waits for the other, from 0 to 1. data-exploded-view-first front End of the stack that leaves first: front or back. Options: front starts with the last part of the markup, the one in front, then the first, then inwards from both ends; back starts with the first. data-exploded-view-length clamp(1500px, 360vh, 4400px) Scroll the view takes, any CSS length: how long the block holds the screen. data-exploded-view-hold 0.3 Share of the scroll the object spends fully apart, every label in place, from 0 to 0.9. data-exploded-view-reassemble on Whether the object closes again before the section ends: on or off. Options: on plays the move back in the last part of the scroll, so the page goes on with the object whole; off leaves the section with the object apart and its labels in place. data-exploded-view-smooth 0.18 Time the parts take to catch the scroll, in seconds. data-exploded-view-side auto Where the labels go: auto, alternate, left, right or list. Options: auto sets each label on the side its part sits on, and shares out the parts that sit in the middle so the two sides stay even; alternate goes left, right, left in the order the parts leave; left and right keep one side; list never sets them beside the object. Whatever is asked, the labels stay a list when the stage is too narrow for them. data-exploded-view-reach clamp(20px, 3.4vw, 64px) Distance between the open object and the near edge of a label, any CSS length. data-exploded-view-pointer 5 Most the mouse tilts the whole, in degrees, at the edge of the screen. data-exploded-view-fit on Whether the open view is scaled down to stay inside its stage: on or off. Options: on measures the object fully apart and scales it, only ever down, to the room the stage and the labels leave; off keeps the size of the CSS, and a spread too large runs out of the stage.
Two files and their pictures (6), no build step.
It runs in the browser only. Load it with a script tag in plain HTML, in a
client-side script in Astro, never in the frontmatter. In React, call
ExplodedView.mount(ref.current) in useEffect and
destroy() in its cleanup.
-
Tune it, either way
Per element with an attribute, or once for the whole site by editingDEFAULTSat the top of the file.Attribute Default What it is Lower Higher data-exploded-view-line #f4ece0 Colour of the leaders, the rules that tie a label to its part, and of the point each one starts from. Options: any CSS colour. data-exploded-view-accent #ffab1a Colour of the part being named: its point on the object, and the number of its label when the label has one marked data-exploded-view-number. Options: any CSS colour. data-exploded-view-spread clamp(180px, min(44vh, 60vw), 520px) Distance between the first part and the last once the object is apart, any CSS length. The parts in between share it evenly. Parts that stay close, still overlapping for a tall object Parts far apart. With fit on, a spread taller than the stage shrinks the whole view instead of leaving the screen data-exploded-view-axis y Direction the parts leave in: x, y or z. Options: y stacks them up the screen, the last part of the markup at the top; x lays them across, the last on the right; z brings them towards the eye, which needs tiltX or tiltY to be seen. A minus sign turns it round: -y, -x, -z. data-exploded-view-depth 0.5 Share of the spread that also comes towards the eye, for x and y: the front parts come nearer and the back ones go further. At 0 every part stays on one plane, and the turn and the pointer move the object as one flat card More depth between the parts: the perspective sizes them apart and a tilt slides them over one another data-exploded-view-tilt-x 5 Lean of the whole once it is apart, in degrees, around the horizontal: the top goes back. A flat-on view. Negative leans the top forward The view from further above. Past 20 a picture drawn head-on starts to look like a card data-exploded-view-tilt-y -14 Turn of the whole once it is apart, in degrees, around the vertical. Negative turns its left side away Positive turns its right side away. At 0 with tiltX at 0, depth only shows as size data-exploded-view-perspective clamp(900px, 110vw, 1800px) Distance of the eye from the stage, any CSS length. A close eye: strong differences of size between near and far parts A distant eye, flatter, closer to a technical drawing data-exploded-view-stagger 0.55 How much one part waits for the other, from 0 to 1. At 0 every part leaves at once, like an accordion At 1 a part only starts when the one before has arrived data-exploded-view-first front End of the stack that leaves first: front or back. Options: front starts with the last part of the markup, the one in front, then the first, then inwards from both ends; back starts with the first. data-exploded-view-length clamp(1500px, 360vh, 4400px) Scroll the view takes, any CSS length: how long the block holds the screen. A quick take-apart A slow one, each part with time to be read, and more wheel to turn before the page goes on data-exploded-view-hold 0.3 Share of the scroll the object spends fully apart, every label in place, from 0 to 0.9. The object closes almost as soon as it is open A long look at the plate, and a faster move on each side of it data-exploded-view-reassemble on Whether the object closes again before the section ends: on or off. Options: on plays the move back in the last part of the scroll, so the page goes on with the object whole; off leaves the section with the object apart and its labels in place. data-exploded-view-smooth 0.18 Time the parts take to catch the scroll, in seconds. At 0 the parts are locked to the scroll, right with a smooth scroll library already on the page Parts that glide after a wheel notch, and lag behind a fast scroll data-exploded-view-side auto Where the labels go: auto, alternate, left, right or list. Options: auto sets each label on the side its part sits on, and shares out the parts that sit in the middle so the two sides stay even; alternate goes left, right, left in the order the parts leave; left and right keep one side; list never sets them beside the object. Whatever is asked, the labels stay a list when the stage is too narrow for them. data-exploded-view-reach clamp(20px, 3.4vw, 64px) Distance between the open object and the near edge of a label, any CSS length. Labels close against the object Longer leaders, and less room for the object before it is scaled down data-exploded-view-pointer 5 Most the mouse tilts the whole, in degrees, at the edge of the screen. At 0 the pointer does nothing A livelier object. Past 10 the pictures show they are flat data-exploded-view-fit on Whether the open view is scaled down to stay inside its stage: on or off. Options: on measures the object fully apart and scales it, only ever down, to the room the stage and the labels leave; off keeps the size of the CSS, and a spread too large runs out of the stage. -
Drive it from JavaScript
When the parts, the labels or an attribute change after load, or when the page reacts to a part being named.const element = document.querySelector('[data-exploded-view]'); element.addEventListener('explodedview:change', (e) => { console.log(e.detail); }); const view = ExplodedView.mount(element); // the section auto() mounted, or a new one view.progress(); // 0 to 1, the place in the scroll view.open(); // 0 to 1, how far apart the object is view.refresh(); // after changing an attribute, a part or a label element.addEventListener('explodedview:part', (e) => { console.log(e.detail.index, e.detail.state); }); // When the section leaves the page: ExplodedView.destroy(element); // removes what it added and gives back the markup as it was
-
Fit it to your page
- Your own object. The parts are your own layers, in the order they stack, the first at the back. Each one is a picture on a transparent ground (export every layer of your Figma frame as a PNG, at the size of the whole frame) or any block of the page. Give each part one label, in the same order. Add or remove parts and labels: the view adapts to however many there are.
- Swapping a picture, adding or removing a part: nothing else to touch. Change the
srcof a part and its leader finds the new part by itself; delete a part and its label, or add one of each, and the labels are numbered again, placed again and shared between the two sides again. - The frame. The box of the object has the proportions of the frame the layers were exported at: in the preview,
aspect-ratio: 1400 / 692on the class of the object, the size of its six pictures. Set it to the proportions of your own frame. A picture of another shape does not push anything: it is set whole inside the frame (object-fit: contain), in its middle. - Structure: one box marked
data-exploded-view, a section or a block inside one, and as many as wanted one after the other, holding one block markeddata-exploded-view-pin: the block that stays on screen. Inside it, a stage markeddata-exploded-view-stage, the room the object comes apart in, and inside the stage the object, a box markeddata-exploded-view-objectthat holds the parts and nothing else. Without the marks the engine takes the parent of the first part as the object, the parent of the object as the stage and the first block of the box as the screen. - The parts are the elements marked
data-exploded-view-part, in the order a page stacks them: the first at the back, the last in front. All of them take the same cell, so each should be the size of the whole object: export every layer on the same artboard, with a transparent ground, and they register on their own. Pictures, inline SVG, or blocks of the page, anything a transform can move. Two parts are the least. - A label is any block marked
data-exploded-view-label, anywhere in the screen block. The first label names the first part, the back one, the second the second; a label that carries a number,data-exploded-view-label="3", names that part instead. A part can go without a label: it moves like the others and is never named, which is the way to add a shadow or a ground. - The number of a label is written by the engine: a block marked
data-exploded-view-numberthat holds digits, or nothing, takes the rank of its label in the list, 01 for the first, so the numbers follow a label added or removed. The digits typed in the markup are what shows before the script runs, on the Webflow canvas for one. Type anything other than digits in the block and the engine leaves it alone. - Where a leader starts is found by the engine. For a picture it reads the pixels that are not transparent and takes a point on the part, near the end that faces its label; for a block, the edge of what the block holds, on that side, and the lower corner of a block that holds nothing, a ground or a back sheet. No part of the preview needs more. To place a point by hand all the same, write
data-exploded-view-anchor="0.32 0.27"on the part, two shares of its box, across and down. - Beside the object, or a list: the labels sit beside the object when the stage is wide enough for the closed object, a label and
reachon each side used. The engine then writes each label's place and its side, and the stylesheet takes it out of the flow. Otherwise the labels stay where the markup put them, a list, and only their state is written. The width a label takes beside the object is the width its own CSS gives it. - The box around the labels is marked
data-exploded-view-labelswhen it should step aside once the labels are set beside the object, so the stage takes its room. - Making the parts: render or draw the object once per part from one fixed point of view, each part alone on a transparent ground, all at the same size. An orthographic view is the one that stays true when the parts slide apart. WebP keeps the transparency: the six parts of the preview, 1400 by 692, weigh 86 KB in all.
- One setting for every section of the page, without opening the file: declare
window.ExplodedViewSettings = { stagger: 0.3 }in a script placed beforeexploded-view.js. The three levels, least specific first, areDEFAULTS, then that object, then adata-exploded-view-*attribute on the section itself (data-exploded-view-tilt-y="-20"), so one section can still differ from the page-wide setting. - What the script writes:
data-exploded-view-stateon the section,closed,movingoropen, andstillunder reduced motion;data-exploded-view-layout,sidesorlist; on each labeldata-exploded-view-label-state,onoroff,data-exploded-view-label-side,leftorright, when it has one, anddata-exploded-view-currenton the one being named. A transform on the object and on each part. Two custom properties on the section, 0 to 1, for any rule of your own:--exploded-view-progress, the place in the scroll, and--exploded-view-open, how far apart the object is. An element markeddata-exploded-view-trackis scaled across by the first. It adds one empty point per named part inside the object, and one SVG, the sheet of leaders, at the end of the screen block. - From JavaScript:
ExplodedView.mount(element, overrides)returns the instance, withelement,settings,state(),progress()andopen()from 0 to 1,layout(),refresh()after an attribute, a part or a label changed, anddestroy(). The section emitsexplodedview:changewith{ element, state }andexplodedview:partwith{ element, part, label, index, state }each time a part is named or let go; both bubble. - **
destroy()leaves the section as it was**: the points and the sheet of leaders removed, the transforms, the states and the custom properties taken off, the listeners and the observers gone. - Touch: the view follows the page scroll, so a finger drives it as a wheel does. The tilt answers a mouse only.
- **
prefers-reduced-motion**: no pin and nothing moves. The object is whole, the labels are a list under it, all lit. Turning the preference off brings the view back without a reload. - Without the script the page shows the same thing: the object whole, since the parts stack by CSS, and the list of its parts.
- Smooth scroll libraries: nothing to wire. The engine listens to scroll events and reads the section's place from the layout, which is what Lenis and the like move. Set
smoothto 0 if the two glides add up. - The words and the pictures of the markup are the preview's, and they ship as they are. Put the user's own in their place whenever they want.
- On Webflow, add the fonts first. Add Geist and Geist Mono to your site's fonts (Site settings, Fonts, Google Fonts) before pasting: the paste names them, and the Designer drops a font the site does not have.
-
Avoid the pitfalls
- Every layer exported at the size of the whole frame. The parts share one cell and are never positioned by hand, so a layer registers with the others only when it was exported on the same artboard. A layer cropped to its own part breaks nothing, but it lands in the middle of the frame, as large as the frame allows: not where it belongs.
- A picture the browser cannot read gets its point in the middle. The engine finds where a leader starts by reading the picture, which a browser refuses for a page opened as a file from the disk and for a picture hosted on another site that sends no CORS header (Webflow's CDN sends it). The console says so. Serve the page, even locally, or write
data-exploded-view-anchoron the part. - An ancestor that cuts its overflow kills the pin, silently.
overflow: hiddenon a parent makes it the scroll container of the sticky block, and a container that does not scroll has nowhere to pin. Useoverflow-x: clipwhere a parent has to cut. The engine says so in the console when it finds one. - Give the section no height of its own. Its height is one screen plus
length, the second added by the stylesheet as the::afterof the section: a fixed height cuts the hold short or leaves a blank, and a section that already uses its::afterloses it while the view is on. - Nothing between the stage and the object may flatten the depth. An
overflow, afilter, anopacityunder 1 or aclip-pathon the object box puts its parts back on one plane: the parts still slide, the perspective and the tilt stop separating them. Put such effects on the stage or on a part, never on the object. - A label needs a width of its own to sit beside the object. Out of the flow, a block with no width is as wide as its longest line. The preview gives its labels a
max-width; without one a long sentence makes one wide label, and the stage may no longer have the room for the sides. - The labels are placed in the screen block. The engine writes their place from its top left corner, so no box between that block and a label may be positioned (
position: relative) or transformed. - Late pictures move the labels once. A part still loading has no height; the layout is measured again when it lands. Give every picture its
widthandheightattributes and nothing jumps. - **
axisatzneeds a tilt.** Parts that only come towards the eye stay one over the other;tiltXaround 55 andtiltYaround -25 turn a flat stack into the classic isometric plate. - **
axisatzfor a screen: stack the pieces from the foot up.** Under a tilt, a layer nearer the eye is drawn higher. Layers whose piece sits lower on the screen should therefore come first in the markup, and the piece at the top last: the open stack is then a clean staircase. In any other order two pieces land over one another;axisatyorxhas no such rule. - **Settings handed to
mount()after the page loaded are dropped.**auto()mounts on DOM ready, andmount()on a section that already carries the effect returns the existing one. A page-wide block goes inwindow.ExplodedViewSettings, whichauto()reads itself; a later change goes through an attribute andrefresh(). - On the canvas of the Webflow Designer, where no script runs, the object is whole, its parts stacked in one cell by their own classes, each one a block of the Navigator to select and replace, and the labels are the list, one under the other, each readable and editable. A click on the canvas always takes the part on top, the six being stacked: pick a part in the Navigator, where they are named Part 1, back, to Part 6, front, and replace its picture in its settings. The view only comes apart on the published page and in preview.
One click on Copy the AI prompt copies everything an assistant needs to build this effect: the complete code, the markup, the dependency, every setting and every pitfall.
What it does
Exploded view is a scroll animation for Webflow and vanilla JavaScript, with no library. Also called exploded view on scroll, exploded product animation or product teardown animation.
The plate from a parts manual, played by the wheel. A section holds the screen while the page scrolls through it, and the object in its middle comes apart: its parts leave their seat one after the other, from the outside in, along one axis and in perspective, the whole turning a little so the depth reads. Each part is named as it arrives, by a label set at its own height and tied to it by one rule that draws itself from the part to the words; then the object closes again by the same move played back, before the page moves on. The parts are the page's own elements, pictures with a transparent ground or anything else, stacked in one cell in the order a page stacks them. The labels are the page's own blocks: beside the object, on the side each part is nearest to and pushed off one another, when the screen has the room; a list under the object, the part being named lit, when it has not. The open view is scaled to the room it has, so nothing ever runs under a label or out of the screen. The move is eased towards the scroll, and a mouse tilts the whole a little. CSS 3D transforms and one SVG for the leaders, no WebGL and no library: the hold is sticky positioning, the position is read from the layout, so it follows the browser's own scroll and a smooth scroll library alike. Under reduced motion, and without the script, the object is whole and its parts are a list. Pattern type exploded view, product teardown, layered product reveal.
Updated
Questions
Mark a section data-exploded-view, the block that stays on screen data-exploded-view-pin, and inside it a stage, data-exploded-view-stage, holding one box marked data-exploded-view-object. Each child of that box marked data-exploded-view-part is a layer, the first at the back, and each block marked data-exploded-view-label names the part of the same rank. data-exploded-view-length is the scroll the view takes.
No library at all, and no WebGL. The hold is CSS sticky positioning, the place in the scroll is read from the layout, the parts move by CSS 3D transforms and the leaders are one SVG. It follows the browser's own scroll and a smooth scroll library alike, and Webflow.destroy() has nothing to take away.
Export every layer of the object at the size of the whole frame, on a transparent ground, from one fixed point of view: the parts share one cell and register on their own. Transparent WebP keeps them light, 86 KB for the six parts of the preview. A part can also be any block of the page, with no picture at all, and adding or removing a part and its label needs nothing else: the labels are numbered and placed again.
Yes. data-exploded-view-axis takes y, the default, x or z, with a minus sign to turn it round, and data-exploded-view-spread is the distance between the first part and the last. data-exploded-view-tilt-x and data-exploded-view-tilt-y turn the open view so the depth reads, data-exploded-view-stagger, 0.55 by default, sets how much one part waits for the other, and data-exploded-view-reassemble="off" leaves the object apart at the end.
A finger drives it as a wheel does, since the view follows the page scroll. When the stage is too narrow to set the labels beside the object, they stay a list under it and the part being named lights up; the open view is scaled down to the room it has. Under reduced motion and without the script nothing is pinned: the object is whole and its parts are a list, all readable.