Input

The universal form-control class. One class covers every input type; each type shares the input appearance (border, radius, surface, focus ring) and adds its own shape below.

Examples

Basic usage

<form class="stack">
            <div class="stack is-tight">
                <label for="f-email">Email</label>
                <input
                    id="f-email"
                    type="email"
                    class="input"
                    placeholder="you@example.com"
                    required
                />
            </div>
            <div class="stack is-tight">
                <label for="f-message">Message</label>
                <textarea id="f-message" class="input" rows="3"></textarea>
            </div>
            <button class="button" type="submit">Send</button>
        </form>

Size

<div class="cluster is-tight">
            <input type="text" class="input is-sm" placeholder="Small" />
            <input type="text" class="input" placeholder="Default" />
            <input type="text" class="input is-lg" placeholder="Large" />
        </div>

State

Letters, numbers, and underscores only.

Shown on your public profile.

<div class="stack">
            <div>
                <div class="stack is-tight measure-narrow">
                    <label for="f-username">Username</label>
                    <input
                        id="f-username"
                        type="text"
                        class="input"
                        value="nope!"
                        aria-invalid="true"
                        aria-describedby="f-username-err"
                    />
                    <p id="f-username-err" class="text-danger text--1">
                        Letters, numbers, and underscores only.
                    </p>
                </div>
            </div>
            <div class="stack is-tight">
                <label for="f-locked">Account ID</label>
                <input id="f-locked" type="text" class="input" value="ACC-0042" disabled />
            </div>
        </div>

        <div class="stack">
            <div class="stack is-tight">
                <label for="f-readonly">Account ID</label>
                <input id="f-readonly" type="text" class="input" value="ACC-0042" readonly />
            </div>
            <div>
                <div class="stack is-tight">
                    <label for="f-helped">Display name</label>
                    <input
                        id="f-helped"
                        type="text"
                        class="input"
                        value="octetic"
                        aria-describedby="f-helped-help"
                    />
                    <p id="f-helped-help" class="text-muted text--1">
                        Shown on your public profile.
                    </p>
                </div>
            </div>
        </div>
    </div>

Native types

<div class="stack is-snug">
            <input type="email" class="input" placeholder="you@example.com" />
            <input type="password" class="input" placeholder="Password" />
            <input type="search" class="input" placeholder="Search..." />
            <input type="tel" class="input" placeholder="(555) 123-4567" />
            <input type="url" class="input" placeholder="https://example.com" />
            <input type="number" class="input" placeholder="42" />
            <input type="date" class="input" />
            <input type="time" class="input" />
        </div>

Textarea

<div class="stack">
            <textarea class="input" rows="4" placeholder="Fixed rows"></textarea>

            <div style="block-size: 12rem">
                <textarea
                    class="input"
                    style="inline-size: 100%; block-size: 100%"
                    placeholder="Fill container"
                ></textarea>
            </div>

            <textarea
                class="input"
                style="field-sizing: content; min-block-size: 2.25rem"
                placeholder="Grow with content"
            ></textarea>
        </div>

Select

<div class="stack is-tight">
            <label for="f-role">Role</label>
            <select id="f-role" class="input">
                <option>Admin</option>
                <option>Editor</option>
                <option>Viewer</option>
            </select>
        </div>

File

<div class="stack is-tight">
            <label for="f-avatar">Avatar</label>
            <input id="f-avatar" type="file" class="input" accept="image/*" />
        </div>

Stacked (canonical)

<form class="stack">
            <div class="stack is-tight">
                <label for="signin-email">Email</label>
                <input
                    id="signin-email"
                    type="email"
                    class="input"
                    required
                    autocomplete="username"
                />
            </div>
            <div class="stack is-tight">
                <label for="signin-password">Password</label>
                <input
                    id="signin-password"
                    type="password"
                    class="input"
                    required
                    autocomplete="current-password"
                />
            </div>
            <label class="cluster is-tight">
                <input type="checkbox" name="remember" class="input" /> Remember me on this device
            </label>
            <button class="button" type="submit">Sign in</button>
        </form>

Horizontal

<form class="cluster is-snug" role="search">
                <label for="quick-search">Search products</label>
                <input
                    id="quick-search"
                    style="flex: 1"
                    type="search"
                    class="input"
                    placeholder="Widget, gadget, ..."
                    autocomplete="off"
                />
                <button class="button" type="submit">Go</button>
            </form>

Multi-column fields

<form class="stack">
                <div class="stack is-tight">
                    <label for="addr-street">Street address</label>
                    <input
                        id="addr-street"
                        type="text"
                        class="input"
                        autocomplete="street-address"
                    />
                </div>
                <div class="grid" style="--grid-min: 12rem">
                    <div class="stack is-tight">
                        <label for="addr-city">City</label>
                        <input
                            id="addr-city"
                            type="text"
                            class="input"
                            autocomplete="address-level2"
                        />
                    </div>
                    <div class="stack is-tight">
                        <label for="addr-state">State</label>
                        <input
                            id="addr-state"
                            type="text"
                            class="input"
                            autocomplete="address-level1"
                        />
                    </div>
                    <div class="stack is-tight">
                        <label for="addr-zip">ZIP</label>
                        <input
                            id="addr-zip"
                            type="text"
                            inputmode="numeric"
                            class="input"
                            autocomplete="postal-code"
                        />
                    </div>
                </div>
                <div class="cluster is-end">
                    <button class="button is-ghost" type="button">Cancel</button>
                    <button class="button" type="submit">Save address</button>
                </div>
            </form>

