Controls

Controls, by kind

Each kind of control is documented once: its classes, then every variant with its disabled look. Under each example is the markup, with a button that copies it.

Buttons

Every button is a real button element with a dish, a case and a disabled look that sinks into its surface. Pick the family that matches the surface it sits on, then add a shape or a color.

ClassWhat it does
fam-plasticRaised plastic button. Add a color: fam-plastic--red, fam-plastic--green, fam-plastic--amber, fam-plastic--blue, fam-plastic--purple or fam-plastic--cream.
fam-plastic--roundAn icon button with a round dish. fam-plastic--square is the same with a square case.
fam-metal-buttonButton in the metal of fam-metal. fam-metal-button--round and fam-metal-button--square are its icon shapes.
fam-metal-button--brushedSwaps the metal for the coarser brushed metal of fam-metal-brushed.
fam-wood-buttonButton in light wood with dark ink. fam-wood-button--round and fam-wood-button--square are its icon shapes.
fam-wood-button--paneledSwaps the light wood for the dark planks of fam-wood-paneled, with light ink.
fam-leather-buttonTan leather button. It fills the width of its container, so put it in a box of the width you want.
fam-glossy-buttonThe aqua pill. fam-glossy-button--silver is the silver one, and fam-gloss-soft and fam-gloss-strong dial its sheen.
fam-glass-buttonThe frosted pill. Use it with fam-glass, and add fam-glass--light or fam-glass--blue to tint it. It reads best on a dark surface.
fam-button-groupPuts buttons in one case. Mark the lit one with aria-pressed="true". fam-button-group--case is a raised case, fam-button-group--leather a leather one and fam-button-group--wood a wooden one.

Plastic

Raised plastic buttons in five colors, with round and square ones that have a dish. They sit best on metal, and a disabled button sinks into its case like one that has not popped up yet.

HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <button class="fam-plastic fam-plastic--red fam-shadow-md" type="button">Record</button>
  <button class="fam-plastic fam-plastic--green fam-shadow-md" type="button">Play</button>
  <button class="fam-plastic fam-plastic--amber fam-shadow-md" type="button">Pause</button>
  <button class="fam-plastic fam-plastic--blue fam-shadow-md" type="button">Share</button>
  <button class="fam-plastic fam-plastic--purple fam-plastic--round fam-shadow-md" type="button" aria-label="Info">i</button>
  <button class="fam-plastic fam-plastic--blue fam-plastic--square fam-shadow-md" type="button" aria-label="Eject">E</button>
  <button class="fam-plastic fam-plastic--blue" type="button" disabled>Disabled</button>
  <button class="fam-plastic fam-plastic--red fam-plastic--square" type="button" aria-label="Eject, disabled" disabled>E</button>
  <button class="fam-plastic fam-plastic--purple fam-plastic--round" type="button" aria-label="Info, disabled" disabled>i</button>
</div>

Metal

Metal buttons are made the same way from metal.

HTML
<div class="fam-metal" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <button class="fam-metal-button fam-shadow-md" type="button">Eject</button>
  <button class="fam-metal-button fam-metal-button--round fam-shadow-md" type="button" aria-label="Info">i</button>
  <button class="fam-metal-button fam-metal-button--square fam-shadow-md" type="button" aria-label="Eject">E</button>
  <button class="fam-metal-button" type="button" disabled>Disabled</button>
  <button class="fam-metal-button fam-metal-button--round" type="button" aria-label="Info, disabled" disabled>i</button>
</div>

Brushed metal

Brushed metal buttons are the same buttons on a coarser, brushed metal: add fam-metal-button--brushed.

HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <button class="fam-metal-button fam-metal-button--brushed fam-shadow-md" type="button">Eject</button>
  <button class="fam-metal-button fam-metal-button--brushed fam-metal-button--round fam-shadow-md" type="button" aria-label="Info">i</button>
  <button class="fam-metal-button fam-metal-button--brushed fam-metal-button--square fam-shadow-md" type="button" aria-label="Eject">E</button>
  <button class="fam-metal-button fam-metal-button--brushed" type="button" disabled>Disabled</button>
</div>

Wood

Wooden buttons are the same buttons in the wood of the navigation bar. They suit wood, and the paneled ones are the dark planks with light ink.

