Organic Button Set
Four real 43 px tall buttons cut as superellipses of exponent 3, 4 and 5, then as an 8 px bevel (four clip-path: polygon()), from roundest to sharpest: a button set that ranks by shape as much as by color, with no SVG and no JavaScript.
Updated
This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Glassmorphism has 47 effects, including 6 free. Explore the category →
3 usage examples



How it works
Four <button class="organic-btn"> (14 × 28 px padding, 12.8 px text at weight 700, no border): 43 px tall and 105 to 127 px wide depending on the label (measured). Each variant calls its variable: --obt-squircle-soft (n = 3), --obt-squircle (n = 4) and --obt-squircle-tight (n = 5) are superellipses of 64 points in percentages drawn over the whole box; --obt-bevel-sm is an 8 px bevel in pixels (eight points in calc()). The higher the exponent, the tighter the sides: the shape removes 11.7%, 7.3% then 5% of the box (computed; measured in Chromium 151: 10.4, 6.9 and 5.3%), the bevel 2.8%. On a button three times wider than tall, the superellipse stretches: n = 3 reads almost like an ellipse, n = 5 like a pill with straight flanks.
Colors: violet #8b5cf6 → #a78bfa (n = 3), pink #ec4899 → #f472b6 (n = 4), cyan #06b6d4 → #22d3ee (n = 5), white text; amber #f59e0b → #fbbf24 for the bevel, #1a1a2e text. On hover: 3 px lift, scale(1.04), brightness(1.15) over 0.4 s with a bounce; on press: translateY(1px) scale(0.97). The transition also lists clip-path 0.5s: nothing changes shape in the sold code, but if you move a button from one variable to another (selected state), the change animates, since the three superellipses have 64 points in the same order.
The four shapes are CSS variables (--obt-squircle-soft, --obt-squircle, --obt-squircle-tight, --obt-bevel-sm), with no SVG and no id. An effect that rests entirely on the difference in shape cannot depend on <clipPath>s supplied separately: missing from the page, they would leave four identical rectangles, clickable corners included. Measured in Chromium 151, Firefox 153 and WebKit 26: the cut applies, and the corner does not get the click.
Accessibility
- The focus ring is clipped:
clip-pathcuts everything outside the shape, outline included. Measured with the keyboard: in Firefox 153, not one pixel changes when the button gets focus; in Chromium 151, only two strokes remain on the flanks (169 pixels out of 6,490). Add an inner indicator:.organic-btn:focus-visible { filter: brightness(1.25); box-shadow: inset 0 0 0 3px #fff }— the inset shadow stays inside the shape. - Contrast of the white 12.8 px text (4.5:1 threshold): 4.2:1 on the violet start, 3.5:1 on pink, 2.4:1 on cyan, and 1.8:1 on the cyan end
#22d3ee. Only the amber bevel (dark text, 7.9:1) passes. The scenes on this page darken all four gradients. - Shape and meaning: curvature can suggest a scale (easy → expert), but a screen reader does not perceive it. The label must state the level. These are real
<button>s: Tab reaches them (measured), Enter and Space activate them natively. For an exclusive choice, addaria-pressedor switch to styled radio buttons. Noprefers-reduced-motion: the 3 px lift stays active under the preference (measured).
Browser compatibility
CSS only: clip-path: polygon() in percentages and calc(), custom properties, gradients, filter: brightness(), transform. Zero JavaScript, zero SVG. Shapes measured identical in Chromium 151, Firefox 153 and WebKit 26.
Without clip-path (Firefox before 54, Safari before 13.1 without prefix), the four buttons turn back into rectangles: they work, but the ranking by shape disappears — so always keep a difference in color or label.
The code
HTML structure to paste into your page (the CSS + JS come with Premium):
<div class="demo-preview">
<div class="organic-btns-wrap">
<button class="organic-btn organic-btn--soft">…</button>
<button class="organic-btn organic-btn--standard">…</button>
<button class="organic-btn organic-btn--tight">…</button>
<button class="organic-btn organic-btn--bevel">…</button>
</div>
</div>
The full HTML + CSS + JS of Organic Button Set, ready to paste — plus all 840 effects. Or $299 once, lifetime access.
Customize
Options passed to the API or data-* attributes:
| Option / property | Default | Effect |
|---|---|---|
Exponents (CSS — --obt-squircle-soft, --obt-squircle, --obt-squircle-tight) |
n = 3, 4, 5 (64 points each) | For another exponent, recompute the 64 points: x = 50 + 50·sign(cos t)·|cos t|^(2/n), y = 50 + 50·sign(sin t)·|sin t|^(2/n), for t = 180° + i × 5.625°. n = 2 gives an ellipse, n = 8 a rectangle with barely softened corners. |
Bevel (CSS — --obt-bevel-sm) |
8 px at each corner | Replace the eight 8px; beyond 12 px on a 43 px button, the bevel bites into the text; beyond 21 px (half the height), the sides disappear and it becomes a hexagon. |
Colors (CSS — .organic-btn--soft, --standard, --tight, --bevel) |
violet, pink, cyan, amber | Start from a dark color to keep white text above 4.5:1 (see accessibility). |
Size (CSS — padding of .organic-btn) |
14 × 28 px, 43 px tall | The superellipses follow the box. The wider the button relative to its height, the longer the corners: for fixed-size corners, use one superellipse per corner in calc(), like the bevel. |
Hover and press (CSS — :hover, :active) |
−3 px and ×1.04 on hover, +1 px and ×0.97 on press | For a selected state, add .organic-btn[aria-pressed="true"] { clip-path: var(--obt-squircle-tight) }: the 0.5 s transition already in place animates the change. |
FAQ
clip-path cuts everything outside the shape, including the outline drawn around the button. Measured: no pixel difference in Firefox, two thin strokes on the flanks in Chromium. The fix is an indicator inside the shape: box-shadow: inset 0 0 0 3px #fff and a brightness change on :focus-visible.--obt-squircle-soft (n = 3) for the main action, the roundest and “friendliest”, and give secondary actions a tighter curve (n = 4 or 5), more discreet. The bevel, the only shape with sharp angles, reads as an exception: keep it for a separate action (delete, expert, special delivery), as in the scenes. On a single isolated button, n = 4 and n = 5 are hard to tell apart (see the first question): ranking by shape works in a series, backed by color or size.