Tag Input
Type a tag and press Enter or comma to commit it as a chip. Backspace on an empty input removes the last chip — a polished pattern for filters and email recipients.
Tag Input the 12th of 28 designs in the 28 CSS Input Field Designs collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<label class="if-tag">
<span class="if-tag-label">Tags</span>
<span class="if-tag-wrap" data-if-tags>
<span class="if-tag-list"></span>
<input type="text" placeholder="Add a tag…" aria-label="Tags" />
</span>
<span class="if-tag-help">Press <kbd>Enter</kbd> or <kbd>,</kbd> to add</span>
</label> .if-tag {
display: grid;
gap: 6px;
width: 100%;
max-width: 280px;
font-size: 11px;
color: #b8b6d4;
}
.if-tag-label {
font-weight: 600;
}
.if-tag-wrap {
display: flex;
flex-wrap: wrap;
gap: 6px;
background: #1a1a22;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
padding: 8px 10px;
align-items: center;
transition:
border-color 0.2s,
box-shadow 0.2s;
}
.if-tag-wrap:focus-within {
border-color: #fb923c;
box-shadow: 0 0 0 3px rgba(251, 146, 60, 0.15);
}
.if-tag-list {
display: contents;
}
.if-tag-chip {
display: inline-flex;
align-items: center;
gap: 5px;
background: rgba(251, 146, 60, 0.12);
border: 1px solid rgba(251, 146, 60, 0.35);
color: #fdba74;
font-size: 12px;
padding: 2px 8px;
border-radius: 99px;
font-weight: 500;
}
.if-tag-chip button {
background: transparent;
border: 0;
padding: 0;
color: inherit;
cursor: pointer;
font-size: 12px;
line-height: 1;
opacity: 0.7;
}
.if-tag-chip button:hover {
opacity: 1;
}
.if-tag input {
flex: 1;
min-width: 80px;
background: transparent;
border: 0;
outline: none;
color: #f0eeff;
font-size: 14px;
padding: 2px 0;
}
.if-tag input::placeholder {
color: #b8b6d4;
}
.if-tag-help {
font-size: 10.5px;
color: #b8b6d4;
}
.if-tag-help kbd {
display: inline-block;
background: #2a2a36;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 4px;
padding: 0 4px;
font-family: "JetBrains Mono", monospace;
font-size: 10px;
} // Tag input — Enter/comma commits a chip, Backspace removes the last
document.querySelectorAll("[data-if-tags]").forEach(function (wrap) {
var input = wrap.querySelector("input");
var list = wrap.querySelector(".if-tag-list");
if (!input || !list) return;
function addChip(value) {
value = (value || "").trim();
if (!value) return;
var chip = document.createElement("span");
chip.className = "if-tag-chip";
chip.textContent = value + " ";
var x = document.createElement("button");
x.type = "button";
x.setAttribute("aria-label", "Remove tag " + value);
x.textContent = "×";
x.addEventListener("click", function () {
chip.remove();
});
chip.appendChild(x);
list.appendChild(chip);
}
input.addEventListener("keydown", function (e) {
if (e.key === "Enter" || e.key === ",") {
e.preventDefault();
addChip(input.value);
input.value = "";
} else if (e.key === "Backspace" && !input.value) {
var last = list.querySelector(".if-tag-chip:last-child");
if (last) last.remove();
}
});
});