HTML
<div class="fam-wood" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <button class="fam-wood-button fam-shadow-md" type="button">Open</button>
  <button class="fam-wood-button fam-wood-button--round fam-shadow-md" type="button" aria-label="Info">i</button>
  <button class="fam-wood-button fam-wood-button--square fam-shadow-md" type="button" aria-label="Eject">E</button>
  <button class="fam-wood-button fam-wood-button--paneled fam-shadow-md" type="button">Open</button>
  <button class="fam-wood-button fam-wood-button--paneled fam-wood-button--round fam-shadow-md" type="button" aria-label="Info">i</button>
  <button class="fam-wood-button fam-wood-button--paneled fam-wood-button--square fam-shadow-md" type="button" aria-label="Eject">E</button>
  <button class="fam-wood-button" type="button" disabled>Disabled</button>
  <button class="fam-wood-button fam-wood-button--paneled" type="button" disabled>Disabled</button>
</div>

Leather

HTML
<div class="fam-leather" style="padding: 20px">
  <button class="fam-leather-button" type="button">Save</button>
  <button class="fam-leather-button" type="button" disabled>Disabled</button>
</div>

Glossy

Glossy buttons are the aqua pill on a button, in blue and silver, and fam-gloss-soft or fam-gloss-strong dial the sheen.

HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <button class="fam-glossy-button" type="button">Save</button>
  <button class="fam-glossy-button fam-glossy-button--silver" type="button">Cancel</button>
  <button class="fam-glossy-button fam-gloss-strong" type="button">Strong gloss</button>
  <button class="fam-glossy-button" type="button" disabled>Disabled</button>
</div>

Glass

Glass buttons are the frosted pill on a button and read best on a dark surface.

HTML
<div class="fam-felt" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <button class="fam-glass fam-glass-button" type="button">Share</button>
  <button class="fam-glass fam-glass--light fam-glass-button" type="button">Send</button>
  <button class="fam-glass fam-glass--blue fam-glass-button" type="button">Save</button>
  <button class="fam-glass fam-glass-button" type="button" disabled>Disabled</button>
</div>

Button groups

Buttons can share one case. Wrap them in a group, and mark the lit one with aria-pressed="true". A lit square plastic button shows its LED in the dish, and the others show the dark lens. Labeled buttons show a small lens above the label, dark until they are lit. The LED fades in and out. A leather group (fam-button-group--leather) is the leather of the navigation bar, and its lit item is the same dark pocket.

HTML
<div class="fam-metal" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <div class="fam-button-group" role="group" aria-label="Playback mode">
    <button class="fam-plastic fam-plastic--square" type="button" aria-label="Mode 1" aria-pressed="false"></button>
    <button class="fam-plastic fam-plastic--square" type="button" aria-label="Mode 2" aria-pressed="true"></button>
    <button class="fam-plastic fam-plastic--square" type="button" aria-label="Mode 3" aria-pressed="false"></button>
    <button class="fam-plastic fam-plastic--square" type="button" aria-label="Mode 4" aria-pressed="false"></button>
  </div>
  <div class="fam-button-group" role="group" aria-label="View">
    <button class="fam-metal-button" type="button" aria-pressed="false">Icons</button>
    <button class="fam-metal-button" type="button" aria-pressed="true">List</button>
    <button class="fam-metal-button" type="button" aria-pressed="false">Columns</button>
  </div>
</div>
HTML
<div class="fam-felt" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <div class="fam-button-group fam-button-group--leather" role="group" aria-label="Sort by">
    <button class="fam-leather-button" type="button" aria-pressed="false">Name</button>
    <button class="fam-leather-button" type="button" aria-pressed="true">Date</button>
    <button class="fam-leather-button" type="button" aria-pressed="false">Size</button>
  </div>
</div>
HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <div class="fam-button-group" role="group" aria-label="Toolbar">
    <button class="fam-glossy-button fam-glossy-button--silver" type="button" aria-pressed="false">Back</button>
    <button class="fam-glossy-button fam-glossy-button--silver" type="button" aria-pressed="true">List</button>
    <button class="fam-glossy-button fam-glossy-button--silver" type="button" aria-pressed="false">Forward</button>
  </div>
  <div class="fam-button-group" role="group" aria-label="Transport">
    <button class="fam-glossy-button" type="button">Previous</button>
    <button class="fam-glossy-button" type="button" aria-pressed="true">Play</button>
    <button class="fam-glossy-button" type="button">Next</button>
  </div>
</div>

Radio buttons

Real radio inputs, so arrow keys and forms work with no JavaScript. Plastic and metal radios are LEDs that are dark when unchecked and glow when checked, and a disabled one sinks into its case. Glossy and glass radios show a plain dot.

