# Key

Every button, and every link that acts like one: a cap on a skirt that drops below the plate when pressed.

Kit part · Free · https://tactileui.dev/parts/key

- Element: `<button> · <a>`
- Needs: `kit.css` only, no script ([how to install the kit](https://tactileui.dev/docs/installation#the-kit))
- Categories: Buttons
- Finishes: Aluminium, Graphite, Oak, Walnut, Porcelain, Black, Daylight, Night, Paper, Phosphor, E-paper, AMOLED
- Volumes: Tactile, Quiet

## Variants

### Contrast · the one action

```html
<button class="tui-key tui-key--primary">Start recording</button>
```

### Plain

```html
<button class="tui-key">Save preset</button>
```

### Flat · printed text that acts

```html
<button class="tui-key tui-key--flat">Cancel</button>
```

### Danger · confirm in a dialog

```html
<button class="tui-key tui-key--danger">Erase reel</button>
```

### Sizes · sm 28 · 36 · lg 46

```html
<div style="display:flex;gap:10px;align-items:center"><button class="tui-key tui-key--sm">Edit</button><button class="tui-key">Edit</button><button class="tui-key tui-key--lg">Edit</button></div>
```

### With a lamp in the cap

```html
<button class="tui-key" aria-pressed="true" data-latch><span class="tui-lamp" data-on></span>Monitor</button>
```

### A link

```html
<a class="tui-key" href="#variants">Read the manual</a>
```

## Every state

- Rest
- Hover
- Pressed
- Latched
- Focus
- Disabled

Hover, pressed and focus are forced with `.is-hover`, `.is-down` and `.is-focus`; checked and disabled are real.

## API

| Name | Kind | Values | What it does |
| - | - | - | - |
| .tui-key | class | — | A plain key: a raised cap on a 2px skirt, 36px tall. |
| .tui-key--primary | class | — | The contrast cap: the one action on a surface that matters most. |
| .tui-key--flat | class | — | No cap at all: printed text that acts. For backing out. |
| .tui-key--danger | class | — | Red printing on a plain cap, for destructive actions. |
| .tui-key--sm · --lg | class | 28px · 46px | Small in tables and panel heads; large in heroes. Skirts scale with the cap: 1.5px, 3px. |
| .tui-key--icon · --round | class | — | Keys with an icon and no words: see the icon key. |
| aria-pressed | attribute | "true" · "false" | A latching key. “true” holds it down below the plate. |
| disabled · aria-disabled | attribute | — | 45% opacity and no travel. Use aria-disabled="true" on links. |
| data-tip | attribute | text | A one-line name shown on hover and focus. Required on icon keys, with an aria-label. |
| data-material | attribute | aluminium · graphite · porcelain · black-anodised · titanium · bakelite · anodised-blue · anodised-green | What the cap, its skirt and its printing are made of, apart from the page’s finish; the contrast key takes the material’s own. On the key or on the device around it. Anodised blue and green go on a whole device only. |
| --h · --skirt | CSS property | 36px · 2px | Cap height and skirt depth. The size modifiers set both. |
| .is-hover · .is-down · .is-focus | class | — | Forced states, for documentation and specimens only. |
| Enter · Space | keyboard | — | Native button behaviour. The key presses on :active, so it drops under a finger, a mouse or a key. |

## Markup

```html
<button class="tui-key tui-key--primary">Start recording</button>
<button class="tui-key">Save preset</button>
<button class="tui-key" aria-pressed="false">
  <span class="tui-lamp" data-on></span>Monitor
</button>
<button class="tui-key tui-key--flat">Cancel</button>
```

The demo on the page:

```html
<div style="display:flex;flex-wrap:wrap;gap:14px;align-items:center;justify-content:center">
  <button class="tui-key tui-key--primary tui-key--lg" data-toast="Recording to reel 4." data-lamp="red">Start recording</button>
  <button class="tui-key tui-key--lg" data-toast="Preset saved to Studio A.">Save preset</button>
  <button class="tui-key tui-key--lg" aria-pressed="false" data-latch><span class="tui-lamp" data-on></span>Monitor</button>
  <button class="tui-key tui-key--flat">Cancel</button>
</div>
```

## Usage notes

Hold a key down: it drops by its skirt and the plate shades its top. Monitor latches.

## Accessibility

- Use a real `<button>`, or an `<a>` for navigation. Both are reached with Tab and keep the 2px focus ring, 3px away.
- Icon keys need an `aria-label`; with `kit.mjs` the `data-tip` becomes a real tooltip, read after the name, so keep the two close in meaning.
- A latching key announces its state through `aria-pressed`. The lamp in its cap is a second signal, never the only one.
- The contrast cap holds 13:1 or better against its printing in aluminium and graphite.

## How it’s built

Two backgrounds and a stack of box-shadows, no images. The cap is a linear gradient of `--tui-face-hi` under a radial highlight from above; the skirt is a hard 2px shadow in `--tui-skirt`, with a contact shadow and a soft one below it. Pressing moves the cap down by exactly the skirt and swaps the shadows for `--tui-pressed`: the plate’s edge now shades the cap’s top and sides. 70ms, one easing curve.

## Rules

One contrast key per surface. The label says what happens: “Erase reel”, not “Submit”.

The full rules are in `key.rules.md` in the brain, which ships with the Kit.

## Related parts

- [Icon key](https://tactileui.dev/parts/icon-key): A key with an icon and no words, square or round: transport, power, the small tools. Its aria-label names it; a tip shows the name.
- [Selector](https://tactileui.dev/parts/selector): One mode of two to five: latching keys in a tray, one down at a time, each with a lamp that lights when chosen.
- [Dialog](https://tactileui.dev/parts/dialog): A decision that must be made now: a native dialog with a question, one sentence of consequence, a way back and the act.
