# CSS Tab Shape - Skill Reference > Tab shapes with concave "feet" or a slanted folder edge, cut with CSS only: `clip-path: shape()` or a `mask` of radial gradients, driven by one `--r` radius variable. No script runs after mount. ## What this teaches - `clip-path: shape()` with `arc`, `vline`, `hline`, `curve` and `line` commands, every number tied to one `--r` custom property - The folder tab: a slanted right edge drawn with a `curve` + `line` + `curve` sequence, so the tab leans into its neighbour - Inward (concave) corners at the tab's feet with `arc ... of` without `cw`, so the shape hugs the strip it sits on - CSS `mask` with three layers (`padding-box` fill + two radial-gradient corner cut-outs) to carve a border away - Overlapping tabs with a negative `margin-left` on `.tab + .tab` (folder stack) - Per-tab fills through custom properties (`--tab-bg`, `--tab-color`), so any CSS background, gradients included, works ## Core concept A tab is a rectangle with its top corners rounded and its bottom corners flared outward. A flare cannot be made with `border-radius`, so the shape is cut after layout: either by tracing the outline with `clip-path: shape()`, or by growing a border the size of the radius and masking it away. Both leave the box model alone (padding and size stay what you set) except the mask, whose border adds `--r` on each side. Because every coordinate is a `calc()` of `--r`, one slider scales the whole shape. ## Use it ### Embed (no build step) ```html
Tab 1
Lorem ipsum
Dolor sit amet
``` - Every key of `defaults` is a kebab-case `data-*` attribute: `data-technique`, `data-radius`, `data-padding-x`, `data-padding-y`, `data-gap`, `data-overlap`, `data-tab-color`, `data-active-color`, `data-text-color`, `data-track-color`, `data-bg-color`, `data-hover-highlight`. - Values convert by the type of the default: numbers via `Number`, booleans are `false` only for `"false"` or `"0"`, everything else stays a string. - Tabs come from child `[data-tab]` elements, not from an attribute. Without any, three tabs "Tab 1", "Tab 2", "Tab 3" show. The children are replaced on mount and put back on `dispose()`. - `data-background` accepts any CSS `background` value; `data-color` sets that tab's text colour. ### Bundled apps ```ts import { mount, defaults } from "@vanilla-motion/css-tab-shape"; // the effect workspace package const container = document.querySelector("#tabs")!; // give it a height; tabs are centred in it // options = any params (below) plus tabs: { label, background?, color? }[] const fx = mount(container, { technique: "clip-path", radius: 12, hoverHighlight: true, tabs: [{ label: "Tab 1" }, { label: "Tab 2", background: "linear-gradient(#60A5FA, #22C55E)", color: "#fff" }], }); fx.setParams({ radius: 20, tabColor: "#FACC15" }); // partial update, rewrites CSS custom properties only fx.dispose(); // removes the markup, restores the container's original children ``` `mount` returns a `CssTabShapeHandle` with exactly `setParams(next: Partial)` and `dispose()`. The tabs cannot change through `setParams`; call `dispose()` and `mount()` again. The `