ClassWhat it does
fam-radioA label that wraps a real radio input and a fam-radio-dot. Arrow keys and forms work with no JavaScript.
fam-radio--plasticAn LED that is dark when unchecked and glows when checked. fam-radio--metal is the same on metal.
fam-radio--glossyA plain dot for the glossy pill. fam-radio--glass is the plain dot for glass, and the checked one turns blue.
HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 8px 24px; align-items: center; padding: 28px">
  <label class="fam-radio fam-radio--plastic"><input type="radio" name="plastic-mode" checked><span class="fam-radio-dot"></span>Record</label>
  <label class="fam-radio fam-radio--plastic"><input type="radio" name="plastic-mode"><span class="fam-radio-dot"></span>Play</label>
  <label class="fam-radio fam-radio--plastic"><input type="radio" name="plastic-mode" disabled><span class="fam-radio-dot"></span>Locked</label>
  <label class="fam-radio fam-radio--metal"><input type="radio" name="metal-mode" checked><span class="fam-radio-dot"></span>Record</label>
  <label class="fam-radio fam-radio--metal"><input type="radio" name="metal-mode"><span class="fam-radio-dot"></span>Play</label>
  <label class="fam-radio fam-radio--metal"><input type="radio" name="metal-mode" disabled><span class="fam-radio-dot"></span>Locked</label>
  <label class="fam-radio fam-radio--glossy"><input type="radio" name="glossy-mode" checked><span class="fam-radio-dot"></span>Record</label>
  <label class="fam-radio fam-radio--glossy"><input type="radio" name="glossy-mode"><span class="fam-radio-dot"></span>Play</label>
  <label class="fam-radio fam-radio--glossy"><input type="radio" name="glossy-mode" disabled><span class="fam-radio-dot"></span>Locked</label>
</div>
HTML
<div class="fam-felt" style="display: flex; flex-wrap: wrap; gap: 8px 24px; align-items: center; padding: 28px">
  <label class="fam-radio fam-radio--glass"><input type="radio" name="glass-mode" checked><span class="fam-radio-dot"></span>Record</label>
  <label class="fam-radio fam-radio--glass"><input type="radio" name="glass-mode"><span class="fam-radio-dot"></span>Play</label>
  <label class="fam-radio fam-radio--glass"><input type="radio" name="glass-mode" disabled><span class="fam-radio-dot"></span>Locked</label>
</div>

Tabs

A tab strip is a button group with role="tablist", and each tab is a button with role="tab" and aria-selected. Silver glossy tabs follow the Snow Leopard strip, and plastic, metal, wood and leather tabs suit their materials. The wood and leather strips are the navigation bar's wood and leather. Arrow keys need a few lines of script, and tabs.js in the showcase folder is the one used here.

ClassWhat it does
fam-button-groupThe tab strip. Give it role="tablist" and each button role="tab" with aria-selected.
fam-glossy-button--silverSilver glossy tabs follow the Snow Leopard strip.
fam-button-group--caseA padded plastic case. Fill it with fam-plastic--cream buttons.
fam-button-group--woodThe wooden navigation bar's wood. Put fam-wood on the group and fam-nav-item on each tab.
fam-button-group--leatherThe leather navigation bar's leather, with fam-leather-button tabs.
Tab panel
View panel
Locked panel
HTML
<div class="fam-paper" style="padding: 28px">
  <div class="tab-demo">
  <div class="fam-button-group" role="tablist" aria-label="Silver tabs" data-tabs>
    <button class="fam-glossy-button fam-glossy-button--silver" type="button" role="tab" id="silver-tab-0" aria-selected="true" aria-controls="silver-panel-0">Tab</button>
    <button class="fam-glossy-button fam-glossy-button--silver" type="button" role="tab" id="silver-tab-1" aria-selected="false" aria-controls="silver-panel-1">View</button>
    <button class="fam-glossy-button fam-glossy-button--silver" type="button" role="tab" id="silver-tab-2" aria-selected="false" aria-controls="silver-panel-2" disabled>Locked</button>
  </div>
  <div class="tab-panel" role="tabpanel" id="silver-panel-0" aria-labelledby="silver-tab-0">Tab panel</div>
  <div class="tab-panel" role="tabpanel" id="silver-panel-1" aria-labelledby="silver-tab-1">View panel</div>
  <div class="tab-panel" role="tabpanel" id="silver-panel-2" aria-labelledby="silver-tab-2">Locked panel</div>
  </div>
</div>
General panel
Sound panel
Display panel
HTML
<div class="fam-plastic-panel fam-round-md" style="padding: 28px">
  <div class="tab-demo">
  <div class="fam-button-group fam-button-group--case" role="tablist" aria-label="Plastic tabs" data-tabs>
    <button class="fam-plastic fam-plastic--cream" type="button" role="tab" id="plastic-tab-0" aria-selected="false" aria-controls="plastic-panel-0">General</button>
    <button class="fam-plastic fam-plastic--cream" type="button" role="tab" id="plastic-tab-1" aria-selected="true" aria-controls="plastic-panel-1">Sound</button>
    <button class="fam-plastic fam-plastic--cream" type="button" role="tab" id="plastic-tab-2" aria-selected="false" aria-controls="plastic-panel-2">Display</button>
  </div>
  <div class="tab-panel" role="tabpanel" id="plastic-panel-0" aria-labelledby="plastic-tab-0">General panel</div>
  <div class="tab-panel" role="tabpanel" id="plastic-panel-1" aria-labelledby="plastic-tab-1">Sound panel</div>
  <div class="tab-panel" role="tabpanel" id="plastic-panel-2" aria-labelledby="plastic-tab-2">Display panel</div>
  </div>
