Button Lab

Restyle
Colour Graphite
Text
Button
Palette
Radius
Version
Theme

Compound

Two mechanisms from the sections below, running on one curve — a fill and a label, an edge and a mark. The pairing is the study: read the parts on their own first.

119Swell

Card 15's roll against a plate that grows under it. They do not fuse into one movement because they are on different axes — the label translates on Y while the plate scales — and the grow is capped at 1.03: at 1.06 the plate wins and the roll becomes something you notice afterwards.

CSSCode in FramerSubtle

123Crest

The one sequenced pairing here: card 10's sheen is delayed by exactly the duration of card 49's lift, so the light crosses the face only once the face has arrived. Played together they read as two effects on one button; played in order they read as one material catching a light it just moved into. Elevation stays lightness — bg-2 to bg-3, no shadow.

CSSCode in FramerSubtle

121Tide

Card 09's fill rising under card 20's letters, and the 26ms stagger is not decoration: it is the fill's own arrival time, sampled per letter, so each character flips just after the front has passed it. The roll is shorter than the fill, so the last letter still lands before the plate is full.

CSSCode in FramerBold

138Counter-rolling pair

Card 15's roll, run twice with opposite sign: the label lifts to its duplicate while the mark drops to its own, both across the same distance on the same curve. Every other pairing here takes two different mechanisms; this takes one and turns half of it around, which is the cheapest way to get the tension 124 names — two channels leaving the same way would be the same word said twice, and the only thing separating repetition from a pair is that one of them goes against. The plate carries the shared curve underneath, so there is one arrival and two readings of it.

CSSCode in FramerSubtle

120Lands first

The same two ingredients as 119, argued from card 52 instead: one curve, DIFFERENT rungs. The label is light and lands at 200ms; the plate is heavy and is still settling at 450ms, darkening a step as it goes. The compound is the gap between the two arrivals, and nothing rotates.

CSSCode in FramerSubtle

122Leading edge

Card 07 sweeping under card 11's arrow, with one change to the sweep: the front is an ellipse pinned to the left edge rather than a scaled rectangle, because a scaleX front is a flat vertical line and that is the one shape a wave never has. The arrow leaves by the edge the front is heading for, so the pair reads as a single movement.

CSSCode in FramerBold

124Closing marks

Card 13's marks close IN while the label grows. Marks out and label open would be two channels saying the same word twice; a frame tightening against type expanding is a tension, and that is what makes it read as one gesture. The label grows on a transform and not on tracking, because tracking changes the label's width and a hug-content button is as wide as its label.

CSSCode in FramerSubtle

Plate

The whole surface answers at once: it scales, lifts, leans, or argues with the pointer about its own weight.

41Inset fill

The plate sits an even four pixels inside its own measure and grows out to the hairline on hover, deepening a shade as it lands — on two concentric capsules a uniform inset is the only band that is provably even at every point.

CSSCode in FramerBold

126Squash and stretch

The plate is a soft mass and the area it covers is conserved — six per cent of width costs 5.6 of height, so the two multiply back to within a thousandth of where they started, which is the whole difference between this and a scale. The word takes the exact inverse and holds its size, because a 999px radius leaves no corner to watch and the gap at the end caps is the only landmark a deformation has here — without something rigid inside it, a soft mass that grows with everything in it is just a scale again. The settle overshoots through rest and squashes briefly the other way, the part a spring does and an ease-out cannot; 119 grows a plate under a label, and this is the only study here that deforms the plate itself.

CSSCode in FramerBold

43Keycap

The plate stands on a hard bottom edge like a keycap and collapses under the press.

CSSVariant in FramerSubtle

49Elevation step

The plate lights first and rises a beat later, and the label rolls over one character at a time across exactly that beat — the last letter lands on the frame the plate does.

CSSVariant in FramerSubtle

82Riser

Two legs grow from the bottom edge, the plate rises by exactly their height, and a face comes up over the top. The trailing leg lands a frame late so the button steps rather than levitates, and the line it was resting on gets drawn behind it. The only study here with an anatomy.

CSSCode in FramerBold

117Fixed shadow

Gumroad's checkout button. The plate slides up-left four pixels while the shadow grows down-right by the same four, so the shadow never moves: it is the seat the plate left. Feed the Accent swatch #ff90e8 to reassemble the shape — the seat arrives in that pink's own dark, because a seat is read against the card on one side and the plate on the other, and a grey one measured 1.17:1 against this plate.

