FormsForms overview

Inputs, selects, textareas, checkboxes, radios and switches are styled by element and by type, with validation states driven by aria-invalid.

On this page

Form controls are styled by tag name and by type, so a plain form needs no classes. Inputs, selects and textareas are full width. A label can wrap its control or sit next to it, and <small> right after a control becomes helper text.

A simple form
<form>
  <label>
    First name
    <input name="first_name" placeholder="First name" autocomplete="given-name" />
  </label>
  <label>
    Email
    <input type="email" name="email" placeholder="Email" autocomplete="email" />
    <small>We will never share your email.</small>
  </label>
  <label>
    Country
    <select name="country">
      <option>Portugal</option>
      <option>Spain</option>
    </select>
  </label>
  <fieldset>
    <label><input type="checkbox" name="terms" /> I agree to the terms</label>
    <label><input type="checkbox" role="switch" name="news" checked /> Send me news</label>
  </fieldset>
  <input type="submit" value="Subscribe" />
</form>

What is covered

Each control has its own page: Input, Textarea, Select, Checkboxes, Radios, Switch, Range, Color, Date and time, File and Search. Feedback is covered in Validation states, and joining controls with buttons in Groups.

Labels, fieldsets and helper text

A label is a block with a small gap below it. Put the control inside the label or after it, and the spacing stays the same. Use fieldset and legend to group related controls. A fieldset has no border or padding, so it only adds structure and spacing.

<small> placed directly after an input, select, textarea, fieldset or .grid is pulled up under that element and takes the muted color. After a control with aria-invalid, it takes the valid or invalid color. See Validation states.

Disabled and read-only

disabled on a control, or on a fieldset, lowers the opacity and turns off pointer events. A label with aria-disabled="true" dims the same way. readonly keeps the normal look but skips the focus ring and the active background.

Disabled and read-only
<label>
  Disabled
  <input value="Cannot edit" disabled />
</label>
<label>
  Read-only
  <input value="Can select, cannot edit" readonly />
</label>
<fieldset disabled>
  <label>
    Inside a disabled fieldset
    <input value="Also disabled" />
  </label>
</fieldset>

Customization

Form colors and spacing come from custom properties on :root. The colors use light-dark(), so they follow the color scheme without extra rules.

--pico-form-element-spacing-vertical
0.5rem
Vertical padding of controls.
--pico-form-element-spacing-horizontal
0.75rem
Horizontal padding of controls.
--pico-form-element-background-color
light-dark(#ffffff, #131518)
Control background.
--pico-form-element-active-background-color
light-dark(#ffffff, #17181c)
Control background while active or focused.
--pico-form-element-border-color
light-dark(#8f929a, #66696f)
Control border.
--pico-form-element-active-border-color
var(--pico-primary-focus)
Control border while active or focused.
--pico-form-element-color
light-dark(#13161c, #edeef1)
Control text color.
--pico-form-element-placeholder-color
var(--pico-muted-color)
Placeholder text color.
--pico-form-element-focus-color
var(--pico-primary-focus)
Focus ring color.
--pico-form-element-disabled-opacity
0.5
Opacity of disabled controls.
--pico-form-label-font-weight
Font weight of labels and legends.