Sticker peel
Any element becomes a sticker. Take it by a corner, or by an edge, and it peels with the hand: it folds along a straight crease that follows the pointer at any angle, the part folded over shows the back of the sticker with a soft roll at the fold, it casts a shadow on what is still stuck, and what shows underneath is a second face of your own, a message, a price, another button, not a hole.
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 tutorialThe box that carriesdata-sticker-peelhas to hug the front: no padding, no border, nothing else inside but the two faces. And nothing close around a sticker may clip it withoverflow: hidden, the flap folds out of its box. -
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 -
Use it on your own elements
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 element 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-sticker-peel Marks a sticker: a box that hugs the element that peels and holds nothing else. It takes no value: leave the value field empty. It carries the settings. Put it around any element of the page, as many as you like; each one peels on its own. data-sticker-peel-front On the element that peels, inside the sticker: a card, a label, a link, a picture. It takes no value. It decides the size of the sticker. Without it nothing is mounted, and the console says so. [ Required ] data-sticker-peel-under On the face that shows underneath, inside the sticker, after the front. It takes no value. The stylesheet lays it exactly behind the front and hides it until the sticker lifts. Without it the page behind the sticker shows through the fold. [ Optional ] data-sticker-peel-label On the sticker, with a few words as its value: what a screen reader says for the button that peels it. Without it the button says Peel back. [ Optional ] data-sticker-peel-state Written by the engine on the sticker: idle at rest, lifted under the pointer, peeling in the hand, settling on the way back, held, falling, off, and still or flipped under reduced motion. Never written by hand. [ Optional ] SettingsEvery setting is a custom attribute too, added the same way and on the same element. An attribute always wins over the defaults written in the code.Attribute Default What it is data-sticker-peel-back-color auto Colour of the back of the sticker, the side the fold shows. Options: auto, the front's own background colour mixed with paper white, and paper white alone under a front with no background; or any CSS colour. Taken out of this block, --sticker-peel-back on the sticker takes over. data-sticker-peel-grab corners Where the sticker can be taken from. Options: corners, the four corners; edges, the four sides; all, both; or a list of names among top-left, top-right, bottom-right, bottom-left, top, right, bottom, left, for instance top-right bottom-right. The first name of the list, in that order with top-right first, is the corner the keyboard peels. data-sticker-peel-reach clamp(22px, 2.4vw, 36px) Size of the square at each corner that takes the pointer, any CSS unit or a percentage of the sticker; never more than half of it. data-sticker-peel-curl clamp(6px, 0.8vw, 12px) Radius of the roll of paper at the fold, any CSS unit. data-sticker-peel-shadow 0.5 Strength of the two shadows, the one the flap casts and the one under the roll, 0 to 1. data-sticker-peel-lift clamp(12px, 1.5vw, 24px) How far a corner rises when the pointer comes over it, any CSS unit. data-sticker-peel-threshold 0.5 Share of the sticker peeled, 0 to 1, from which a release counts as beyond. data-sticker-peel-beyond back What a release beyond the threshold does. Options: back, the sticker lays back down as it does before the threshold; hold, it stays peeled where it was left, and a click on its corner lays it back; off, it peels to the end, falls away and leaves the face underneath. data-sticker-peel-duration 0.55 Time the sticker takes to lay back down from fully peeled, in seconds; a smaller peel takes its share of it.
Two files, 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
StickerPeel.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-sticker-peel-back-color auto Colour of the back of the sticker, the side the fold shows. Options: auto, the front's own background colour mixed with paper white, and paper white alone under a front with no background; or any CSS colour. Taken out of this block, --sticker-peel-back on the sticker takes over. data-sticker-peel-grab corners Where the sticker can be taken from. Options: corners, the four corners; edges, the four sides; all, both; or a list of names among top-left, top-right, bottom-right, bottom-left, top, right, bottom, left, for instance top-right bottom-right. The first name of the list, in that order with top-right first, is the corner the keyboard peels. data-sticker-peel-reach clamp(22px, 2.4vw, 36px) Size of the square at each corner that takes the pointer, any CSS unit or a percentage of the sticker; never more than half of it. A corner that has to be aimed at, and more of the front left to clicks and selection Easier to take, on a phone above all; a round sticker needs about 36% for the square to reach its rim data-sticker-peel-curl clamp(6px, 0.8vw, 12px) Radius of the roll of paper at the fold, any CSS unit. At 0 a sharp crease, like folded card A thick, soft roll, like vinyl; past a quarter of the sticker the roll eats the fold data-sticker-peel-shadow 0.5 Strength of the two shadows, the one the flap casts and the one under the roll, 0 to 1. At 0 no shadow at all, and a flat look Heavy shadows, a sticker held high over the page data-sticker-peel-lift clamp(12px, 1.5vw, 24px) How far a corner rises when the pointer comes over it, any CSS unit. At 0 no invitation: nothing moves until the sticker is taken A corner that visibly curls up; past a third of the sticker it hides the front data-sticker-peel-threshold 0.5 Share of the sticker peeled, 0 to 1, from which a release counts as beyond. The smallest peel is enough to hold the sticker open or take it off The sticker has to be peeled nearly whole; at 1 a release never counts as beyond data-sticker-peel-beyond back What a release beyond the threshold does. Options: back, the sticker lays back down as it does before the threshold; hold, it stays peeled where it was left, and a click on its corner lays it back; off, it peels to the end, falls away and leaves the face underneath. data-sticker-peel-duration 0.55 Time the sticker takes to lay back down from fully peeled, in seconds; a smaller peel takes its share of it. A sticker that snaps back A slow, heavy sheet -
Drive it from JavaScript
When something other than a hand should peel a sticker: a sticker that opens by itself when it scrolls into view, a button elsewhere that reveals every offer, or a sticker put back after it came off.const element = document.querySelector('[data-sticker-peel]'); element.addEventListener('stickerpeel:release', (e) => { console.log(e.detail); }); const sticker = StickerPeel.mount(element); // the sticker auto() mounted, or a new one sticker.peel(0.5, 'top-right'); // peels half of it from that corner, and holds sticker.stick(); // lays it back down, from held or from off element.addEventListener('stickerpeel:off', () => { /* the sticker came off */ }); // When the sticker leaves the page: sticker.destroy(); // removes the two boxes the script added and the listeners
-
Fit it to your page
- Structure: three marks.
data-sticker-peelgoes on a box that hugs the sticker and holds nothing else: the sticker. Inside it,data-sticker-peel-frontgoes on the element that peels, a card, a label, a link, a button, a picture, anddata-sticker-peel-underon the face that shows underneath. The front decides the size; the stylesheet lays the face underneath exactly behind it and hides it until the sticker lifts. - The face underneath is real content. It is the page's own element: a message, a price, a picture, another link. It can be clicked and read as soon as it shows. Without one, the page behind the sticker shows through the fold, which is right for a sticker on a photograph.
- The front stays the page's element. Nothing wraps it and nothing copies it. At rest its text can be selected, and a link or a button works: a press on a corner that did not travel more than a few pixels is handed to the front as a click.
- **Any shape that a
border-radiusmakes**: square corners, rounded ones, a pill, a circle, corners that differ. The back, the roll and the shadow take the radius of the front, read when the sticker is lifted. - A sticker can be turned or scaled by a transform of its own or of a parent: the pointer is read in the sticker's own space.
- One setting for every sticker of the page, without opening the file: declare
window.StickerPeelSettings = { beyond: 'hold' }in a script placed beforesticker-peel.js. The three levels, least specific first, areDEFAULTS, then that object, then adata-sticker-peel-*attribute on the sticker itself (data-sticker-peel-beyond="off"), so one sticker can still differ from the page-wide setting. - The back can also come from the stylesheet: with
backColorleft onauto, a custom property--sticker-peel-backon the sticker is read before the front's own colour. - What the script adds and writes. Two boxes as the last children of the sticker:
data-sticker-peel-layers, the back, the roll and the shadow, shown only while the sticker is lifted, anddata-sticker-peel-handles, one small grab zone per place named bygrab, the first of them a realbutton. On the sticker,data-sticker-peel-state:idleat rest,liftedunder the pointer,peelingin the hand,settlingon the way back,held,falling,off, andstillorflippedunder reduced motion;data-sticker-peel-openwhile the face underneath shows; anddata-sticker-peel-focuswhile the keyboard is on it. While the sticker is lifted, an inlineclip-pathon the front and on the face underneath, taken off once it is flat again. - Events, all on the sticker, all bubbling:
stickerpeel:grab{ sticker, place }when a hand, a key orpeel()starts to peel;stickerpeel:release{ sticker, progress, beyond }when the hand lets go;stickerpeel:offwhen the sticker has fallen away;stickerpeel:stickwhen it is flat again after a peel. - **From JavaScript, beyond
mount,autoanddestroy**: the api carrieselement,front,under,settings,peel(amount, place)which peels by itself to a share of the sticker and holds,stick()which lays it back, from held or from off,off()which takes it off whateverbeyondsays,progress(),state(),isRunning()andrefresh(), to call after a setting or an attribute changed. - The label of the button:
data-sticker-peel-labelon the sticker is what a screen reader says for it, "Peel back" without one. - Keyboard: each sticker is one Tab stop, on its first grab zone. A link or a button you put on the front keeps its own stop, reached just before the sticker's: the button of the preview has two. Enter or Space peels it open and holds it, or takes it off when
beyondisoff; the same key lays it back, even from off. Escape lays a held sticker back. The button says pressed while the face underneath shows, and that face is out of the reading order while the sticker is flat. - Touch: a finger on a corner peels, and the page does not scroll from there; a finger anywhere else on the sticker scrolls the page as usual. A tap on a corner is a tap on the front. There is no hover, so no corner lifts by itself: say it in the page, as the preview does.
- **
prefers-reduced-motion**: no fold, no lift, no drag. A click on a corner, or the key, switches plainly between the front and the face underneath. Turning the preference off brings the peel back without a reload. - Without JavaScript the front is complete and the face underneath stays hidden: nothing is lost but the second face.
- 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.
- In the Webflow Designer the two faces show one under the other. The Designer never runs the Embed, so the canvas shows each face underneath below its front, where its text can be edited. On the published site, and in preview, it sits behind the front.
- Structure: three marks.
-
Avoid the pitfalls
- The sticker has to hug its front. The box that carries
data-sticker-peeltakes no padding and no border, and holds the front and the face underneath and nothing else: the grab zones are laid on its corners, not on the front's. - Nothing around a sticker may clip it. The flap folds over the sticker and out of its box, and falls through the page when it comes off:
overflow: hiddenon a close parent cuts it. On the section itself it is welcome, it keeps a falling sticker from stretching the page. - **The face underneath is
position: absolute, set by the stylesheet.** It takes the box of the front whatever its own size, and clips what does not fit. A layout of your own for it has to hold in that box. - A front with no background shows a paper white back. The back is one flat colour;
autoreads the front'sbackground-color, and a front made of a picture or a gradient has none to read. Name the colour. - **A
clip-pathof your own on the front is replaced while it peels.** The fold is a clip-path on the front. A shape cut withclip-pathor a mask is not followed by the back either: onlyborder-radiusis. - **A round sticker needs a larger
reach.** The grab zones sit in the corners of the box, which a circle leaves empty. Withreachat about 36% they overlap its rim. - **Settings handed to
mount()after the page loaded are dropped.**auto()mounts on DOM ready, andmount()on a sticker that already carries the effect returns the existing one. A page-wide block goes inwindow.StickerPeelSettings, whichauto()reads itself; after changing an attribute by script, callrefresh(). - **The shading is a
color-mix()of the back colour.** A browser too old forcolor-mix()paints the back flat, without its lighter fold. - A resize lays the sticker back. The fold is measured in pixels when the sticker is lifted; a held sticker goes flat when the window changes size, and a sticker that is off stays off.
- A link under a corner is followed with a plain click only. The click handed to the front is the script's: a middle click or a modified click on a corner does not open a new tab. Everywhere else on the front the link is the browser's own.
- The sticker has to hug its front. The box that carries
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
Sticker peel is a cursor animation for Webflow and vanilla JavaScript, with no library. Also called sticker peel effect, peelable sticker or peel off sticker animation.
Any element becomes a sticker. Take it by a corner, or by an edge, and it peels with the hand: it folds along a straight crease that follows the pointer at any angle, the part folded over shows the back of the sticker with a soft roll at the fold, it casts a shadow on what is still stuck, and what shows underneath is a second face of your own, a message, a price, another button, not a hole. Let go and it lays back down with a slightly sticky ease; past a threshold it can also stay peeled, or come off for good and fall away. Under the pointer a corner lifts a little as an invitation. The fold is geometry, not a picture: the front is the page's own element, cut with a clip-path and never turned into a bitmap, so its text stays sharp on any screen and selectable at rest, and a link still works on a click that was not a peel. It holds for any size, any corner radius, a pill or a full circle, and a sticker turned on the page. Each sticker is one Tab stop, after any link of its own front: Enter or Space peels it and lays it back. Under reduced motion there is no fold, the corner is a plain switch between the two faces. Without the script the front is all there is. No library, no canvas, no picture to load.
Updated
Questions
Three custom attributes: data-sticker-peel on a box that hugs the sticker and holds nothing else, data-sticker-peel-front on the element that peels and data-sticker-peel-under on the face that shows underneath. The front decides the size and the stylesheet lays the second face exactly behind it. Settings go on the sticker, for instance data-sticker-peel-beyond="off".
Neither, and no library. The front is the page's own element, cut with a clip-path and never turned into a bitmap, so its text stays sharp on any screen and can be selected at rest. The back, the roll at the fold and the shadow are gradients drawn while the sticker is lifted.
Yes, with data-sticker-peel-beyond. A release past threshold, half the sticker by default, lays it back down with back, the default, keeps it peeled with hold, or lets it come off and fall away with off. From JavaScript, peel(amount, place) peels it by itself and holds, stick() lays it back and off() takes it off.
Yes, on both faces. A press on a corner that did not travel more than a few pixels is handed to the front as a click, so a link or a button on the front works. The face underneath is the page's own element too, and can be clicked and read as soon as it shows.
It takes any shape a border-radius makes, a pill or a full circle included, and a sticker turned on the page. A finger on a corner peels, and a finger anywhere else on the sticker scrolls the page as usual. Each sticker is one Tab stop: Enter or Space peels it open, the same key lays it back, and Escape lays a held sticker back.