CSSCode in FramerBold

140Answers back

Two faces on one hinge inside a single perspective: the front turns 85° away and up out of it while the back comes from −90° to flat. 34 and 104 are called flips and neither moves — they swap a light source on press — so this is the only study here where the plate has a back at all. What is written on that back is the study: it does not repeat the front, it answers it, and the objection the label raises is gone by the time the turn finishes.

CSSCode in FramerBold

116Stack fan

The plate lifts and three more fan out beneath it. They are plates and not shadow — three steps of one tone, drawn by one property at the plate's own radius, so depth is still stated as lightness. The tone follows the picked colour and lands where the grey did.

CSSCode in FramerSubtle

147Turns over

A closed prism, not a flip: two faces 45px apart and a floor hinged at the bottom edge, turning a half circle. Every face carries the same word, so nothing is revealed — an object simply tumbles. It has no roof, which is the point: mid-turn you are looking down into an open container. Recreated from Item-Box on tiny-mighty-buttons.webflow.io, whose geometry and easing this keeps.

CSSCode in FramerBold

148Counts its turns

147 always comes back. This one adds a roof, puts a different word on each of the four faces, and advances exactly a quarter turn per hover without returning — so the button holds its state in its geometry rather than in a class. The square profile is what makes it legal: at 45px deep against a 45px face, a quarter turn presents a face the same size as the one it replaced.

CSS + JSCode in FramerBold

149Stops halfway

147 passes through 90° in about 200ms and never lets you see it. This stops there: hover holds the box open with the floor face square to you, and press finishes the turn. One move split across two states, so hover and press stop competing for the same rotation — the same split 129 makes between a park and a landing.

CSSCode in FramerBold

150Rounds a corner

Half a turn on X and a whole one on Y, on nested elements finishing 90ms apart, so the box goes round a corner instead of spinning on a spit. The depth is in the asynchrony. Two axes means two elements — one element cannot carry two transforms on two clocks — and only X keeps the overshoot, because two bouncing axes read as a wobble.

CSSCode in FramerBold

50Magnetic

The button is drawn toward the pointer on a critically damped spring; the label follows with extra parallax.

JSCode in FramerBold

130Loose label

50 draws the whole button toward the pointer and lets the label parallax a little further. Turned inside out: the plate is nailed down and only the word drifts, capped at five pixels across, which stops the button being the thing attracted and makes it a frame the label is loose inside — a different feeling, not a smaller one.

CSS + JSCode in FramerSubtle

52Two masses

The arrow and the label leave at the same instant and travel the same distance at different rates, so the light one arrives first and the pair closes up by two pixels before the heavier label lands and restores the gap.

CSSCode in FramerSubtle

131Two targets

The plate answers which half of itself you are on, and it reads that from structure rather than from coordinates: :has() asks which child is hovered. 09, 75 and 111 all measure where the pointer is and hand CSS the number; this needs no number and no script at all, because the question is not where but which of these two.

CSSCode in FramerBold

136Grows its word

Card 128 opens the plate for a mark that arrives; this opens it for a word that was there all along, clipped to no width. It is the second study allowed to re-measure, and for the same reason: the silhouette change is the subject, so nothing here can be faked with a transform. The radius resolves against the live height, so the button is a true pill at both widths instead of changing shape family on the way out.

CSSCode in FramerBold

143Tightens

136 grows a plate until it fits a word. This closes one down onto it: the surface turns a corner toward you, gives up its radius from a pill to 6px, and draws in symmetrically until it is the label plus one step — 20px of padding to 8px — so the close has a destination it can reach rather than a distance it was told to travel. The label rides the tilt, because it is printed on the surface, but it does not follow it home: it hops out through the top and back in from the bottom while the plate is still moving, and the two things are on different clocks on purpose. Take the pointer away and the word hops the other way — out through the bottom, back in from the top — because the swap is two copies on transitions rather than one node on a keyframe, and a keyframe that only exists on hover has no way out at all.

CSSCode in FramerSubtle

146Only the ends are pixels

137 rasterises the whole plate; here the raster is confined to the two end-caps, so what changes is the SILHOUETTE. The plate withdraws to its label 11px at a time, the box holding its size and the label its place, and the cells ghost rather than switch off, so the shape given up stays readable behind the one kept. 143 tightens by re-measuring its padding; this tightens with nothing moving at all.

