Input

Form input components with consistent styling

Overview

Form inputs with automatic dark mode support and accessible focus states.

Import

/* Full framework (includes all components) */
@import "@shift-css/core";

/* Or import just the input component */
@import "@shift-css/core/components/input";

Note: When importing individual components, you also need @shift-css/core/reset and @shift-css/core/tokens for the base styles and design tokens.

Text Inputs

Basic input fields

We'll never share your email.
This field has an error.
<div class="demo-grid">
<div s-field>
  <label s-field-label for="demo-text">Text Input</label>
  <input s-input type="text" id="demo-text" placeholder="Enter text..." />
</div>
<div s-field>
  <label s-field-label for="demo-email">With Hint</label>
  <input s-input type="email" id="demo-email" placeholder="you@example.com" />
  <span s-field-hint>We'll never share your email.</span>
</div>
<div s-field>
  <label s-field-label for="demo-error">With Error</label>
  <input s-input type="text" id="demo-error" aria-invalid="true" value="Invalid input" />
  <span s-field-error>This field has an error.</span>
</div>
</div>

Input Sizes

Use the s-size attribute:

Size variants

<div class="demo-grid">
<div s-field>
  <label s-field-label for="input-sm">Small</label>
  <input s-input s-size="sm" type="text" id="input-sm" placeholder="Small input" />
</div>
<div s-field>
  <label s-field-label for="input-md">Default</label>
  <input s-input type="text" id="input-md" placeholder="Default input" />
</div>
<div s-field>
  <label s-field-label for="input-lg">Large</label>
  <input s-input s-size="lg" type="text" id="input-lg" placeholder="Large input" />
</div>
</div>

Input Groups

Combine inputs with addons for prefixes or suffixes:

Input with addons

https://
USD
<div class="demo-grid">
<div s-field>
  <label s-field-label for="demo-url">URL</label>
  <div s-input-group>
    <span s-input-addon>https://</span>
    <input s-input type="text" id="demo-url" placeholder="example.com" />
  </div>
</div>
<div s-field>
  <label s-field-label for="demo-price">Price</label>
  <div s-input-group>
    <input s-input type="number" id="demo-price" placeholder="0.00" />
    <span s-input-addon>USD</span>
  </div>
</div>
</div>

Select & Textarea

Select and textarea

<div class="demo-grid">
<div s-field>
  <label s-field-label for="demo-select">Select</label>
  <select s-input id="demo-select">
    <option>Option 1</option>
    <option>Option 2</option>
    <option>Option 3</option>
  </select>
</div>
<div s-field>
  <label s-field-label for="demo-textarea">Textarea</label>
  <textarea s-input id="demo-textarea" rows="3" placeholder="Enter message..."></textarea>
</div>
</div>

Checkbox, Radio & Toggle

Form controls

<div class="demo-grid">
<div class="demo-stack">
  <label s-checkbox>
    <input type="checkbox" checked />
    Checkbox option
  </label>
  <label s-checkbox>
    <input type="checkbox" />
    Another option
  </label>
</div>
<div class="demo-stack">
  <label s-radio>
    <input type="radio" name="demo-radio" checked />
    Radio option 1
  </label>
  <label s-radio>
    <input type="radio" name="demo-radio" />
    Radio option 2
  </label>
</div>
<div class="demo-stack">
  <label s-toggle>
    <input type="checkbox" checked />
    Enable feature
  </label>
  <label s-toggle>
    <input type="checkbox" />
    Another toggle
  </label>
</div>
</div>

States

Disabled

<input s-input type="text" disabled placeholder="Disabled input" />

Invalid

<input s-input type="text" aria-invalid="true" value="Invalid input" />

Form Layout Example

<form>
  <div s-field>
    <label s-field-label for="name">Name</label>
    <input s-input type="text" id="name" />
  </div>
  <div s-field>
    <label s-field-label for="email">Email</label>
    <input s-input type="email" id="email" />
    <span s-field-hint>We'll never share your email.</span>
  </div>
  <div s-field>
    <label s-field-label for="message">Message</label>
    <textarea s-input id="message" rows="4"></textarea>
    <span s-field-error>This field is required.</span>
  </div>
  <div>
    <button s-btn="primary" type="submit">Submit</button>
    <button s-btn="ghost" type="reset">Reset</button>
  </div>
</form>

How It Works

:where([s-input]) {
  --_input-bg: var(--s-surface-base);
  --_input-border: var(--s-border-default);
  --_input-radius: var(--s-radius-md);

  background-color: var(--_input-bg);
  border: 2px solid var(--_input-border);
  border-radius: var(--_input-radius);
  padding: var(--s-space-2) var(--s-space-3);
}

[s-input]:focus {
  --_input-border: var(--s-interactive-primary);
  box-shadow: 0 0 0 3px oklch(from var(--s-interactive-primary) l c h / 0.2);
}

Form Attributes

AttributePurposeExample
s-inputText input styling<input s-input>
s-fieldForm field wrapper<div s-field>
s-field-labelField label<label s-field-label>
s-field-hintHelper text<span s-field-hint>
s-field-errorError message<span s-field-error>
s-checkboxCheckbox wrapper<label s-checkbox>
s-radioRadio button wrapper<label s-radio>
s-toggleToggle switch wrapper<label s-toggle>
s-input-groupInput with addons<div s-input-group>
s-input-addonAddon element<span s-input-addon>

Customization Examples

Rounded Inputs

[s-input] {
  --_radius: var(--s-radius-full);
}

Custom Focus Color

:root {
  --s-focus-ring: var(--s-accent-500);
}
Search