Sectioned with fieldsets

Notifications
Profile visibility
<form class="stack">
            <fieldset class="stack is-tight">
                <legend class="text-subtle text-semibold">Notifications</legend>
                <label class="cluster is-tight">
                    <input type="checkbox" checked class="input" /> Product updates
                </label>
                <label class="cluster is-tight">
                    <input type="checkbox" class="input" /> Weekly digest
                </label>
                <label class="cluster is-tight">
                    <input type="checkbox" checked class="input" /> Security alerts
                </label>
            </fieldset>
            <fieldset class="stack is-tight">
                <legend class="text-subtle text-semibold">Profile visibility</legend>
                <label class="cluster is-tight">
                    <input type="radio" name="visibility" value="public" checked class="input" />
                    Public (anyone can find your profile)
                </label>
                <label class="cluster is-tight">
                    <input type="radio" name="visibility" value="unlisted" class="input" /> Unlisted
                    (direct link required)
                </label>
                <label class="cluster is-tight">
                    <input type="radio" name="visibility" value="private" class="input" /> Private
                    (only you)
                </label>
            </fieldset>
            <div class="cluster is-between">
                <button class="button is-ghost" type="button">Cancel</button>
                <button class="button" type="submit">Save settings</button>
            </div>
        </form>

Source comments

Input family -- text inputs, textarea, select, file, checkbox,
radio, and input-group. Atoms share a common chrome token set
(--input-border-color, --input-border-width, --input-radius,
--input-bg, --input-focus-color, --input-transition) so one override
on any ancestor retones the whole family.

Markup:
  <form class="stack">
      <div class="stack is-tight">
          <label for="email">Email</label>
          <input id="email" type="email" class="input" required>
      </div>
      <button class="button" type="submit">Submit</button>
  </form>

  Labeled checkbox/radio: <label class="cluster is-tight">
  (Flex's anon-item rule means no span wrapper around text.)
  <fieldset> + <legend> for groups; bare with base.css defaults.

Design notes:
  - Validation states paint borders; error COPY is author-
    responsible (<p class="text-danger"> adjacent, or page-level
    <div class="alert is-danger" role="alert">). The automatic
    paint is gated by :user-invalid -- it matches only after the
    user has interacted with the control, so an empty required
    field does not render invalid on page load. Engines without
    :user-invalid keep the aria-invalid paint (the author-driven
    one) and simply skip the automatic one; graceful degradation,
    no feature query (P-stance on modern CSS).
  - A required field inside the field-unit stack (label directly
    before the control) picks up a CSS-drawn marker on its label --
    form.css owns that rule. The full label / help / error
    convention lives in the patterns section's field unit page.
  - Checkbox/radio/range use appearance:none custom chrome for
    visual parity with .input in dense forms. @media (forced-
    colors: active) reverts to native rendering for all three.
  - Select chevron is a pure-CSS two-gradient V per P8. Border-
    rotate chevron (details, sidebar-nav) needs a pseudo, and
    <select> doesn't accept pseudos in evergreen browsers
    without appearance: base-select.
  - .input uses :focus (not :focus-visible) because text entry
    needs the ring on click for caret visibility. Checkbox and
    radio use :focus-visible (no caret).
  - .input-group default: group owns border/bg; children are
    transparent. .is-joined reinstates per-child borders for
    the classic shaded-endcap look.

Reference

Source: src/css/input.css

Applies to

.input, .input-addon, .input-group, input[type="checkbox"].input, input[type="radio"].input

Classes

ClassKindDescription
.is-smvariantSmaller text input with tighter padding
.is-lgvariantLarger text input with more padding

Selectors

SelectorDescription
input[type="file"].inputFile input; padded shell around a styled native selector button
textarea.inputMulti-line text; height comes from rows (or field-sizing), vertical resize only
select.inputNative select; appearance:none with a CSS-drawn chevron

Tokens

TokenDefaultDescription
--input-border-colorvar(--color-border-stronger)Border color shared across the input family
--input-border-widthvar(--border-width-default)Border width shared across the input family
--input-radiusvar(--radius-md)Border radius shared across the input family
--input-bgvar(--color-surface)Background color shared across the input family
--input-focus-colorvar(--color-focus)Focus ring color shared across the input family
--input-transitionvar(--transition-fast)Transition speed shared across the input family
--input-height2.25remBlock height for text inputs and select
--input-padding-blockvar(--ui-pad-block-compact)Block-axis inner padding for text inputs and select
--input-padding-inlinevar(--ui-pad-inline-tight)Inline-axis inner padding for text inputs and select
--input-font-sizevar(--ui-font-size-sm)Font size for text inputs and select
--input-line-heightvar(--leading-tight)Line height for text inputs and select
--input-chevron-colorvar(--color-text-muted)Color of the select dropdown chevron