ContentButton

Buttons from button, input and role="button" elements, with secondary, contrast and outline variants, loading and disabled states.

On this page

<button>, <input type="submit">, <input type="button">, <input type="reset"> and any element with role="button" share one style. A link that should look like a button takes role="button".

Buttons
<button>Button</button>
<a href="#" role="button">Link button</a>
<input type="button" value="Input button" />

Submit buttons and input buttons are full width by default, like text fields. Plain <button> and role="button" elements are as wide as their content. Set style="width: auto" on a full width one, or put buttons in a group.

Variants

Add .secondary or .contrast for the other two palettes. A reset button looks secondary without a class.

Secondary and contrast
<button>Primary</button>
<button class="secondary">Secondary</button>
<button class="contrast">Contrast</button>
<input type="reset" value="Reset" />

Outline

.outline removes the fill and keeps the border. It combines with .secondary and .contrast.

Outline buttons
<button class="outline">Primary</button>
<button class="outline secondary">Secondary</button>
<button class="outline contrast">Contrast</button>

Disabled

disabled fades the button and turns off pointer events. A fieldset[disabled] disables every button inside it.

Disabled buttons
<button disabled>Disabled</button>
<fieldset disabled>
  <button>Inside a disabled fieldset</button>
</fieldset>

disabled is not valid on <a>, so a link with role="button" cannot be disabled this way. Render a <button disabled> instead.

Loading

aria-busy="true" shows a spinner before the label. Without a label the spinner is centered. Remember to remove the attribute when the work ends.

Busy buttons
<button aria-busy="true">Please wait</button>
<button aria-busy="true" class="secondary" aria-label="Please wait"></button>

Groups

role="group" joins buttons into one control. Inside a group buttons are auto width and overlap by one border.

Button group
<div role="group">
  <button>Save</button>
  <button class="secondary">Cancel</button>
  <button class="contrast">Help</button>
</div>

Accessibility

Use a <button> for actions and an <a> for navigation. When you give a link role="button", it does not respond to the space key like a real button, so use it for navigation only. Keyboard focus shows a ring, and aria-current on a button applies the hover look.

Customization

--pico-primary-background
#0172ad
Fill of the default button.
--pico-primary-border
var(--pico-primary-background)
Border of the default button.
--pico-primary-inverse
#ffffff
Text color on the fill.
--pico-primary-hover-background
light-dark(#02659a, #017fc0)
Fill on hover, active, focus and aria-current.
--pico-primary-focus
light-dark(#017fc0, #01aaff)
Focus ring color. Secondary and contrast have their own.
--pico-button-box-shadow
0 0.0625rem 0.125rem 0 oklch(0 0 0 / 0.08), inset 0 0.0625rem 0 0 oklch(1 0 0 / 0.12)
Resting shadow. Set it to add depth to every button.
--pico-button-hover-box-shadow
0 0.125rem 0.375rem -0.0625rem oklch(0 0 0 / 0.14), inset 0 0.0625rem 0 0 oklch(1 0 0 / 0.12)
Shadow on hover and focus.
--pico-form-element-spacing-vertical
0.5rem
Vertical padding.
--pico-form-element-spacing-horizontal
0.75rem
Horizontal padding.
--pico-border-radius
0.5rem
Corner radius.

The secondary and contrast variants use the matching --pico-secondary-* and --pico-contrast-* variables. See Themes. Form controls that sit next to buttons are on Forms.