</div>
One panel
Two panel
Three panel
HTML
<div class="fam-metal" style="padding: 28px">
  <div class="tab-demo">
  <div class="fam-button-group" role="tablist" aria-label="Metal tabs" data-tabs>
    <button class="fam-metal-button" type="button" role="tab" id="metal-tab-0" aria-selected="true" aria-controls="metal-panel-0">One</button>
    <button class="fam-metal-button" type="button" role="tab" id="metal-tab-1" aria-selected="false" aria-controls="metal-panel-1">Two</button>
    <button class="fam-metal-button" type="button" role="tab" id="metal-tab-2" aria-selected="false" aria-controls="metal-panel-2">Three</button>
  </div>
  <div class="tab-panel" role="tabpanel" id="metal-panel-0" aria-labelledby="metal-tab-0">One panel</div>
  <div class="tab-panel" role="tabpanel" id="metal-panel-1" aria-labelledby="metal-tab-1">Two panel</div>
  <div class="tab-panel" role="tabpanel" id="metal-panel-2" aria-labelledby="metal-tab-2">Three panel</div>
  </div>
</div>
Library panel
Shelf panel
Archive panel
Name panel
Date panel
Size panel
HTML
<div class="fam-felt" style="padding: 28px">
  <div class="tab-demo">
  <div class="fam-wood fam-button-group fam-button-group--wood" role="tablist" aria-label="Wood tabs" data-tabs>
    <button class="fam-nav-item" type="button" role="tab" id="wood-tab-0" aria-selected="true" aria-controls="wood-panel-0">Library</button>
    <button class="fam-nav-item" type="button" role="tab" id="wood-tab-1" aria-selected="false" aria-controls="wood-panel-1">Shelf</button>
    <button class="fam-nav-item" type="button" role="tab" id="wood-tab-2" aria-selected="false" aria-controls="wood-panel-2">Archive</button>
  </div>
  <div class="tab-panel" role="tabpanel" id="wood-panel-0" aria-labelledby="wood-tab-0">Library panel</div>
  <div class="tab-panel" role="tabpanel" id="wood-panel-1" aria-labelledby="wood-tab-1">Shelf panel</div>
  <div class="tab-panel" role="tabpanel" id="wood-panel-2" aria-labelledby="wood-tab-2">Archive panel</div>
  </div>
  <div class="tab-demo">
  <div class="fam-button-group fam-button-group--leather" role="tablist" aria-label="Leather tabs" data-tabs>
    <button class="fam-leather-button" type="button" role="tab" id="leather-tab-0" aria-selected="false" aria-controls="leather-panel-0">Name</button>
    <button class="fam-leather-button" type="button" role="tab" id="leather-tab-1" aria-selected="true" aria-controls="leather-panel-1">Date</button>
    <button class="fam-leather-button" type="button" role="tab" id="leather-tab-2" aria-selected="false" aria-controls="leather-panel-2">Size</button>
  </div>
  <div class="tab-panel" role="tabpanel" id="leather-panel-0" aria-labelledby="leather-tab-0">Name panel</div>
  <div class="tab-panel" role="tabpanel" id="leather-panel-1" aria-labelledby="leather-tab-1">Date panel</div>
  <div class="tab-panel" role="tabpanel" id="leather-panel-2" aria-labelledby="leather-tab-2">Size panel</div>
  </div>
</div>
Notes panel
Todo panel
Done panel
HTML
<div class="fam-leather" style="padding: 28px">
  <div class="tab-demo">
  <div class="fam-button-group fam-button-group--leather" role="tablist" aria-label="Leather tabs on leather" data-tabs>
    <button class="fam-leather-button" type="button" role="tab" id="lol-tab-0" aria-selected="true" aria-controls="lol-panel-0">Notes</button>
    <button class="fam-leather-button" type="button" role="tab" id="lol-tab-1" aria-selected="false" aria-controls="lol-panel-1">Todo</button>
    <button class="fam-leather-button" type="button" role="tab" id="lol-tab-2" aria-selected="false" aria-controls="lol-panel-2">Done</button>
  </div>
  <div class="tab-panel" role="tabpanel" id="lol-panel-0" aria-labelledby="lol-tab-0">Notes panel</div>
  <div class="tab-panel" role="tabpanel" id="lol-panel-1" aria-labelledby="lol-tab-1">Todo panel</div>
  <div class="tab-panel" role="tabpanel" id="lol-panel-2" aria-labelledby="lol-tab-2">Done panel</div>
  </div>
