SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/tailwind-input-fields

6 Tailwind Input Fields

4 Tailwind2 with JSPublished 2026-10-04Free · no sign-up

Six Tailwind form inputs: a floating label made with peer-placeholder-shown, a search field with a keyboard hint, default, error and success states, prefix and suffix add-ons, a textarea with a live counter and a password field with a Show button.

01. Tailwind Floating Label

TailwindLabel

A floating label done entirely with Tailwind: the input is the peer, placeholder-shown: keeps the label large inside the field, and peer-focus: and the non-empty state lift it above. A single-space placeholder makes :placeholder-shown work.

View code
<div class="relative w-full max-w-xs">
  <input id="twf" type="email" placeholder=" " autocomplete="email" class="peer block w-full rounded-xl border-2 border-slate-300 bg-white px-3.5 pb-2 pt-6 text-base text-slate-900 outline-none focus:border-blue-600 focus:ring-4 focus:ring-blue-100">
  <label for="twf" class="pointer-events-none absolute left-3.5 top-2 origin-left text-xs font-medium text-blue-700 transition-all peer-placeholder-shown:top-4 peer-placeholder-shown:text-base peer-placeholder-shown:text-slate-500 peer-focus:top-2 peer-focus:text-xs peer-focus:text-blue-700">Email address</label>
</div>

03. Tailwind Input States

TailwindValidation

Default, error and success fields with matching hint text. The error field uses aria-invalid and the aria-[invalid=true]: variant for its red border, so the visual state always matches the state announced to assistive technology.

View code
<div class="grid w-full max-w-sm gap-4 text-sm">
  <div><label for="tw1" class="mb-1.5 block font-semibold text-slate-700">Shop name</label><input id="tw1" value="Clayworks" aria-describedby="tw1h" class="w-full rounded-lg border border-slate-300 px-3 py-2.5 text-[15px] outline-none focus:border-blue-600 focus:ring-2 focus:ring-blue-100"><p id="tw1h" class="mt-1.5 text-slate-500">Shown on receipts.</p></div>
  <div><label for="tw2" class="mb-1.5 block font-semibold text-slate-700">Email</label><input id="tw2" value="hello@" aria-invalid="true" aria-describedby="tw2h" class="w-full rounded-lg border border-slate-300 px-3 py-2.5 text-[15px] outline-none aria-[invalid=true]:border-red-600 aria-[invalid=true]:ring-2 aria-[invalid=true]:ring-red-100"><p id="tw2h" class="mt-1.5 text-red-700">&#9888; Enter a full email address.</p></div>
  <div><label for="tw3" class="mb-1.5 block font-semibold text-slate-700">Shop URL</label><input id="tw3" value="clayworks" aria-describedby="tw3h" class="w-full rounded-lg border border-green-600 px-3 py-2.5 text-[15px] outline-none focus:ring-2 focus:ring-green-100"><p id="tw3h" class="mt-1.5 text-green-700">&#10003; Available</p></div>
</div>

04. Tailwind Input with Add-ons

TailwindAddon

A price field with a currency prefix and a URL field with a domain suffix. The wrapper uses focus-within: to show the focus ring around the whole group, and the add-ons are styled spans that inherit the group's rounded corners.

View code
<div class="grid w-full max-w-sm gap-4 text-sm font-semibold text-slate-300">
  <div><label for="twp" class="mb-1.5 block">Price</label><div class="flex overflow-hidden rounded-lg border border-slate-700 bg-slate-900 focus-within:border-amber-400 focus-within:ring-2 focus-within:ring-amber-400/30"><span class="grid place-items-center bg-slate-800 px-3 text-slate-400">$</span><input id="twp" inputmode="decimal" value="49.00" class="w-0 min-w-0 flex-1 bg-transparent px-3 py-2.5 text-[15px] text-white outline-none"></div></div>
  <div><label for="twu" class="mb-1.5 block">Shop address</label><div class="flex overflow-hidden rounded-lg border border-slate-700 bg-slate-900 focus-within:border-amber-400 focus-within:ring-2 focus-within:ring-amber-400/30"><input id="twu" value="clayworks" class="w-0 min-w-0 flex-1 bg-transparent px-3 py-2.5 text-[15px] text-white outline-none"><span class="grid place-items-center bg-slate-800 px-3 text-slate-400">.myshop.com</span></div></div>