CSSCode in FramerBold

86Hairline only

One property moves and nothing travels — the least a button can do and still answer, with the house press doing the rest. The floor of the set, and of the page. Not in the library: it is here as the reference the other studies are measured against rather than as a button to drop into a page, so it hands over CSS and nothing else.

CSSVariant in FramerSubtle

Fill

A fill arrives or leaves. What differs is where it comes from and whether you can see it travel.

07One-way sweep

The fill enters from the left and leaves to the right — it never reverses the way it came. One fixed direction, and that is the point: card 75 is the one that reads which edge the pointer crossed.

CSSCode in FramerBold

75Directional fill

The fill enters from whichever of the four edges the pointer actually crossed, and leaves by the opposite one.

CSS + JSCode in FramerBold

129Takes turns

The fill enters from a different edge on each pass, cycling left, top, right and bottom, and leaves by the opposite one. 75 reads the edge the pointer actually crossed; this reads nothing — the order is authored, which is 25's argument moved from letters to edges, and it gives the button a rhythm of its own instead of a reflection of how you came at it.

CSS + JSCode in FramerBold

08Shutter

The fill comes down from the top edge and rolls back up to it. The anchor is the whole card: 07 sweeps across on one axis and this drops on the other, and a shutter that opened from its own middle would be a curtain.

CSSVariant in FramerBold

09Ink fill

The fill grows from the exact point where the pointer entered — and retreats to where it left. The radius is measured to the farthest point of the plate from that point, so the ink lands exactly as the transition ends rather than nearly: a guessed radius overshoots by a different amount on every plate width, and spends the slow tail of the ease off-screen. The plate is a stadium, so the measurement is to its outline and not to the corners of its box.

CSS + JSCode in FramerBold

111Press fill

The plate shrinks two per cent and drops half an elevation step as the pointer arrives, so the press has an approach rather than a start; the flood then runs from the point you pressed — the one study here you can call off: drag off the plate and it retracts, release outside and nothing happened. Card 74 times the press; this one places it.

CSS + JSCode in FramerBold

135The plus is the source

Every other fill on the page starts at the pointer or at an edge. This one starts at the mark: the bloom opens from the centre of the plus and spreads outward, so it arrives the same way whichever side you come in on, and the origin is derived from the padding and the mark rather than typed as a number. The polarity follows the front, which is why the plus turns first and the label a beat later.

CSSCode in FramerBold

91Stepped fill

Six columns rise on a stagger, so the fill arrives with a jagged leading edge and resolves flat. It does not retract: on the way out it collapses toward the ceiling, last column first. Blocks arriving, not a front moving.

CSSCode in FramerBold

139The wash outlives the fill

Two tilted panels sweep up under the label 64ms apart, so the fill arrives as one gesture in two stages: the first is only the wash that announces it, the second is the one that stays. 91 steps a fill in visible units along the same edge; this splits it across two panels that never share an edge. The exit is where it argues — the delay is stated in BOTH rules, so leaving, the fill goes first and the wash it arrived under is the last thing off the plate. A Framer gesture variant has no way to say that: its exit is always its entrance played backwards.

CSSCode in FramerBold

137Pixel dissolve

The plate is a raster and the fill arrives cell by cell rather than as a front: twenty-four cells, eight by three, each waiting its own turn. The order is authored, not random — cell i goes at rank (i × 7) mod 24, and because 7 is coprime with 24 no two neighbours hold neighbouring delays. That is card 25's argument moved from letters to a grid, and 91 is the nearest fill: it arrives in visible units too, but in six columns that still read as a front. The leave is the same order compressed to a fraction of its spread, so the plate dissolves out the way it came instead of clearing in one frame. The label rolls a third of that spread behind the raster, and it is blended rather than timed: 91 reveals a twin in the fill’s colour in the same six steps its fill arrives in, but a twin has to be clipped against a front and a raster has none, so at every moment the word covers cells on both sides of the flip. Difference resolves that per cell.

CSSCode in FramerBold

Edge

The outline does the work and the plate holds still: an underline, a rule, a drawn border, a corner that changes shape.

14Directional underline

In from the left, out to the right — the line never snaps back.

CSSCode in FramerSubtle

39Centre underline

The rule grows from the centre of the word and retreats to it. Card 14 flips its origin so the underline arrives from one side and leaves by the other; with no direction to read, this underlines the label.