</div>

Knobs and dials

A knob is a picture, so give it role="img" and an aria-label that says its value. --fam-knob-angle turns its tick.

ClassWhat it does
fam-knobThe metal knob, a photograph of a real one.
fam-dialThe plastic dial, drawn in CSS. It sits on fam-plastic-panel.
fam-plastic-panelA cream plastic surface to put dials, buttons and LEDs on. Use it with a fam-round-* class.

Metal knob

HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <span class="fam-knob fam-cast-lg" role="img" aria-label="Volume low" style="--fam-knob-angle: -100deg"></span>
  <span class="fam-knob fam-cast-lg" role="img" aria-label="Volume medium"></span>
  <span class="fam-knob fam-cast-lg" role="img" aria-label="Volume high" style="--fam-knob-angle: 100deg"></span>
</div>

Plastic dial

HTML
<div class="fam-plastic-panel fam-round-md" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <span class="fam-dial fam-cast-lg" role="img" aria-label="Volume low" style="--fam-knob-angle: -100deg"></span>
  <span class="fam-dial fam-cast-lg" role="img" aria-label="Volume medium"></span>
  <span class="fam-dial fam-cast-lg" role="img" aria-label="Volume high" style="--fam-knob-angle: 100deg"></span>
</div>

Switches and toggles

A switch is a checkbox, so it toggles with no JavaScript. A toggle LED is a label that wraps a checkbox: it is lit while checked, works in forms, and takes its name from its label.

ClassWhat it does
fam-switchA label that wraps a checkbox with role="switch" and a fam-switch-knob.
fam-ledA label that wraps a checkbox with role="switch" is a toggle LED. Add a color with fam-led--green, fam-led--red or fam-led--blue and a size with fam-led--large.

Switch

HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 16px; align-items: center; padding: 28px">
  <label class="fam-switch fam-shadow-md"><input type="checkbox" role="switch" aria-label="On example" checked><span class="fam-switch-knob"></span></label>
  <label class="fam-switch fam-shadow-md"><input type="checkbox" role="switch" aria-label="Off example"><span class="fam-switch-knob"></span></label>
  <label class="fam-switch"><input type="checkbox" role="switch" aria-label="Disabled example" disabled><span class="fam-switch-knob"></span></label>
</div>

Toggle LEDs

An LED that wraps a checkbox is a toggle, driven the same way as the switch: it is lit while checked, so it works without JavaScript and in forms. Give the input role="switch" and the label is its name. A disabled one sinks into its case like a disabled button.

HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: flex-start; padding: 28px">
  <label class="fam-led"><input type="checkbox" role="switch" checked><span class="fam-led-lens"></span><span class="fam-led-label">Power</span></label>
  <label class="fam-led"><input type="checkbox" role="switch"><span class="fam-led-lens"></span><span class="fam-led-label">Standby</span></label>
  <label class="fam-led fam-led--green"><input type="checkbox" role="switch" checked><span class="fam-led-lens"></span><span class="fam-led-label fam-led-label--printed">Ready</span></label>
  <label class="fam-led fam-led--red"><input type="checkbox" role="switch"><span class="fam-led-lens"></span><span class="fam-led-label fam-led-label--printed">Fault</span></label>
  <label class="fam-led fam-led--blue fam-led--large"><input type="checkbox" role="switch" checked><span class="fam-led-lens"></span><span class="fam-led-label">Link</span></label>
  <label class="fam-led fam-led--blue fam-led--large"><input type="checkbox" role="switch"><span class="fam-led-lens"></span><span class="fam-led-label fam-led-label--printed">Sync</span></label>
  <label class="fam-led fam-led--green"><input type="checkbox" role="switch" disabled><span class="fam-led-lens"></span><span class="fam-led-label">Locked</span></label>
  <label class="fam-led fam-led--red"><input type="checkbox" role="switch" checked disabled><span class="fam-led-lens"></span><span class="fam-led-label">Locked</span></label>
</div>

LEDs

Standalone indicator lamps for the plastic panel and the metal. Add fam-led--lit to light one, and fam-led--green, --red or --blue to change its color (amber is the default). fam-led--large makes it bigger. The label is engraved unless it has fam-led-label--printed, and the lens is a photo of a real lamp tinted by CSS. The lens is decorative, so say the state in fam-visually-hidden text.

