Sizing
Sizing sets the height of a control, the size of each small part, and the minimum hit area.
Control Heights
A control has one of four heights, set by its size prop. By default, it is 32px.
| Size | Height | Purpose |
|---|---|---|
xs | 24px | Inside a Table row or another control |
sm | 28px | A dense toolbar with no Input |
default | 32px | Everywhere else |
lg | 36px | The one main action of a sparse surface |
Some controls don’t have every size.
| Control | Sizes |
|---|---|
| Button | xs, sm, default, lg |
| Toggle, Toggle Group, Segmented Control | sm, default, lg |
| Select, Native Select | sm, default |
| Input, Input Group | None; both are 32px. |
Fixed Sizes
These parts have one size or a short set of their own.
An Avatar has three sizes.
| Size | Width and Height | Placement |
|---|---|---|
sm | 24px | A Table row, a menu, or a field |
default | 32px | The Sidebar and a comment |
lg | 40px | Next to a page title |
Rows
A Table row has no fixed height. A row of text is 36px, and a row with a Badge is 40px.
| Invoice | Amount |
|---|
| INV-2026-014 | $4,200.00 |
| Row | Height |
|---|---|
| Table head | 40px |
| Table row | 36px and a 1px line |
| Item of a Dropdown Menu, a Context Menu, a Menubar, a Select, a Combobox, or a Command list | 32px |
| Sidebar menu button | 32px, or 28px at sm and 48px at lg |
Tabs list, and a Segmented Control at default | 32px |
Hit Targets
A control that is drawn smaller than 24px has a larger hit area. An after: pseudo-element extends past the control’s edge, and the dashed line in the specimen shows where it ends.
Rules
The components already follow the first rule. Apply the others to a row, a form, or a list that the product lays out.
Minimum Target
Make a control 24px or larger, or extend its hit area to 24px with after:absolute after:-inset-*. A Checkbox, a radio, a Switch, and a Slider thumb already have the extension, so keep it when you override their classes. Add space around an extended control: when two hit areas overlap, users who click near one control can activate the other.
Controls in a Row
An Input is 32px and has no other size, so use default for every control in a row that has one. A row of Buttons alone can use sm.
sm Buttons are next to an Input, they are 28px tall next to its 32px, so the row has two top edges and two bottom edges.Largest Size
Use no size above lg in a product. A product screen has no touch size. Its tallest control is lg, at 36px. The marketing site’s call to action and the Input next to it are the exception: they are 48px, set with h-12 where they are used.
Widths
A Button and a Badge are as wide as their content. An Input, a Textarea, and an Input Group are w-full, so they fill the width of their container. Set the width on the column. A Select and a Native Select are the exception: a Select is as wide as its value, and a Native Select is as wide as its longest option, unless you add w-full.
Stacked Options
Stack Checkboxes and radios 12px apart. RadioGroup sets gap-3. Use the same gap for a stack of Checkboxes. At 8px, each option keeps less than the 24px floor clear of its neighbors.
Accessibility
See Accessibility for the floor for a pointer target.
In Code
Set a control’s height with its size prop, not with an h-* class. The button in this example is drawn at 20px and has a hit area of 24px.
<button aria-label="Remove" className="relative size-5 after:absolute after:-inset-0.5">
<XIcon />
</button>