</div>

05. Tailwind Textarea with Counter

TailwindJavaScript

A message box with a live character count in the corner, turning amber near the limit. The count is a polite live region, and the textarea uses resize-y so people can make it taller but the layout width never breaks.

View code
<div class="w-full max-w-sm">
  <label for="twt" class="mb-1.5 block text-sm font-semibold text-slate-700">Note to the seller</label>
  <div class="relative">
    <textarea id="twt" rows="4" maxlength="160" aria-describedby="twc" class="w-full resize-y rounded-lg border border-slate-300 px-3 py-2.5 pb-7 text-[15px] text-slate-900 outline-none focus:border-teal-600 focus:ring-2 focus:ring-teal-100">Please wrap it as a gift.</textarea>
    <span id="twc" aria-live="polite" class="absolute bottom-3 right-3 text-xs text-slate-500"></span>
  </div>
</div>
const ta = document.getElementById('twt'), ct = document.getElementById('twc');
function upd() { const left = ta.maxLength - ta.value.length; ct.textContent = left + ' left'; ct.classList.toggle('text-amber-700', left <= 20); ct.classList.toggle('text-slate-500', left > 20); }
ta.addEventListener('input', upd); upd();

06. Tailwind Password with Toggle

TailwindAuth

A password field with an eye button that reveals the text. The button sits inside the field with absolute positioning, has an accessible name and aria-pressed, and the input keeps autocomplete="new-password" for password managers.

View code
<div class="w-full max-w-xs">
  <label for="twpw" class="mb-1.5 block text-sm font-semibold text-slate-300">New password</label>
  <div class="relative">
    <input id="twpw" type="password" value="studio-2026" autocomplete="new-password" class="w-full rounded-lg border border-slate-700 bg-slate-900 py-2.5 pl-3 pr-20 text-[15px] text-white outline-none focus:border-sky-400 focus:ring-2 focus:ring-sky-400/30">
    <button type="button" aria-pressed="false" aria-controls="twpw" class="absolute right-2 top-1/2 -translate-y-1/2 rounded-md bg-slate-800 px-2.5 py-1 text-xs font-bold text-slate-200 focus-visible:outline focus-visible:outline-2 focus-visible:outline-sky-400">Show</button>
  </div>
</div>
const pb = document.querySelector('[aria-controls=twpw]'), pf = document.getElementById('twpw');
pb.addEventListener('click', () => { const s = pf.type === 'password'; pf.type = s ? 'text' : 'password'; pb.textContent = s ? 'Hide' : 'Show'; pb.setAttribute('aria-pressed', String(s)); });

About these Tailwind Input Fields

Floating labels with peer

Put the label after the input, mark the input as peer and give it a single-space placeholder. peer-placeholder-shown: keeps the label large inside the empty field, and peer-focus: lifts it when the field is focused.

Error state from ARIA

The error field uses aria-invalid="true" and the aria-[invalid=true]: variant for its red border. Styling from the ARIA attribute guarantees the visual state matches what assistive technology announces.

Focus inside a group

For fields with add-ons, put the border on the wrapper and use focus-within: utilities so the ring surrounds the whole group when the input inside is focused.

Readable placeholders

Placeholder text often fails contrast checks. Use placeholder:text-slate-400 or darker on light fields, and never put instructions only in the placeholder.

Frequently asked questions

Which demos use JavaScript?

The textarea counter and the password toggle; the rest are pure Tailwind.

Do these use the forms plugin?

No. They style inputs directly with utilities, so no plugin is needed.

Can I use them with React or Vue?

Yes. Copy the markup and rename class to className in JSX.