ClassWhat it does
fam-ledA standalone indicator lamp with a fam-led-lens and a fam-led-label. Amber by default.
fam-led--litLights the lamp. fam-led--green, fam-led--red and fam-led--blue change its color, and fam-led--large makes it bigger.
fam-led-label--printedFlat printed ink in place of the engraved label.
fam-visually-hiddenHolds the state as text, because the lens is decorative and a color alone does not say whether it is on.
Power, on Standby, off Ready, on Idle, off Fault, on Alarm, off Link, on Sync, off
HTML
<div class="fam-plastic-panel fam-round-md" style="display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: flex-start; padding: 28px">
  <span class="fam-led fam-led--lit"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label">Power</span><span class="fam-visually-hidden">, on</span></span>
  <span class="fam-led"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label">Standby</span><span class="fam-visually-hidden">, off</span></span>
  <span class="fam-led fam-led--green fam-led--lit"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label fam-led-label--printed">Ready</span><span class="fam-visually-hidden">, on</span></span>
  <span class="fam-led fam-led--green"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label fam-led-label--printed">Idle</span><span class="fam-visually-hidden">, off</span></span>
  <span class="fam-led fam-led--red fam-led--lit"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label fam-led-label--printed">Fault</span><span class="fam-visually-hidden">, on</span></span>
  <span class="fam-led fam-led--red"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label">Alarm</span><span class="fam-visually-hidden">, off</span></span>
  <span class="fam-led fam-led--blue fam-led--large fam-led--lit"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label">Link</span><span class="fam-visually-hidden">, on</span></span>
  <span class="fam-led fam-led--blue fam-led--large"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label fam-led-label--printed">Sync</span><span class="fam-visually-hidden">, off</span></span>
</div>
Power, on Standby, off Ready, on Idle, off Fault, on Alarm, off Link, on Sync, off
HTML
<div class="fam-metal-brushed" style="display: flex; flex-wrap: wrap; gap: 8px 16px; align-items: flex-start; padding: 28px">
  <span class="fam-led fam-led--lit"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label fam-led-label--printed">Power</span><span class="fam-visually-hidden">, on</span></span>
  <span class="fam-led"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label fam-led-label--printed">Standby</span><span class="fam-visually-hidden">, off</span></span>
  <span class="fam-led fam-led--green fam-led--lit"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label">Ready</span><span class="fam-visually-hidden">, on</span></span>
  <span class="fam-led fam-led--green"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label">Idle</span><span class="fam-visually-hidden">, off</span></span>
  <span class="fam-led fam-led--red fam-led--lit"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label">Fault</span><span class="fam-visually-hidden">, on</span></span>
  <span class="fam-led fam-led--red"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label fam-led-label--printed">Alarm</span><span class="fam-visually-hidden">, off</span></span>
  <span class="fam-led fam-led--blue fam-led--large fam-led--lit"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label fam-led-label--printed">Link</span><span class="fam-visually-hidden">, on</span></span>
  <span class="fam-led fam-led--blue fam-led--large"><span class="fam-led-lens" aria-hidden="true"></span><span class="fam-led-label">Sync</span><span class="fam-visually-hidden">, off</span></span>
</div>

Progress tubes

Set the value with --fam-value and pick a fill: candy, aqua or green.

ClassWhat it does
fam-progressThe tube. Give it role="progressbar", its value in aria-valuenow and the same value in --fam-value.
fam-progress-fill--candyThe candy cane fill. fam-progress-fill--aqua and fam-progress-fill--green are the others.
HTML
<div class="fam-metal-brushed" style="display: grid; gap: 18px; padding: 28px">
  <div class="fam-progress" role="progressbar" aria-label="Candy cane progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="68" style="--fam-value: 68%">
    <div class="fam-progress-fill fam-progress-fill--candy"></div>
  </div>
  <div class="fam-progress" role="progressbar" aria-label="Blue progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="52" style="--fam-value: 52%">
    <div class="fam-progress-fill fam-progress-fill--aqua"></div>
  </div>
  <div class="fam-progress" role="progressbar" aria-label="Green progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="84" style="--fam-value: 84%">
    <div class="fam-progress-fill fam-progress-fill--green"></div>
  </div>
</div>

Fields

Frosted glass fields for dark surfaces, a recessed search pill for paper, and labeled fields cut into leather.

ClassWhat it does
fam-glassThe frosted pill. Wrap a fam-glass-input in it for a field, or use a select for a dropdown. fam-glass--light is light glass with dark text.
fam-menuAn open list for your own menus, with aria-selected="true" on the chosen item.
fam-fieldA text field cut into any material, part white so the texture shows through. Add fam-field--pill for a pill, fam-field--sm or fam-field--lg for a size, and fam-field--group to hold labeled fam-field-rows in one well. aria-invalid="true" on the input turns it red and shakes it, and fam-field-message holds the error text.