CSSVariant in FramerSubtle

57Real underline

The browser's own underline thickens and rises toward the baseline, so skip-ink keeps clean gaps around the descenders the whole way through.

CSSCode in FramerSubtle

55Rule bend

The rule under the label deflects four pixels, like a beam under load, and comes back straight — the path itself is interpolated rather than a bent shape being scaled.

CSSCode in FramerBold

13Crop marks

Register marks land in the corners, as on a press sheet.

CSSVariant in FramerSubtle

42Edge light

A streak of the primary circles the hairline for as long as the pointer stays, and holds its place when it goes. It travels the outline, not an angle: a conic gradient crosses the caps 11.6 times faster than the flanks.

CSSCode in FramerSubtle

28Chamfered corner

The chamfered corners unfold and the rectangle becomes whole.

CSSCode in FramerSubtle

98Cell chamfer

Card 28 unfolds a chamfer along a straight diagonal; at bitmap resolution the same corner can only leave as whole cells, two of them, in two steps. The one card here the toolbar's radius cannot reach.

CSSCode in FramerSubtle

Label

The word performs: as one piece, so the button can change what it says without changing size — then split, so the characters can move apart.

15Label roll

The label rolls up and its duplicate takes its place from below — and the plate opens a slot for an arrow that arrives one delay behind it, so the room is made before anything is in it. Cards 20 and 23 do the same roll per character and per word; neither can open a slot, because ten characters have nowhere to open one between them. That is what this card is for.

CSSCode in FramerSubtle

127Arc swap

The swap travels an arc rather than a rail: both copies pivot ten line-heights below the baseline, so one rotation of five degrees carries the sideways drift and the tilt as consequences instead of as two more properties timed to agree with it. 15 is this gesture on a straight line and 70 pivots the mark; this pivots the word, and the ground draws back three pixels behind it while the border stays where it is.

CSSCode in FramerBold

19Overflow only

The label moves only if it is actually too long for the plate; if it fits, nothing happens at all.

CSS + JSCode in FramerBold

30Counter

The counter wakes and steps up to today's number.

CSSCode in FramerBold

20Letter roll

Card 15's gesture resolved per character: each letter leaves through the top of its own box while its duplicate arrives from the bottom, 26ms apart. An identical label replaces the one that left.

CSSCode in FramerBold

23Word roll

The same roll with the unit changed, and the answer to who would actually ship this. Four words reading themselves out is a CTA; twenty-one characters is a wave passing over a button. Only the granularity moved.

CSSCode in FramerSubtle

21Letter lift

The same stagger with nothing masked and nothing duplicated: each character lifts 3px and returns. Here as the argument that card 20 is usually the wrong choice — a roll needs a mask, a duplicate and a deep enough box.

CSSCode in FramerSubtle

24Middle out

The same lift ordered by distance from the label's centre rather than by reading order. Both ends move last, so the word breathes from the middle as one object instead of reading as a queue being served.

CSSCode in FramerSubtle

141Bursts from the middle

20 rolls each character through its own box on a straight line. Here the pair gets a diagonal, and the diagonal is not shared: every character's direction and rotation are derived from where it sits in the word, so the label bursts outward from its own centre rather than sliding one way as a block. The stagger runs middle-out with it — 24's order, thrown — and the arrival overshoots, so the replacement lands like something dropped into a hand. It fires on pointerenter and finishes even if you leave; that one-shot is the character of it, and a hover-driven animation would snap back mid-flight.

CSS + JSCode in FramerBold

25Random stagger

The same lift with the order taken away: a fixed permutation chosen so no two neighbouring characters hold neighbouring delays. CSS has no randomness, so the disorder is authored — a surface disturbed, not a sequence played.

CSSCode in FramerSubtle

26Weight wave

The weight rises in the characters nearest the pointer and ebbs once it has passed — the typography answers, nothing moves.

CSS + JSCode in FramerSubtle

85Nervous type

Every letter tilts on its own timing, so the word never settles. Card 26 also works letter by letter, but it moves weight and only where the pointer is; this moves geometry everywhere at once, and reads as hand-drawn.

CSSCode in FramerBold

142Each letter keeps its area

