Bruhs home Forms

Form controls

Style native HTML controls with CSS. State variants handle their appearance.

Text input

Add input to a text field or textarea. Set aria-invalid="true" to show an error. The focus ring stays inside the field.

That handle is taken. Choose another.

HTML
<div class="flex flex-col gap-2">
  <label for="email" class="text-label text-rambutan-200">Email</label>
  <input id="email" name="email" type="email" placeholder="you@bruhs.dev" class="input" />
</div>
<div class="flex flex-col gap-2">
  <label for="handle" class="text-label text-rambutan-200">Handle</label>
  <input id="handle" name="handle" value="bruh" aria-invalid="true" aria-describedby="handle-error" class="input" />
  <p id="handle-error" class="text-body-sm text-lychee-300">That handle is taken. Choose another.</p>
</div>
<div class="flex flex-col gap-2 sm:col-span-2">
  <label for="bio" class="text-label text-rambutan-200">Bio</label>
  <textarea id="bio" name="bio" rows="3" placeholder="A short bio" class="input"></textarea>
</div>

Segmented control

Use a segmented control to choose one of two to four views. Mark the active item with the ARIA state that matches its role. The class supports aria-pressed, aria-selected and aria-checked.

HTML
<div class="segmented" role="group" aria-label="View">
  <button type="button" class="segmented-item" aria-pressed="true">Preview</button>
  <button type="button" class="segmented-item" aria-pressed="false">Code</button>
</div>

Select

Use a native <select> with a custom chevron. The wrapper carries the focus ring. Examples below show the available sizes and states.

Choose a fruit to continue.

Checkbox

Set input.indeterminate = true in JavaScript for a partial selection. CSS handles the appearance through :indeterminate and group-not-has-indeterminate.

Radio

Toggle

Rules

Give every control a name and an accessible label.

Use input for text fields. Use inset-ring for custom control outlines.

Make choice controls larger on mobile with size-5 sm:size-4.

Leave a gap between a field and its button, or place the button inside the field.