Glass field and dropdown

A frosted field and a dropdown made from the same field with a select. The open list is a plain styled list for your own menus.

  • Oak
  • Walnut
  • Cherry
HTML
<div class="fam-felt" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 320px)); gap: 18px; align-items: start; padding: 28px">
  <div class="fam-glass"><input class="fam-glass-input" placeholder="Search" aria-label="Search"></div>
  <div class="fam-glass fam-glass--light"><input class="fam-glass-input" placeholder="Light search" aria-label="Light search"></div>
  <div class="fam-glass">
    <select class="fam-glass-input" aria-label="Wood">
      <option>Walnut</option>
      <option>Oak</option>
      <option>Cherry</option>
    </select>
  </div>
  <div class="fam-glass fam-glass--light">
    <select class="fam-glass-input" aria-label="Light wood">
      <option>Walnut</option>
      <option>Oak</option>
      <option>Cherry</option>
    </select>
  </div>
  <ul class="fam-menu">
    <li>Oak</li>
    <li aria-selected="true">Walnut</li>
    <li>Cherry</li>
  </ul>
  <div class="fam-glass"><input class="fam-glass-input" placeholder="Disabled" aria-label="Disabled" disabled></div>
</div>

Text fields

A field is a well cut into whatever it sits on. The recessed fill is part white, so the wood, leather or paper shows through. Add fam-field--pill for a pill, and fam-field--sm or fam-field--lg for a size.

HTML
<div class="fam-wood" style="padding: 20px">
  <label class="fam-field"><input placeholder="Medium" aria-label="Name"></label>
  <label class="fam-field fam-field--lg"><input placeholder="Large" aria-label="Name"></label>
  <label class="fam-field fam-field--pill fam-field--sm"><input placeholder="Small pill" aria-label="Name"></label>
</div>

Search pill

A pill field with a magnifier before the input.

HTML
<div class="fam-paper" style="padding: 20px">
  <label class="fam-field fam-field--pill fam-field--sm">
    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" aria-hidden="true"><circle cx="10" cy="10" r="6.5"/><path d="M15 15l6 6"/></svg>
    <input placeholder="Search" aria-label="Search notes">
  </label>
</div>

Grouped fields

Labeled rows share one well, with a line between them.

HTML
<div class="fam-leather" style="padding: 20px">
  <div class="fam-field fam-field--group">
    <div class="fam-field-row"><label for="name">Name</label><input id="name" placeholder="Required"></div>
    <div class="fam-field-row"><label for="email">Email</label><input id="email" type="email" placeholder="Required"></div>
  </div>
</div>

Error and disabled

Set aria-invalid="true" on the input and the field turns red and shakes. Link the message with aria-describedby. Clear the attribute and set it again to shake a second time. A disabled input dims its field.

Enter a valid email address
The code has 6 digits
HTML
<div class="fam-linen" style="padding: 20px">
  <label class="fam-field">
    <input id="email" value="not-an-email" aria-label="Email" aria-invalid="true" aria-describedby="email-message">
  </label>
  <span class="fam-field-message" id="email-message">Enter a valid email address</span>
  <button class="fam-metal-button fam-metal-button--brushed" type="button" data-shake-field="email">Shake the field</button>
  <label class="fam-field"><input placeholder="Disabled" aria-label="Disabled" disabled></label>
</div>

Lists and tables

Rows are real links in a plain list, and tables are real tables in a scrolling box.

ClassWhat it does
fam-listA plain list of rows. Each fam-list-row is a link or a button, with aria-current="true" on the selected one.
fam-table-boxA box of fixed height that scrolls its fam-table, with a sticky header and stripes that carry on below the last row.
fam-table-box--light-inkLight ink for dark surfaces such as brown cardstock.

List rows

A list with a selected row, on paper.

HTML
<div class="fam-paper" style="padding: 20px">
  <ul class="fam-list" aria-label="Notes">
    <li><a class="fam-list-row" href="#"><b>Grocery run</b><span>Today</span></a></li>
    <li><a class="fam-list-row" href="#" aria-current="true"><b>Picnic plans</b><span>Yesterday</span></a></li>
    <li><a class="fam-list-row" href="#"><b>Book ideas</b><span>Monday</span></a></li>
  </ul>
</div>

Zebra tables