126 conserves the area of the plate; this conserves the area of a glyph. Each character compresses to .72 of its height and is charged 1.389 of width for it, so the two multiply back to within a ten-thousandth of where they started and the letter fattens as it flattens — the difference between a squash and a scale, at the one scale small enough that you read it as the type moving rather than the button. 26 and 85 change the characters in place too, but neither pays for what it takes. A tone pulse rides the same 700ms clock rather than one of its own, so the colour is part of the squash and not a second event happening near it.

CSS + JSCode in FramerBold

144Hinged at the first letter

Every swap here pivots on something the whole word shares: 15 rails it, 20 rails it per character, and 127 pivots ten line-heights below the baseline so the word tilts as one rigid object. This hinges on the word’s OWN LEFT EDGE, so travel is proportional to each character’s distance from the start — the C barely moves and the k at the end swings through nearly fifteen pixels. The word that arrives is the same word, so there is nothing to read but the motion, and rotation is the only channel: no lift, no drift, no tracking. Sixteen degrees is the angle at which the filled version still holds it — measured on the plate, the outgoing copy stays inside by seven pixels.

CSSCode in FramerSubtle

80Resolve

The label churns and locks in left to right, drawing only on its own characters, so the button never shows a glyph that does not belong to it.

CSS + JSCode in FramerBold

Mark

A small mark beside the label carries the gesture: an arrow travels, an icon redraws itself, a caret points.

11Arrow relay

The arrow leaves to the right and its twin takes over from the left, and the plate grows four per cent and shades down behind them. The growth is on the background alone — scaling the button would take both arrows with it, and the arrows are the study.

CSSVariant in FramerSubtle

12Dot to arrow

The dot that marks rest gives way to the arrow that marks action — in the same fixed slot, so nothing in the layout jumps.

CSSVariant in FramerSubtle

145One dot, five times

12’s dot marks rest and gives way to the arrow in a fixed slot. This one does not give way. There are five dots in that 3px box at rest, stacked exactly, and one length pulls them apart: each dot’s place is its index times THE SAME NUMBER, signed for the vertical and folded for the horizontal. So the chevron is not a second glyph, it is the dot at a different value, and the mark travels BETWEEN shapes rather than being swapped for one. Tiny Mighty’s arrow-dots computes its head the same way and then draws it once; the number is what is animated here, which is also why one control in Framer can hold the whole set.

CSSCode in FramerSubtle

69Clipped relay

One capsule with two windows, and only their contents move: the arrow exits the right edge and the next enters from the left, while the label rolls up out of the top and its next copy arrives from below. Each window advances its content the way that content reads. Neither comes back — every pass advances the cycle, the one study with no exit.

CSS + JSCode in FramerBold

59Exit velocity

The mark's way home is handed the pointer's exit velocity, so a quick sweep away carries it about two and a half pixels past rest before it settles and a slow drift simply eases home. It rests as a ring and fills as it goes, so it reports its state as well as its travel.

JSCode in FramerSubtle

78Corner exit

Card 09's fill, taken off the pointer and pinned to the corner the mark points at: the plate fills from the exit while the mark leaves by it, so the pair is two directions on one diagonal rather than one said twice — the trap card 124 names. The mark still only rotates. It used to lift and then leave along the line it was now pointing down, three properties arguing that the turn and the travel were one statement, where they read as two things happening to agree. The label's colour waits one beat and the mark's does not, because the mark is standing where the fill starts.

CSSCode in FramerBold

92Changes sides

The mark starts left of the label and finishes right of it, crossing rather than going around — the position card 79 declines to take. It stays lit the whole way and shrinks as it passes the letters.

CSS + JSCode in FramerBold

67Mark walk

The two pieces exchange places: the mark crosses the whole label to the far end while the plate slides into the slot it vacates. Card 92 walks a bare icon; this is one solid mass crossing another.

CSS + JSCode in FramerBold

128Buds a mark

The silhouette changes. The plate opens a slot for the mark — padding carries 28 to 48 pixels — and the disc scales up one delay later, so the room is made before anything arrives in it; at 33 pixels inside a 45 pixel plate it keeps six pixels of plate on three sides and stays contained by the button rather than bolted to its edge.

CSSCode in FramerBold

100Plus to X

A plus becomes an X without passing through a single angle: four cells step one place around the centre, 26ms apart, and the fifth is already where it needs to be. Nothing rotates; the mark is redrawn.

CSSVariant in FramerBold

93Pieces join

The mark's own plate closes the gap and the two facing corners give up their radius, so what were two objects read as one.

