28 / 28
All 28 in 28 Tailwind CSS Input Fields
- 01Tailwind Floating Label Input
- 02Tailwind Underline Sweep Input
- 03Tailwind Neon Glow Input
- 04Tailwind Frosted Glass Input
- 05Tailwind Notched Outline Input
- 06Tailwind Drawn Border Input
- 07Tailwind Inline Validation Input
- 08Tailwind Search Input With Clear
- 09Tailwind Password Strength Meter
- 10Tailwind OTP Code Input
- 11Tailwind Rotating Placeholder Input
- 12Tailwind Tag Chip Input
- 13Tailwind Phone Input With Country
- 14Tailwind Stepper Number Input
- 15Tailwind File Drop Zone
- 16Tailwind Currency Input
- 17Tailwind Native Date Input
- 18Tailwind Time Range Input
- 19Tailwind Colour Picker Input
- 20Tailwind Voice Search Input
- 21Tailwind Email Suggestion Combobox
- 22Tailwind Auto-Grow Textarea
- 23Tailwind Inline Edit Field
- 24Tailwind Range Slider
- 25Tailwind URL Input With Protocol
- 26Tailwind Credit Card Input
- 27Tailwind Password Toggle Input
- 28Tailwind Brutalist Input
Tailwind Brutalist Input
A hard 2.5px border, zero radius and a flat offset shadow that the field presses into on focus. The whole aesthetic is four utilities, and the RTL flip the CSS original leaves as a gotcha is one rtl: variant here.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<div class="tif-28 grid min-h-svh w-full place-items-center bg-tif28-bg px-6 py-14 font-tif28-mono" aria-label="Brutalist input demo">
<label class="grid w-full max-w-70 gap-2">
<span class="text-[11px] font-bold tracking-[0.12em] text-tif28-ink">USERNAME_</span>
<input type="text" name="tif28-user" placeholder="enter handle…" pattern="[a-z0-9_]{3,}" required
class="w-full rounded-none border-[2.5px] border-tif28-edge bg-tif28-paper px-3.5 py-3 text-[13px] font-bold tracking-[0.06em] text-tif28-edge shadow-[5px_5px_0_var(--color-tif28-acc)] outline-none transition-[transform,box-shadow] duration-100 placeholder:text-tif28-edge/50 focus:translate-x-0.5 focus:translate-y-0.5 focus:shadow-[3px_3px_0_var(--color-tif28-acc)] user-invalid:shadow-[5px_5px_0_var(--color-tif28-bad)] rtl:shadow-[-5px_5px_0_var(--color-tif28-acc)] rtl:focus:-translate-x-0.5 rtl:focus:shadow-[-3px_3px_0_var(--color-tif28-acc)] motion-reduce:transition-none">
<span class="text-[10px] tracking-[0.08em] text-tif28-ink/60">LOWERCASE_LETTERS_DIGITS_UNDERSCORE · MIN_3</span>
</label>
</div><div class="tif-28 grid min-h-svh w-full place-items-center bg-tif28-bg px-6 py-14 font-tif28-mono" aria-label="Brutalist input demo">
<label class="grid w-full max-w-70 gap-2">
<span class="text-[11px] font-bold tracking-[0.12em] text-tif28-ink">USERNAME_</span>
<input type="text" name="tif28-user" placeholder="enter handle…" pattern="[a-z0-9_]{3,}" required
class="w-full rounded-none border-[2.5px] border-tif28-edge bg-tif28-paper px-3.5 py-3 text-[13px] font-bold tracking-[0.06em] text-tif28-edge shadow-[5px_5px_0_var(--color-tif28-acc)] outline-none transition-[transform,box-shadow] duration-100 placeholder:text-tif28-edge/50 focus:translate-x-0.5 focus:translate-y-0.5 focus:shadow-[3px_3px_0_var(--color-tif28-acc)] user-invalid:shadow-[5px_5px_0_var(--color-tif28-bad)] rtl:shadow-[-5px_5px_0_var(--color-tif28-acc)] rtl:focus:-translate-x-0.5 rtl:focus:shadow-[-3px_3px_0_var(--color-tif28-acc)] motion-reduce:transition-none">
<span class="text-[10px] tracking-[0.08em] text-tif28-ink/60">LOWERCASE_LETTERS_DIGITS_UNDERSCORE · MIN_3</span>
</label>
</div>@import "tailwindcss";
@theme {
--color-tif28-bg: #12121a;
--color-tif28-bg: oklch(0.19 0.015 285);
--color-tif28-paper: #f0eeff;
--color-tif28-paper: oklch(0.95 0.02 290);
--color-tif28-edge: #1a1a2e;
--color-tif28-edge: oklch(0.22 0.04 285);
--color-tif28-ink: #f0eeff;
--color-tif28-ink: oklch(0.95 0.02 290);
--color-tif28-acc: #ff6c8a;
--color-tif28-acc: oklch(0.72 0.17 15);
--color-tif28-bad: #ff5d6c;
--color-tif28-bad: oklch(0.69 0.19 20);
--font-tif28-mono: 'Space Mono', ui-monospace, monospace;
}
.tif-28 {
width: 100%;
}
.tif-28 ::selection {
background: var(--color-tif28-acc);
color: #1a1a2e;
}@import "tailwindcss";
@theme {
--color-tif28-bg: #12121a;
--color-tif28-bg: oklch(0.19 0.015 285);
--color-tif28-paper: #f0eeff;
--color-tif28-paper: oklch(0.95 0.02 290);
--color-tif28-edge: #1a1a2e;
--color-tif28-edge: oklch(0.22 0.04 285);
--color-tif28-ink: #f0eeff;
--color-tif28-ink: oklch(0.95 0.02 290);
--color-tif28-acc: #ff6c8a;
--color-tif28-acc: oklch(0.72 0.17 15);
--color-tif28-bad: #ff5d6c;
--color-tif28-bad: oklch(0.69 0.19 20);
--font-tif28-mono: 'Space Mono', ui-monospace, monospace;
}
.tif-28 {
width: 100%;
}
.tif-28 ::selection {
background: var(--color-tif28-acc);
color: #1a1a2e;
}Setup — do this once per project
Skip this if your project already runs Tailwind v4.
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>Compiles in the browser — perfect for a CodePen or a quick test, not for production.
npm install tailwindcss @tailwindcss/vite
npm install tailwindcss @tailwindcss/vite// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})// vite.config.js ("type": "module" in package.json)
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
export default defineConfig({
plugins: [tailwindcss()],
})Any v4 setup works — Vite, PostCSS or the CLI. Nothing in this demo is bundler-specific.
@import "tailwindcss";
@theme {
--color-tif28-bg: #12121a;
--color-tif28-bg: oklch(0.19 0.015 285);
--color-tif28-paper: #f0eeff;
--color-tif28-paper: oklch(0.95 0.02 290);
--color-tif28-edge: #1a1a2e;
--color-tif28-edge: oklch(0.22 0.04 285);
--color-tif28-ink: #f0eeff;
--color-tif28-ink: oklch(0.95 0.02 290);
--color-tif28-acc: #ff6c8a;
--color-tif28-acc: oklch(0.72 0.17 15);
--color-tif28-bad: #ff5d6c;
--color-tif28-bad: oklch(0.69 0.19 20);
--font-tif28-mono: 'Space Mono', ui-monospace, monospace;
}
.tif-28 {
width: 100%;
}
.tif-28 ::selection {
background: var(--color-tif28-acc);
color: #1a1a2e;
}@import "tailwindcss";
@theme {
--color-tif28-bg: #12121a;
--color-tif28-bg: oklch(0.19 0.015 285);
--color-tif28-paper: #f0eeff;
--color-tif28-paper: oklch(0.95 0.02 290);
--color-tif28-edge: #1a1a2e;
--color-tif28-edge: oklch(0.22 0.04 285);
--color-tif28-ink: #f0eeff;
--color-tif28-ink: oklch(0.95 0.02 290);
--color-tif28-acc: #ff6c8a;
--color-tif28-acc: oklch(0.72 0.17 15);
--color-tif28-bad: #ff5d6c;
--color-tif28-bad: oklch(0.69 0.19 20);
--font-tif28-mono: 'Space Mono', ui-monospace, monospace;
}
.tif-28 {
width: 100%;
}
.tif-28 ::selection {
background: var(--color-tif28-acc);
color: #1a1a2e;
}<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
- The RTL gotcha became an
rtl:variant trio — the port's recurring pattern: warnings in the CSS collection turn into utilities here. :invalid:not(:placeholder-shown)becomesuser-invalid:, and a realpatternwas added so the red stamp means something.- A hint line was added under the field: a validation state with no stated rule is a guessing game.
Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Brutalist Input
Source: https://codefronts.com/components/tailwind-css-input-fields/tailwind-brutalist-input/
A hard 2.5px border, zero radius and a flat offset shadow that the field presses into on focus. The whole aesthetic is four utilities, and the RTL flip the CSS original leaves as a gotcha is one rtl: variant here.
## HTML
```html
<div class="tif-28 grid min-h-svh w-full place-items-center bg-tif28-bg px-6 py-14 font-tif28-mono" aria-label="Brutalist input demo">
<label class="grid w-full max-w-70 gap-2">
<span class="text-[11px] font-bold tracking-[0.12em] text-tif28-ink">USERNAME_</span>
<input type="text" name="tif28-user" placeholder="enter handle…" pattern="[a-z0-9_]{3,}" required
class="w-full rounded-none border-[2.5px] border-tif28-edge bg-tif28-paper px-3.5 py-3 text-[13px] font-bold tracking-[0.06em] text-tif28-edge shadow-[5px_5px_0_var(--color-tif28-acc)] outline-none transition-[transform,box-shadow] duration-100 placeholder:text-tif28-edge/50 focus:translate-x-0.5 focus:translate-y-0.5 focus:shadow-[3px_3px_0_var(--color-tif28-acc)] user-invalid:shadow-[5px_5px_0_var(--color-tif28-bad)] rtl:shadow-[-5px_5px_0_var(--color-tif28-acc)] rtl:focus:-translate-x-0.5 rtl:focus:shadow-[-3px_3px_0_var(--color-tif28-acc)] motion-reduce:transition-none">
<span class="text-[10px] tracking-[0.08em] text-tif28-ink/60">LOWERCASE_LETTERS_DIGITS_UNDERSCORE · MIN_3</span>
</label>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tif28-bg: #12121a;
--color-tif28-bg: oklch(0.19 0.015 285);
--color-tif28-paper: #f0eeff;
--color-tif28-paper: oklch(0.95 0.02 290);
--color-tif28-edge: #1a1a2e;
--color-tif28-edge: oklch(0.22 0.04 285);
--color-tif28-ink: #f0eeff;
--color-tif28-ink: oklch(0.95 0.02 290);
--color-tif28-acc: #ff6c8a;
--color-tif28-acc: oklch(0.72 0.17 15);
--color-tif28-bad: #ff5d6c;
--color-tif28-bad: oklch(0.69 0.19 20);
--font-tif28-mono: 'Space Mono', ui-monospace, monospace;
}
.tif-28 {
width: 100%;
}
.tif-28 ::selection {
background: var(--color-tif28-acc);
color: #1a1a2e;
}
```Here's a working CSS demo from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Tailwind Brutalist Input
Source: https://codefronts.com/components/tailwind-css-input-fields/tailwind-brutalist-input/
A hard 2.5px border, zero radius and a flat offset shadow that the field presses into on focus. The whole aesthetic is four utilities, and the RTL flip the CSS original leaves as a gotcha is one rtl: variant here.
## HTML
```html
<div class="tif-28 grid min-h-svh w-full place-items-center bg-tif28-bg px-6 py-14 font-tif28-mono" aria-label="Brutalist input demo">
<label class="grid w-full max-w-70 gap-2">
<span class="text-[11px] font-bold tracking-[0.12em] text-tif28-ink">USERNAME_</span>
<input type="text" name="tif28-user" placeholder="enter handle…" pattern="[a-z0-9_]{3,}" required
class="w-full rounded-none border-[2.5px] border-tif28-edge bg-tif28-paper px-3.5 py-3 text-[13px] font-bold tracking-[0.06em] text-tif28-edge shadow-[5px_5px_0_var(--color-tif28-acc)] outline-none transition-[transform,box-shadow] duration-100 placeholder:text-tif28-edge/50 focus:translate-x-0.5 focus:translate-y-0.5 focus:shadow-[3px_3px_0_var(--color-tif28-acc)] user-invalid:shadow-[5px_5px_0_var(--color-tif28-bad)] rtl:shadow-[-5px_5px_0_var(--color-tif28-acc)] rtl:focus:-translate-x-0.5 rtl:focus:shadow-[-3px_3px_0_var(--color-tif28-acc)] motion-reduce:transition-none">
<span class="text-[10px] tracking-[0.08em] text-tif28-ink/60">LOWERCASE_LETTERS_DIGITS_UNDERSCORE · MIN_3</span>
</label>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tif28-bg: #12121a;
--color-tif28-bg: oklch(0.19 0.015 285);
--color-tif28-paper: #f0eeff;
--color-tif28-paper: oklch(0.95 0.02 290);
--color-tif28-edge: #1a1a2e;
--color-tif28-edge: oklch(0.22 0.04 285);
--color-tif28-ink: #f0eeff;
--color-tif28-ink: oklch(0.95 0.02 290);
--color-tif28-acc: #ff6c8a;
--color-tif28-acc: oklch(0.72 0.17 15);
--color-tif28-bad: #ff5d6c;
--color-tif28-bad: oklch(0.69 0.19 20);
--font-tif28-mono: 'Space Mono', ui-monospace, monospace;
}
.tif-28 {
width: 100%;
}
.tif-28 ::selection {
background: var(--color-tif28-acc);
color: #1a1a2e;
}
```How this works
Press into the shadow. Focus moves the field two pixels toward its own drop and shrinks the drop by the same amount, so the stamp appears to depress:
class="shadow-[5px_5px_0_var(--color-tif28-acc)]
focus:translate-x-0.5 focus:translate-y-0.5
focus:shadow-[3px_3px_0_var(--color-tif28-acc)]"Zero blur is the point. A hard offset shadow reads as a second flat rectangle, not as depth — which is the whole neo-brutalist grammar, and why any blur radius above 0 breaks it.
Make it yours
- Accent: one bright colour against black. Pink, lime and cyan all work; two accents do not.
- Weight:
8px 8px 0for a chunkier stamp,3px 3px 0for restraint — change the focus value by the same delta. - Type: any monospace. Space Mono and JetBrains Mono both read more modern than Courier.
- Validation: add
patternand the red stamp fires on a real rule.
Gotchas — read before shipping
- RTL flips the light source. The
rtl:variant is not optional if you ship Arabic or Hebrew. - 2.5px borders with zero radius look ragged on 1x displays. Check on a non-retina monitor.
user-invalidrather thaninvalidis what stops the red stamp appearing before the user has typed anything.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 119+ | 16.5+ | 128+ | 119+ |
:user-invalid sets the floor; below it the field simply never turns red, which is a safe fallback.