23 / 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 Inline Edit Field
Click-to-edit text that swaps a display span for an input, saves on Enter or blur and cancels on Escape. The editing state is a data-editing attribute on the wrapper, so the border, background and pencil all read it as a variant.
Untitled UI Pro: 5,000+ React + Tailwind CSS v4 components · from $349 one-time
Untitled UI React · Affiliate link
The code
<div class="tif-23 grid min-h-svh w-full place-items-center bg-tif23-bg px-6 py-14 font-tif23-sans" aria-label="Inline edit field demo">
<div class="grid w-full max-w-70 gap-1.5">
<span class="font-tif23-mono text-[10px] tracking-[0.12em] text-tif23-mut uppercase" id="tif23-cap">Project name</span>
<span data-tif23 data-value="Aurora Dashboard"
class="group flex cursor-text items-center gap-1.5 rounded-lg border border-dashed border-transparent bg-transparent px-3 py-2 transition-[background-color,border-color] duration-150 hover:border-tif23-acc/20 hover:bg-tif23-acc/6 focus-within:border-tif23-acc/40 data-editing:border-solid data-editing:border-tif23-acc data-editing:bg-tif23-field">
<span data-tif23-display tabindex="0" role="button" aria-labelledby="tif23-cap" aria-label="Edit project name"
class="min-w-0 flex-1 text-sm font-semibold text-tif23-ink outline-none">Aurora Dashboard</span>
<input data-tif23-input type="text" value="Aurora Dashboard" hidden aria-label="Project name"
class="min-w-0 flex-1 border-0 bg-transparent p-0 text-sm font-semibold text-tif23-ink outline-none">
<span aria-hidden="true" class="text-xs text-tif23-dim opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100 group-data-editing:hidden">✎</span>
</span>
</div>
</div><div class="tif-23 grid min-h-svh w-full place-items-center bg-tif23-bg px-6 py-14 font-tif23-sans" aria-label="Inline edit field demo">
<div class="grid w-full max-w-70 gap-1.5">
<span class="font-tif23-mono text-[10px] tracking-[0.12em] text-tif23-mut uppercase" id="tif23-cap">Project name</span>
<span data-tif23 data-value="Aurora Dashboard"
class="group flex cursor-text items-center gap-1.5 rounded-lg border border-dashed border-transparent bg-transparent px-3 py-2 transition-[background-color,border-color] duration-150 hover:border-tif23-acc/20 hover:bg-tif23-acc/6 focus-within:border-tif23-acc/40 data-editing:border-solid data-editing:border-tif23-acc data-editing:bg-tif23-field">
<span data-tif23-display tabindex="0" role="button" aria-labelledby="tif23-cap" aria-label="Edit project name"
class="min-w-0 flex-1 text-sm font-semibold text-tif23-ink outline-none">Aurora Dashboard</span>
<input data-tif23-input type="text" value="Aurora Dashboard" hidden aria-label="Project name"
class="min-w-0 flex-1 border-0 bg-transparent p-0 text-sm font-semibold text-tif23-ink outline-none">
<span aria-hidden="true" class="text-xs text-tif23-dim opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100 group-data-editing:hidden">✎</span>
</span>
</div>
</div>@import "tailwindcss";
@theme {
--color-tif23-bg: #12121a;
--color-tif23-bg: oklch(0.19 0.015 285);
--color-tif23-field: #1a1a22;
--color-tif23-field: oklch(0.23 0.015 285);
--color-tif23-ink: #f0eeff;
--color-tif23-ink: oklch(0.95 0.02 290);
--color-tif23-mut: #b8b6d4;
--color-tif23-mut: oklch(0.77 0.03 290);
--color-tif23-dim: #7a7899;
--color-tif23-dim: oklch(0.6 0.04 292);
--color-tif23-acc: #7c6cff;
--color-tif23-acc: oklch(0.62 0.2 288);
--font-tif23-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tif23-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tif-23 {
width: 100%;
}
.tif-23 ::selection {
background: var(--color-tif23-acc);
color: #12121a;
}@import "tailwindcss";
@theme {
--color-tif23-bg: #12121a;
--color-tif23-bg: oklch(0.19 0.015 285);
--color-tif23-field: #1a1a22;
--color-tif23-field: oklch(0.23 0.015 285);
--color-tif23-ink: #f0eeff;
--color-tif23-ink: oklch(0.95 0.02 290);
--color-tif23-mut: #b8b6d4;
--color-tif23-mut: oklch(0.77 0.03 290);
--color-tif23-dim: #7a7899;
--color-tif23-dim: oklch(0.6 0.04 292);
--color-tif23-acc: #7c6cff;
--color-tif23-acc: oklch(0.62 0.2 288);
--font-tif23-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tif23-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tif-23 {
width: 100%;
}
.tif-23 ::selection {
background: var(--color-tif23-acc);
color: #12121a;
}(function () {
document.querySelectorAll('.tif-23').forEach(function (root) {
if (root.dataset.bound) return; root.dataset.bound = '1';
root.querySelectorAll('[data-tif23]').forEach(function (wrap) {
var display = wrap.querySelector('[data-tif23-display]');
var input = wrap.querySelector('[data-tif23-input]');
if (!display || !input) return;
function enter() {
wrap.dataset.editing = '';
display.hidden = true;
input.hidden = false;
input.value = wrap.dataset.value || display.textContent;
input.focus();
input.select();
}
function exit() {
delete wrap.dataset.editing;
input.hidden = true;
display.hidden = false;
}
function commit() {
var v = input.value.trim();
if (v) {
display.textContent = v;
wrap.dataset.value = v;
wrap.dispatchEvent(new CustomEvent('inline-edit:change', { detail: v, bubbles: true }));
}
exit();
}
function cancel() {
input.value = wrap.dataset.value || display.textContent;
exit();
display.focus();
}
display.addEventListener('click', enter);
display.addEventListener('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); enter(); }
});
input.addEventListener('blur', commit);
input.addEventListener('keydown', function (e) {
if (e.key === 'Enter') { e.preventDefault(); commit(); }
if (e.key === 'Escape') { e.preventDefault(); cancel(); }
});
});
});
})();(function () {
document.querySelectorAll('.tif-23').forEach(function (root) {
if (root.dataset.bound) return; root.dataset.bound = '1';
root.querySelectorAll('[data-tif23]').forEach(function (wrap) {
var display = wrap.querySelector('[data-tif23-display]');
var input = wrap.querySelector('[data-tif23-input]');
if (!display || !input) return;
function enter() {
wrap.dataset.editing = '';
display.hidden = true;
input.hidden = false;
input.value = wrap.dataset.value || display.textContent;
input.focus();
input.select();
}
function exit() {
delete wrap.dataset.editing;
input.hidden = true;
display.hidden = false;
}
function commit() {
var v = input.value.trim();
if (v) {
display.textContent = v;
wrap.dataset.value = v;
wrap.dispatchEvent(new CustomEvent('inline-edit:change', { detail: v, bubbles: true }));
}
exit();
}
function cancel() {
input.value = wrap.dataset.value || display.textContent;
exit();
display.focus();
}
display.addEventListener('click', enter);
display.addEventListener('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); enter(); }
});
input.addEventListener('blur', commit);
input.addEventListener('keydown', function (e) {
if (e.key === 'Enter') { e.preventDefault(); commit(); }
if (e.key === 'Escape') { e.preventDefault(); cancel(); }
});
});
});
})();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-tif23-bg: #12121a;
--color-tif23-bg: oklch(0.19 0.015 285);
--color-tif23-field: #1a1a22;
--color-tif23-field: oklch(0.23 0.015 285);
--color-tif23-ink: #f0eeff;
--color-tif23-ink: oklch(0.95 0.02 290);
--color-tif23-mut: #b8b6d4;
--color-tif23-mut: oklch(0.77 0.03 290);
--color-tif23-dim: #7a7899;
--color-tif23-dim: oklch(0.6 0.04 292);
--color-tif23-acc: #7c6cff;
--color-tif23-acc: oklch(0.62 0.2 288);
--font-tif23-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tif23-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tif-23 {
width: 100%;
}
.tif-23 ::selection {
background: var(--color-tif23-acc);
color: #12121a;
}@import "tailwindcss";
@theme {
--color-tif23-bg: #12121a;
--color-tif23-bg: oklch(0.19 0.015 285);
--color-tif23-field: #1a1a22;
--color-tif23-field: oklch(0.23 0.015 285);
--color-tif23-ink: #f0eeff;
--color-tif23-ink: oklch(0.95 0.02 290);
--color-tif23-mut: #b8b6d4;
--color-tif23-mut: oklch(0.77 0.03 290);
--color-tif23-dim: #7a7899;
--color-tif23-dim: oklch(0.6 0.04 292);
--color-tif23-acc: #7c6cff;
--color-tif23-acc: oklch(0.62 0.2 288);
--font-tif23-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tif23-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tif-23 {
width: 100%;
}
.tif-23 ::selection {
background: var(--color-tif23-acc);
color: #12121a;
}<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=JetBrains+Mono:wght@400;500;700&family=Plus+Jakarta+Sans:wght@400;500;600&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=JetBrains+Mono:wght@400;500;700&family=Plus+Jakarta+Sans:wght@400;500;600&display=swap">What changed in the port
Which parts became utilities, which stayed CSS, and why.
classList.add('is-editing')becomesdataset.editing, read bydata-editing:andgroup-data-editing:— the script stops knowing anything about appearance.- Escape now returns focus to the display element; the original left focus nowhere, which strands keyboard users mid-list.
- An
inline-edit:changeevent was added so a store can persist the value — the original wrote to a data attribute and told nobody.
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 Inline Edit Field
Source: https://codefronts.com/components/tailwind-css-input-fields/tailwind-inline-edit-field/
Click-to-edit text that swaps a display span for an input, saves on Enter or blur and cancels on Escape. The editing state is a data-editing attribute on the wrapper, so the border, background and pencil all read it as a variant.
## HTML
```html
<div class="tif-23 grid min-h-svh w-full place-items-center bg-tif23-bg px-6 py-14 font-tif23-sans" aria-label="Inline edit field demo">
<div class="grid w-full max-w-70 gap-1.5">
<span class="font-tif23-mono text-[10px] tracking-[0.12em] text-tif23-mut uppercase" id="tif23-cap">Project name</span>
<span data-tif23 data-value="Aurora Dashboard"
class="group flex cursor-text items-center gap-1.5 rounded-lg border border-dashed border-transparent bg-transparent px-3 py-2 transition-[background-color,border-color] duration-150 hover:border-tif23-acc/20 hover:bg-tif23-acc/6 focus-within:border-tif23-acc/40 data-editing:border-solid data-editing:border-tif23-acc data-editing:bg-tif23-field">
<span data-tif23-display tabindex="0" role="button" aria-labelledby="tif23-cap" aria-label="Edit project name"
class="min-w-0 flex-1 text-sm font-semibold text-tif23-ink outline-none">Aurora Dashboard</span>
<input data-tif23-input type="text" value="Aurora Dashboard" hidden aria-label="Project name"
class="min-w-0 flex-1 border-0 bg-transparent p-0 text-sm font-semibold text-tif23-ink outline-none">
<span aria-hidden="true" class="text-xs text-tif23-dim opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100 group-data-editing:hidden">✎</span>
</span>
</div>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tif23-bg: #12121a;
--color-tif23-bg: oklch(0.19 0.015 285);
--color-tif23-field: #1a1a22;
--color-tif23-field: oklch(0.23 0.015 285);
--color-tif23-ink: #f0eeff;
--color-tif23-ink: oklch(0.95 0.02 290);
--color-tif23-mut: #b8b6d4;
--color-tif23-mut: oklch(0.77 0.03 290);
--color-tif23-dim: #7a7899;
--color-tif23-dim: oklch(0.6 0.04 292);
--color-tif23-acc: #7c6cff;
--color-tif23-acc: oklch(0.62 0.2 288);
--font-tif23-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tif23-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tif-23 {
width: 100%;
}
.tif-23 ::selection {
background: var(--color-tif23-acc);
color: #12121a;
}
```
## JavaScript
```js
(function () {
document.querySelectorAll('.tif-23').forEach(function (root) {
if (root.dataset.bound) return; root.dataset.bound = '1';
root.querySelectorAll('[data-tif23]').forEach(function (wrap) {
var display = wrap.querySelector('[data-tif23-display]');
var input = wrap.querySelector('[data-tif23-input]');
if (!display || !input) return;
function enter() {
wrap.dataset.editing = '';
display.hidden = true;
input.hidden = false;
input.value = wrap.dataset.value || display.textContent;
input.focus();
input.select();
}
function exit() {
delete wrap.dataset.editing;
input.hidden = true;
display.hidden = false;
}
function commit() {
var v = input.value.trim();
if (v) {
display.textContent = v;
wrap.dataset.value = v;
wrap.dispatchEvent(new CustomEvent('inline-edit:change', { detail: v, bubbles: true }));
}
exit();
}
function cancel() {
input.value = wrap.dataset.value || display.textContent;
exit();
display.focus();
}
display.addEventListener('click', enter);
display.addEventListener('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); enter(); }
});
input.addEventListener('blur', commit);
input.addEventListener('keydown', function (e) {
if (e.key === 'Enter') { e.preventDefault(); commit(); }
if (e.key === 'Escape') { e.preventDefault(); cancel(); }
});
});
});
})();
```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 Inline Edit Field
Source: https://codefronts.com/components/tailwind-css-input-fields/tailwind-inline-edit-field/
Click-to-edit text that swaps a display span for an input, saves on Enter or blur and cancels on Escape. The editing state is a data-editing attribute on the wrapper, so the border, background and pencil all read it as a variant.
## HTML
```html
<div class="tif-23 grid min-h-svh w-full place-items-center bg-tif23-bg px-6 py-14 font-tif23-sans" aria-label="Inline edit field demo">
<div class="grid w-full max-w-70 gap-1.5">
<span class="font-tif23-mono text-[10px] tracking-[0.12em] text-tif23-mut uppercase" id="tif23-cap">Project name</span>
<span data-tif23 data-value="Aurora Dashboard"
class="group flex cursor-text items-center gap-1.5 rounded-lg border border-dashed border-transparent bg-transparent px-3 py-2 transition-[background-color,border-color] duration-150 hover:border-tif23-acc/20 hover:bg-tif23-acc/6 focus-within:border-tif23-acc/40 data-editing:border-solid data-editing:border-tif23-acc data-editing:bg-tif23-field">
<span data-tif23-display tabindex="0" role="button" aria-labelledby="tif23-cap" aria-label="Edit project name"
class="min-w-0 flex-1 text-sm font-semibold text-tif23-ink outline-none">Aurora Dashboard</span>
<input data-tif23-input type="text" value="Aurora Dashboard" hidden aria-label="Project name"
class="min-w-0 flex-1 border-0 bg-transparent p-0 text-sm font-semibold text-tif23-ink outline-none">
<span aria-hidden="true" class="text-xs text-tif23-dim opacity-0 transition-opacity duration-150 group-hover:opacity-100 group-focus-within:opacity-100 group-data-editing:hidden">✎</span>
</span>
</div>
</div>
```
## CSS
```css
@import "tailwindcss";
@theme {
--color-tif23-bg: #12121a;
--color-tif23-bg: oklch(0.19 0.015 285);
--color-tif23-field: #1a1a22;
--color-tif23-field: oklch(0.23 0.015 285);
--color-tif23-ink: #f0eeff;
--color-tif23-ink: oklch(0.95 0.02 290);
--color-tif23-mut: #b8b6d4;
--color-tif23-mut: oklch(0.77 0.03 290);
--color-tif23-dim: #7a7899;
--color-tif23-dim: oklch(0.6 0.04 292);
--color-tif23-acc: #7c6cff;
--color-tif23-acc: oklch(0.62 0.2 288);
--font-tif23-sans: 'Plus Jakarta Sans', system-ui, sans-serif;
--font-tif23-mono: 'JetBrains Mono', ui-monospace, monospace;
}
.tif-23 {
width: 100%;
}
.tif-23 ::selection {
background: var(--color-tif23-acc);
color: #12121a;
}
```
## JavaScript
```js
(function () {
document.querySelectorAll('.tif-23').forEach(function (root) {
if (root.dataset.bound) return; root.dataset.bound = '1';
root.querySelectorAll('[data-tif23]').forEach(function (wrap) {
var display = wrap.querySelector('[data-tif23-display]');
var input = wrap.querySelector('[data-tif23-input]');
if (!display || !input) return;
function enter() {
wrap.dataset.editing = '';
display.hidden = true;
input.hidden = false;
input.value = wrap.dataset.value || display.textContent;
input.focus();
input.select();
}
function exit() {
delete wrap.dataset.editing;
input.hidden = true;
display.hidden = false;
}
function commit() {
var v = input.value.trim();
if (v) {
display.textContent = v;
wrap.dataset.value = v;
wrap.dispatchEvent(new CustomEvent('inline-edit:change', { detail: v, bubbles: true }));
}
exit();
}
function cancel() {
input.value = wrap.dataset.value || display.textContent;
exit();
display.focus();
}
display.addEventListener('click', enter);
display.addEventListener('keydown', function (e) {
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); enter(); }
});
input.addEventListener('blur', commit);
input.addEventListener('keydown', function (e) {
if (e.key === 'Enter') { e.preventDefault(); commit(); }
if (e.key === 'Escape') { e.preventDefault(); cancel(); }
});
});
});
})();
```How this works
Two children, one visible at a time. Entering edit mode hides the display, shows the input, focuses and selects it, and sets the flag the styling reads:
wrap.dataset.editing = '';
display.hidden = true;
input.hidden = false;
input.select();Enter commits, Escape reverts, blur commits. That exact trio is what Notion, Linear, Asana and Airtable all use for a title field, and users have learned it — deviating from it is the one customisation not worth making.
Make it yours
- Icon: the pencil glyph is plain text; drop in an SVG and keep
aria-hidden. - Validation: reject commits below a minimum length before writing back.
- Persistence: the wrapper dispatches
inline-edit:changeon commit — listen for it. - Accent:
--color-tif23-accdrives hover tint, editing border and focus ring.
Gotchas — read before shipping
- If you switch the display to
contenteditable, a Word paste brings rich text with it — strip formatting in a paste handler. - The empty-value branch reverts silently. If your product needs a visible rejection, add one.
- Without
role="button"on the display, the click-to-edit affordance simply does not exist for assistive tech.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.4+ | 128+ | 111+ |
Plain focus/blur/keydown plus a hidden input; the floor is Tailwind v4's sheet.