CSSCode in FramerBold

66Split apart

Card 93 read backwards: this one arrives joined and comes apart. The same gap and the same two corners, arguing for separation rather than for one object.

CSSVariant in FramerBold

97Grid steps

The mark crosses twelve pixels in three jumps of four and the label makes room in one, so the button is never between two positions. The exact argument section L is built to deny.

CSSCode in FramerBold

54Anticipation

The arrow winds a pixel and a half backwards before it goes — one easing whose curve dips below zero, nothing more.

CSSCode in FramerSubtle

79Optical centre

The mark's space is reserved from the start, so the label alone reads as centred until the mark arrives.

CSSVariant in FramerSubtle

Material

The button behaves like a physical thing — lit, glazed, printed, knurled or cut — and hover changes the material, not the layout.

04Bloom

The first light on this page that leaves the plate. Cards 31 and 42 both work inside the boundary; this spends its light outward, the only way to say brighter on one grayscale.

CSSVariant in FramerSubtle

05Inner light

Light gathers along the bottom edge on hover and floods the whole plate on the press, instead of the plate pushing down. Card 43 answers the press with depth; this answers it with energy, the other thing a physical control does when you close it.

CSSVariant in FramerSubtle

34Light flip

The plate is lit from the top left, and pressing it moves the light to the bottom right. Nothing travels — the four edges stay where they are. Cards 43 and 86 are also press-only, but neither moves the light.

CSSVariant in FramerSubtle

109Fixed light

A plate lit from above, with the flood passing underneath the light rather than over it — so the surface changes colour without changing material. The first study here to light the face rather than its edges.

CSSCode in FramerSubtle

10Sheen

A soft light crosses the dark surface, once per hover.

CSSVariant in FramerSubtle

31Frosted glass

The glass materialises: the blur grows in as the surface tints up and a light edge catches along the top.

CSSVariant in FramerSubtle

36Sprite swap

Rest, hover and press are three flat sprite frames and the swap between them is the whole effect — plate, type and stair changing in one paint. The only study with no transition, and the argument against this page's second rule.

CSSCode in FramerBold

104Bevel flip

Two light sources, four edges, and the pair swapping the instant you press. No hover state at all and no transition anywhere — and it still reports what it is doing faster than anything else on this page.

CSSVariant in FramerSubtle

State

These answer the click rather than the pointer: the button takes an instruction and reports on it in place, with no spinner and no second surface.

72Status button

The button takes the instruction and reports on it in place, with no spinner. Every state change is the same move — one row of the label rolling upward, the check riding the row it belongs to — and the plate takes the impact as the bar hits the end. Card 83 is the other loop you start by acting, but that one is bound to a hover; this one ends when the work does.

CSS + JSCode in FramerBold

73Plate to check

The plate closes to a disc the height of the button and the check draws itself inside it. Card 80 stays a button the whole way; this one spends the plate, so the button becomes the confirmation.

CSS + JSCode in FramerBold

74Hold to confirm

Press and hold; let go early and nothing happens. Cards 86 and 43 answer the instant of contact — this is the only study that makes the duration of the press the input, putting the friction in the gesture.

CSS + JSCode in FramerBold

83Working state

The mark turns a quarter and a dashed ring runs around it. A loop that is already running when you arrive gives up the moment you point at it; this is the loop that starts because you pointed.

CSSCode in FramerBold

Row

These need siblings to be read. Hovering one changes the others, so the row is the unit and a single button shows nothing.

60Others recede

Nothing is added to the item you are pointing at — the rest of the row simply stops competing with it.

CSSCode in FramerSubtle

62Conserved compression

The item you point at takes twenty-four pixels and its two neighbours give up twelve each, so the row's width is unchanged by construction rather than by rounding.

CSSCode in FramerSubtle

63Repulsion

The neighbours step away from the item you point at, five pixels for the ones beside it and two for the ones beyond, and the item itself holds still.

CSSCode in FramerSubtle

151Weight budget

The row is allowed sixteen hundred units of weight and no more, so the item you point at can only reach 650 by the other three dropping to 317 each. The cells are fixed, which is what keeps the conservation honest: the debt is settled in ink and the layout never learns about it.

CSSCode in FramerSubtle

152Radius budget

Forty-eight pixels of corner, shared four ways. The one you point at rounds to twenty-four — half its height, where the plate becomes a true pill and past which nothing further happens — and the other three square off to eight.

