Skip to content

CSS

A dropdown is a composition: a trigger, the tng-dropdown panel, and a List inside it. tng-dropdown paints the panel — surface, elevation and inline padding — and everything in it comes from other components. The examples below show the panel open; the Recipes wire it to a popover.

<div class="tng-field-control">
<button class="tng-field-control-button" aria-expanded="true">
Zone
</button>
<i class="tng-icon icon-chevron-down"></i>
</div>
<div class="tng-dropdown">
<ul
class="tng-list tng-has-dividers"
role="listbox"
aria-label="Zone"
>
<li class="tng-list-option" role="option" aria-selected="true">
TZ1
</li>
<li class="tng-list-option" role="option">TZ2</li>
<li class="tng-list-option" role="option">TZ3</li>
</ul>
</div>
  • TZ1
  • TZ2
  • TZ3

Open the panel from a Field control button inside a form, or from a Chip as a filter. The trigger owns the label, helper text, required mark and its own states.

<button class="tng-chip" aria-expanded="true">
Body type
<i class="tng-icon icon-chevron-down" aria-hidden="true"></i>
</button>
<div class="tng-dropdown">
<ul
class="tng-list tng-has-dividers"
role="listbox"
aria-label="Body type"
>
<li class="tng-list-option" role="option">Hatchback</li>
<li class="tng-list-option" role="option">Saloon</li>
<li class="tng-list-option" role="option">SUV</li>
</ul>
</div>
  • Hatchback
  • Saloon
  • SUV

When an option opens a second level, put a borderless tertiary Button above the list to return to the first.

<div class="tng-dropdown">
<button class="tng-button is-tertiary is-ghost">
<i
class="tng-icon icon-arrow-left tng-rtl-flip-x"
aria-hidden="true"
></i>
Back
</button>
<ul
class="tng-list tng-has-dividers"
role="listbox"
aria-label="Hybrid"
>
<li class="tng-list-option" role="option">
Yaris Hybrid
<i
class="tng-icon icon-chevron-right tng-rtl-flip-x"
aria-hidden="true"
></i>
</li>
<li class="tng-list-option" role="option">
C-HR Hybrid
<i
class="tng-icon icon-chevron-right tng-rtl-flip-x"
aria-hidden="true"
></i>
</li>
<li class="tng-list-option" role="option">
RAV4 Hybrid
<i
class="tng-icon icon-chevron-right tng-rtl-flip-x"
aria-hidden="true"
></i>
</li>
</ul>
</div>
  • Yaris Hybrid
  • C-HR Hybrid
  • RAV4 Hybrid

Cap a long list with max-block-size and let tng-overflow-scroll draw the scrollbar. Figma caps it at 455px.

<div class="tng-dropdown">
<ul
class="tng-list tng-has-dividers tng-overflow-scroll"
role="listbox"
aria-label="Zone"
style="max-block-size: 200px"
>
<li class="tng-list-option" role="option">TZ1</li>
<li class="tng-list-option" role="option">TZ2</li>
<li class="tng-list-option" role="option">TZ3</li>
<li class="tng-list-option" role="option">TZ4</li>
<li class="tng-list-option" role="option">TZ5</li>
<li class="tng-list-option" role="option">TZ6</li>
<li class="tng-list-option" role="option">TZ7</li>
</ul>
</div>
  • TZ1
  • TZ2
  • TZ3
  • TZ4
  • TZ5
  • TZ6
  • TZ7

A multi-select list confirms with a row of buttons under the list: a tertiary one to clear, a primary one to apply.

<div class="tng-dropdown">
<ul
class="tng-list"
role="listbox"
aria-label="Body type"
aria-multiselectable="true"
>
<li class="tng-list-option" role="option">
<label class="tng-checkbox-control">
<input type="checkbox" tabindex="-1" checked />
Hatchback
</label>
</li>
<li class="tng-list-option" role="option">
<label class="tng-checkbox-control">
<input type="checkbox" tabindex="-1" />
Saloon
</label>
</li>
</ul>
<div class="tng-flex gap-4xl pb-xl pi-xl">
<button class="tng-button is-tertiary flex-grow-1">
Clear all
</button>
<button class="tng-button is-primary flex-grow-1">
Show 12 results
</button>
</div>
</div>

The panel takes any List content. Three shapes cover the Figma list types.

Text options. Add tng-has-dividers for the line under each one.

<div class="tng-dropdown">
<ul
class="tng-list tng-has-dividers"
role="listbox"
aria-label="Zone"
>
<li class="tng-list-option" role="option">TZ1</li>
<li class="tng-list-option" role="option">TZ2</li>
</ul>
</div>
  • TZ1
  • TZ2

Options that carry a model image and a powertrain label.

<div class="tng-dropdown">
<ul
class="tng-list tng-has-dividers"
role="listbox"
aria-label="Model"
>
<li class="tng-list-option" role="option">
<img alt="" src="/_astro/prius.B6m1c0f0.png" />
<div class="tng-list-powertrain">
<div class="tng-list-powertrain-subtitle">
<span class="tng-label is-blue">
<i
class="tng-icon icon-plug-droplet"
aria-hidden="true"
></i>
<span>Plug-in Hybrid</span>
</span>
<div>333 mi</div>
</div>
<div class="tng-text-body">Prius</div>
</div>
</li>
</ul>
</div>
  • Plug-in Hybrid
    333 mi
    Prius

Wrap each option in a Checkbox control and mark the list aria-multiselectable. Pair it with Actions.

<div class="tng-dropdown">
<ul
class="tng-list"
role="listbox"
aria-label="Body type"
aria-multiselectable="true"
>
<li class="tng-list-option" role="option">
<label class="tng-checkbox-control">
<input type="checkbox" tabindex="-1" checked />
Hatchback
</label>
</li>
<li class="tng-list-option" role="option">
<label class="tng-checkbox-control">
<input type="checkbox" tabindex="-1" />
Saloon
</label>
</li>
<li class="tng-list-option" role="option">
<label class="tng-checkbox-control">
<input type="checkbox" tabindex="-1" />
Estate
</label>
</li>
</ul>
</div>

aria-selected="true" on an option, or a checked checkbox inside it, gives it the selected background.

<div class="tng-dropdown">
<ul
class="tng-list tng-has-dividers"
role="listbox"
aria-label="Zone"
>
<li class="tng-list-option" role="option">TZ1</li>
<li class="tng-list-option" role="option" aria-selected="true">
TZ2
</li>
</ul>
</div>
  • TZ1
  • TZ2
source code
source code