A table in a box of fixed height. The header stays at the top while the rows scroll, and the stripes carry on below the last row so the box always looks full. The stripes are a see-through tint of one ink, so the paper or cardstock shows through them. --fam-row-height sets the height of every row and of the empty stripes, --fam-table-rows sets how many rows tall the box is, and --fam-table-ink and --fam-table-stripe set the color and strength of the stripes. Rows are one line, so text that does not fit is cut short with an ellipsis. Light ink is for dark materials such as brown cardstock. Small dark text does not reach 4.5:1 on the natural light cardstock, whose fibers are dark flecks, so put dark ink on paper and use light ink on brown cardstock. The first table is read only. The second is a grid with a selected row, and its arrow keys need a few lines of script, which table-grid.js in the showcase folder supplies.

NameKindSize
Receipt-01.pngPNG image2.6 MB
Receipt-02.pngPNG image2.9 MB
Notes.txtPlain text4 KB
Invoice.pdfPDF document1.1 MB
Photo-01.jpgJPEG image3.9 MB
Photo-02.jpgJPEG image4.2 MB
Budget.csvSpreadsheet18 KB
Letter.docxWord document64 KB
Map.pngPNG image1.8 MB
Song.m4aAudio5.1 MB
Slides.keyPresentation12 MB
Archive.zipZIP archive48 MB
HTML
<div class="fam-paper" style="padding: 20px">
  <div class="fam-table-box" role="region" aria-label="Files on paper" tabindex="0" style="--fam-table-rows: 6">
    <table class="fam-table" aria-label="Files on paper">
      <colgroup><col style="width:44%"><col style="width:34%"><col style="width:22%"></colgroup>
      <thead><tr><th scope="col">Name</th><th scope="col">Kind</th><th scope="col">Size</th></tr></thead>
      <tbody>
        <tr><td>Receipt-01.png</td><td>PNG image</td><td>2.6 MB</td></tr>
        <tr><td>Receipt-02.png</td><td>PNG image</td><td>2.9 MB</td></tr>
        <!-- more rows -->
      </tbody>
    </table>
  </div>
</div>
NameKindSize
Receipt-01.pngPNG image2.6 MB
Receipt-02.pngPNG image2.9 MB
Notes.txtPlain text4 KB
Invoice.pdfPDF document1.1 MB
Photo-01.jpgJPEG image3.9 MB
Photo-02.jpgJPEG image4.2 MB
Budget.csvSpreadsheet18 KB
Letter.docxWord document64 KB
Map.pngPNG image1.8 MB
Song.m4aAudio5.1 MB
HTML
<div class="fam-paper" style="padding: 20px">
  <div class="fam-table-box" role="region" aria-label="Selectable files on paper" style="--fam-table-rows: 6; --fam-row-height: 28px">
    <table class="fam-table" role="grid" aria-label="Selectable files on paper" data-table-grid>
      <thead><tr><th scope="col">Name</th><th scope="col">Kind</th><th scope="col">Size</th></tr></thead>
      <tbody>
        <tr tabindex="-1" aria-selected="false"><td>Receipt-01.png</td><td>PNG image</td><td>2.6 MB</td></tr>
        <tr tabindex="0" aria-selected="true"><td>Notes.txt</td><td>Plain text</td><td>4 KB</td></tr>
        <!-- more rows -->
      </tbody>
    </table>
  </div>
</div>
NameKindSize
Receipt-01.pngPNG image2.6 MB
Receipt-02.pngPNG image2.9 MB
Notes.txtPlain text4 KB
HTML
<div class="fam-cardstock" style="--fam-cardstock-tint: #562a0e; padding: 20px">
  <div class="fam-table-box fam-table-box--light-ink" role="region" aria-label="Files on brown cardstock" tabindex="0" style="--fam-table-rows: 6">
    <table class="fam-table" aria-label="Files on brown cardstock">
      <thead><tr><th scope="col">Name</th><th scope="col">Kind</th><th scope="col">Size</th></tr></thead>
      <tbody>
        <tr><td>Receipt-01.png</td><td>PNG image</td><td>2.6 MB</td></tr>
        <!-- more rows -->
      </tbody>
    </table>
  </div>
</div>

Keyboard focus

Press Tab to move through these controls. Each one draws a two-tone ring: a white halo next to the control and a dark outline outside it, so the ring reads on metal, felt and wood alike.

HTML
<div class="fam-metal" style="padding: 28px"><button class="fam-metal-button fam-shadow-md" type="button">Play</button></div>
<div class="fam-felt" style="padding: 28px"><div class="fam-glass"><input class="fam-glass-input" placeholder="Search" aria-label="Search"></div></div>
<div class="fam-wood" style="padding: 28px"><label class="fam-switch fam-shadow-md"><input type="checkbox" role="switch" aria-label="Wi-Fi" checked><span class="fam-switch-knob"></span></label></div>