CSSCode in FramerSubtle

153Gap budget

Card 62 moved the items and left the gaps alone. This moves only the gaps: the two flanking the one you point at open, the rest close, and because every item is a flex track inside a fixed-width row the outer edges cannot move to pay for it.

CSSCode in FramerSubtle

154Lever

The row is one rigid body pinned at its middle. Point left of centre and the whole row tips left, by an angle taken from how far off centre you are — the ends travel most, the pivot not at all, and nothing is added to any button.

CSSCode in FramerSubtle

155Elevation trade

There is one raise in the row and only one button may hold it. Taking it presses the other three into the card, so the lift is paid for locally rather than added on top — four buttons lifting at once would be four objects, and this stays one surface with a dent in it.

CSSCode in FramerBold

156Depth of field

The row has a focal plane and the item you point at is on it. Every other edge takes blur by how far it sits from you, so the row reads as one photograph refocusing. The words stay sharp on purpose: a blurred glyph cannot hold its contrast, and there is no blur small enough to both pass and be seen.

CSSCode in FramerSubtle

157Fan

Every button rotates about the same origin, eleven heights below the row, so the angles splay instead of each one spinning in place. Sign comes from which side of you a button sits on and magnitude from how far — a hand of cards opening away from your thumb.

CSSCode in FramerBold

158Stiff beam

The inverse of every other falloff here: the row is clamped at both ends, so each button’s deflection is its own compliance times its proximity to you. Point at the middle and the row gives; point at an end and almost nothing happens, because that end is held.

CSSCode in FramerSubtle

161Icon to label

Four squares at rest, and the one you point at grows to say what it is. The growth is paid for out of the row’s trailing space rather than out of its neighbours, which is the honest version — a real toolbar has that space, and pretending the neighbours shrink would be card 62 wearing a different hat.

CSSCode in FramerSubtle

162Fanned deck

At rest the buttons overlap by twenty pixels — as far as the plate’s own padding allows before a label slides under its neighbour — stacked front-to-back, so the row reads as a held deck and only the first label is fully clear. Entering the row anywhere spreads the whole deck; only then does the one you are on come forward. The deck needs about four hundred and ninety pixels of card to open into — four plates side by side are wider than a narrow card, so below that the spread is held and only the lift runs.

CSSCode in FramerBold

159One plate for the row

Card 61 slides a rule under the row; this slides the plate. There is exactly one filled surface, the four buttons are outlines with text in them, and the plate takes each target’s width and its radius on the way — so the shared object changes shape to become the thing it is standing in for.

CSSCode in FramerBold

160Shared caret

One caret above the row slides to whatever you point at, and it leans back the way it came — travelling right it tips left for the length of the journey, then rights itself on arrival. So the row says not only where you are but which direction you got there from.

CSS + JSCode in FramerSubtle

61Travelling rule

One rule serves the whole row and slides to whichever item you point at, taking that item’s own width as it goes rather than a fixed quarter of the row, and parking back on the current one when you leave.

CSSCode in FramerSubtle

65Divider yields

The two hairlines touching the segment you point at stand down, so it reads as lifted out of the row rather than tinted inside it.

CSSCode in FramerSubtle

64Emphasis trade

Emphasis is a fixed quantity, so the secondary can only take it by the primary giving it up — point at the outline and the two trade places.

CSSCode in FramerBold

132One light for the row

One source lights the whole row, so a button you are not pointing at is still lit if its neighbour is. Give every button its own lamp and the row reads as four separate objects; here the four share a coordinate space, and what changes between them is only how far each one sits from the light.

CSS + JSCode in FramerSubtle

134Handover

Card 75 reads the edge one button was crossed at; this reads the edge between two of them. Sweep the row and each fill enters from the side you arrived on while the one you left drains toward the side you are heading for, so four buttons answer as one continuous movement rather than four separate ones. Sweep back and the whole row reverses with you.

CSS + JSCode in FramerBold

133The row that doesn’t fit

The other six rows on this page assume every item is on screen. This one is wider than what holds it, which is what a filter row actually looks like on a phone: the end of it goes under a mask, and pointing at the last stretch of track advances the row by exactly one item. The mask is a mask and not a gradient painted in the card colour, so the row keeps working on any ground you drop it on.

CSS + JSCode in FramerSubtle