Lesson 17 / 25

Forms

Inputs, labels and validation states.

Accessible, styled form controls

Style inputs with border, padding, radius and a visible focus ring (focus:ring-2 focus:ring-cyan-500). Always pair inputs with a <label>, show help and error text linked with aria-describedby, and style invalid states with invalid: or aria-invalid: variants. accent-cyan-600 colours checkboxes and radios natively. The official forms plugin (@tailwindcss/forms) resets controls to a consistent, easily styled base.

A labelled input with an error

Error state driven by aria-invalid.

<div>
  <label for="email" class="block text-sm font-medium text-gray-900">Email</label>
  <input id="email" type="email" aria-invalid="true" aria-describedby="email-error"
         class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2
                focus:border-cyan-500 focus:ring-2 focus:ring-cyan-500/30 focus:outline-none
                aria-invalid:border-red-500">
  <p id="email-error" class="mt-1 text-sm text-red-600">Please enter a valid email address.</p>
</div>

<label class="mt-4 flex items-center gap-2 text-sm">
  <input type="checkbox" class="size-4 accent-cyan-600"> Remember me
</label>

Never rely on colour alone for errors

Pair red borders with text messages so colour-blind users understand the problem.

Quick check: Which variant styles an input whose aria-invalid attribute is true?

  • dark:
  • hover:
  • aria-invalid:
  • group-invalid-only:
Answer

aria-invalid: — ARIA attribute variants.