Release candidate (RC)
This component is in the Release Candidate phase and its API is considered stable. Minor adjustments may still occur before the final release.
Bootstrap 5 Chip Input
Chip input
Bootstrap Chip Input component for CoreUI — create tag-like multi-value inputs for skills, categories, or recipients with keyboard support, selection, and form integration.
🤖 Looking for the LLM-optimized version? View llm.md
Available in Other JavaScript Frameworks
CoreUI Chip input components are available as native React, and Vue components. Explore framework-specific implementations below:
Overview
The CoreUI Bootstrap Chip Input component lets users enter multiple values as chips inside a single field. Use it as a tag input, multi-value selector, or token field for skills, categories, email recipients, and more. The chip input component supports keyboard-friendly entry, chip removal, and optional selection for bulk actions.
- Type values and press
Enter(or a separator) to create chips. - Chips can be removable and selectable.
- The input stays inline and grows as you type.
- Full form integration via a hidden input with configurable
name.
The chip input is built on top of the Chip set component, so it inherits the same roving focus and keyboard navigation between chips. Its public API and events are unchanged.
When to use Chip Input
Use the Bootstrap Chip Input component when you need:
- A tag input or token field for free-form multi-value entry
- An email or recipient input where users add multiple addresses
- A skills or category selector in forms
- A filterable multi-select that integrates with standard HTML forms
Basic example
Wrap chips and add data-coreui-chip-input to enable behavior.
<div class="chip-input" data-coreui-chip-input data-coreui-name="chipInputBasicExample" data-coreui-placeholder="Add a skill...">
<label class="chip-input-label" for="skillsInputBasic">Skills:</label>
<span class="chip">JavaScript</span>
<span class="chip">TypeScript</span>
<span class="chip">Accessibility</span>
</div><input class="chip-input-field"> is created automatically by the component when initialized. You can also add it manually in the markup if preferred. Additionally, a hidden input is generated automatically to submit chip values with the form. The name attribute of this hidden input is taken from the data-coreui-name attribute (e.g., data-coreui-name="chipInputBasicExample").
<div class="chip-input" data-coreui-chip-input data-coreui-placeholder="Add a skill...">
<label class="chip-input-label" for="skillsInputBasic">Skills:</label>
<span class="chip">JavaScript</span>
<span class="chip">TypeScript</span>
<span class="chip">Accessibility</span>
<input type="text" class="chip-input-field" name="skillsInputBasic" placeholder="Add a skill...">
</div>
Variants
Use contextual chip classes inside Bootstrap 5 Chip Input to represent categories, status, or priority.
<div class="chip-input" data-coreui-chip-input data-coreui-name="issues" data-coreui-placeholder="Add label...">
<span class="chip chip-primary">Feature</span>
<span class="chip chip-success">Approved</span>
<span class="chip chip-warning">Needs review</span>
<span class="chip chip-danger">Blocking</span>
</div>In the example below, the chip color is assigned dynamically based on the chip text using the chipClassName callback. Each value (e.g., Feature or Blocking) maps to a contextual class, so chips remain visually consistent even when added programmatically.
<div id="chipVariants" class="chip-input"></div>The JavaScript below initializes the example:
const chipInputElement = document.querySelector('#chipVariants')
const chipInput = new coreui.ChipInput(chipInputElement, {
// Class is resolved dynamically from chip value.
chipClassName(value) {
const variants = {
approved: 'chip-success',
blocking: 'chip-danger',
feature: 'chip-primary',
'needs review': 'chip-warning'
}
return variants[value.trim().toLowerCase()] || 'chip-secondary'
},
placeholder: 'Add a bug...'
})
chipInput.add('Feature')
Sizes
Use chip-input-sm and chip-input-lg to match surrounding form controls. Default size is provided by .chip-input without a size modifier.
<div class="chip-input chip-input-sm mb-3" data-coreui-chip-input data-coreui-placeholder="Add small tag...">
<label class="chip-input-label" for="skillsInputSm">Small</label>
<span class="chip">HTML</span>
</div>
<div class="chip-input mb-3" data-coreui-chip-input data-coreui-placeholder="Add default tag...">
<label class="chip-input-label" for="skillsInputMd">Default</label>
<span class="chip">JavaScript</span>
</div>
<div class="chip-input chip-input-lg" data-coreui-chip-input data-coreui-placeholder="Add large tag...">
<label class="chip-input-label" for="skillsInputLg">Large</label>
<span class="chip">TypeScript</span>
</div>Empty state
Start with just the input and let users add chips as they type.
<div class="chip-input" data-coreui-chip-input data-coreui-name="tags" data-coreui-placeholder="Start typing tags..."></div>With label
Use a standard form label for accessibility.
<div class="mb-3">
<label class="form-label" for="techStackInput">Tech stack</label>
<div class="chip-input" data-coreui-chip-input data-coreui-name="techStack" data-coreui-placeholder="Add package...">
<span class="chip">Vue</span>
<span class="chip">Vite</span>
</div>
<div class="form-text">Press Enter or comma to add a value.</div>
</div>Disabled
Set disabled state on the component to make the input and managed chips non-interactive.
You can use either the disabled class or the data-coreui-disabled="true" option.
For disabled, non-removable chips, combine it with data-coreui-removable="false".
<div class="chip-input" data-coreui-chip-input data-coreui-disabled="true" data-coreui-removable="false" data-coreui-placeholder="Input disabled">
<span class="chip">Read only</span>
<span class="chip">Locked</span>
</div>Readonly
Use readonly state when chips should stay visible and focusable, but values must not change.
Set data-coreui-readonly="true" (or readonly: true in JavaScript) to block adding and removing chips.
<div class="chip-input" data-coreui-chip-input data-coreui-readonly="true" data-coreui-placeholder="Read-only values">
<span class="chip">JavaScript</span>
<span class="chip">TypeScript</span>
</div>Selectable chips
Enable selection for chips managed by Chip Input.
In this example, select.coreui.chip-input updates a live list of selected values below the field.
Selected chips: None
<div id="chipSelectable" class="chip-input">
<span class="chip">Design</span>
<span class="chip">Backend</span>
<span class="chip active">QA</span>
<span class="chip active">DevOps</span>
</div>
<p class="form-text mt-2 mb-0">Selected chips: <span id="chipSelectableOutput">None</span></p>const chipSelectableElement = document.querySelector('#chipSelectable')
const chipSelectableOutput = document.querySelector('#chipSelectableOutput')
const chipSelectable = new coreui.ChipInput(chipSelectableElement, {
placeholder: 'Add team role...',
selectable: true
})
const updateSelectedOutput = selected => {
chipSelectableOutput.textContent = selected.length > 0 ? selected.join(', ') : 'None'
}
chipSelectableElement.addEventListener('select.coreui.chip-input', event => {
updateSelectedOutput(event.selected)
})
chipSelectable.add('Frontend')
chipSelectable.add('Security')
updateSelectedOutput(chipSelectable.getSelectedValues())
Usage
Initialize the Bootstrap Chip Input component via data attributes or JavaScript. The chip input component automatically creates a hidden form input to submit all chip values with the form.
Via data attributes
Add data-coreui-chip-input to initialize the chip input component. Options can be passed as data-coreui-* attributes.
<div class="chip-input" data-coreui-chip-input data-coreui-name="skills" data-coreui-placeholder="Add tags..." data-coreui-separator=","></div>
When initialized, Chip Input creates a hidden input to submit values with the form.
Use name (or data-coreui-name) to control the submitted field name.
Via JavaScript
const chipInputElement = document.querySelector('.chip-input')
const chipInput = coreui.ChipInput.getOrCreateInstance(chipInputElement, {
separator: ',',
maxChips: 5
})
Options
Options can be passed using data attributes or JavaScript. To do this, append an option name to data-coreui-, such as data-coreui-animation="{value}". Remember to convert the case of the option name from “camelCase” to “kebab-case” when using data attributes. For instance, you should write data-coreui-custom-class="beautifier" rather than data-coreui-customClass="beautifier".
Starting with CoreUI 4.2.0, all components support an experimental reserved data attribute named data-coreui-config, which can contain simple component configurations as a JSON string. If an element has attributes data-coreui-config='{"delay":50, "title":689}' and data-coreui-title="Custom Title", then the final value for title will be Custom Title, as the standard data attributes will take precedence over values specified in data-coreui-config. Moreover, existing data attributes can also hold JSON values like data-coreui-delay='{"show":50, "hide":250}'.
| Option | Type | Default | Description |
|---|---|---|---|
chipClassName |
string | function | null | null |
Adds classes to chips. Use a string for all chips or a function (value) => className for per-chip styling. |
disabled |
boolean | false |
Disables the input and marks managed chips as non-interactive. |
readonly |
boolean | false |
Prevents adding and removing chips while keeping input focus behavior. |
id |
string | null | auto-generated | Custom id for the generated hidden input. |
name |
string | null | auto-generated | Name for the generated hidden input used in form submission. |
separator |
string | null | ',' |
Character that triggers chip creation when typed. Set to null to disable. |
maxChips |
number | null | null |
Maximum number of chips allowed. null for unlimited. |
placeholder |
string | '' |
Placeholder text for dynamically created inputs. |
selectable |
boolean | false |
Enables selection behavior for chips managed by Chip Input. |
removable |
boolean | true |
Add remove buttons to created chips. |
removeIcon |
string | SVG | HTML string for the remove button icon. |
createOnBlur |
boolean | true |
Create a chip from the input value when the input loses focus. |
Methods
| Method | Description |
|---|---|
add(value) |
Adds a chip with the given value. Returns the chip element or null if rejected. |
remove(chipOrValue) |
Removes a chip by element reference or value string. Returns true if removed. |
removeSelected() |
Removes all currently selected chips. |
getValues() |
Returns an array of all chip values. |
getSelectedValues() |
Returns an array of selected chip values. |
clear() |
Removes all chips. |
clearSelection() |
Deselects all chips without removing them. |
selectChip(chip) |
Selects a specific chip element. |
focus() |
Focuses the ghost input. |
dispose() |
Destroys the component instance. |
const chipInputElement = document.querySelector('.chip-input')
const chipInput = coreui.ChipInput.getOrCreateInstance(chipInputElement)
chipInput.add('JavaScript')
chipInput.add('TypeScript')
// eslint-disable-next-line no-console
console.log(chipInput.getValues())
chipInput.remove('JavaScript')
chipInput.clear()
Events
| Event | Description |
|---|---|
input.coreui.chip-input |
Fired when the inline input value changes. Contains value and relatedTarget. |
add.coreui.chip-input |
Fired before a chip is added. Call event.preventDefault() to cancel. |
remove.coreui.chip-input |
Fired before a chip is removed. Call event.preventDefault() to cancel. |
change.coreui.chip-input |
Fired after any chip is added or removed. Contains values. |
select.coreui.chip-input |
Fired when chip selection changes. Contains selected. |
const chipInputElement = document.querySelector('.chip-input')
chipInputElement.addEventListener('add.coreui.chip-input', event => {
if (event.value.length < 2) {
event.preventDefault()
}
})
chipInputElement.addEventListener('input.coreui.chip-input', event => {
// eslint-disable-next-line no-console
console.log('Input value:', event.value)
})
chipInputElement.addEventListener('change.coreui.chip-input', event => {
// eslint-disable-next-line no-console
console.log('Current values:', event.values)
})
Keyboard behavior
When input is focused
| Key | Action |
|---|---|
Enter |
Create chip from current input value |
, (or separator) |
Create chip from current input value |
Backspace / Delete |
When input is empty, move focus to the last chip |
← |
When cursor is at start, move focus to the last chip |
Escape |
Clear selection, clear input, and blur |
When a chip is focused
| Key | Action |
|---|---|
Enter / Space |
Toggle selection (selectable chips) |
Backspace / Delete |
Remove chip (removable chips) |
← |
Move to previous chip |
→ |
Move to next chip |
Home |
Move to first chip |
End |
Move to last chip |
Accessibility
The Bootstrap Chip Input component follows WAI-ARIA patterns to ensure the chip input is fully usable with keyboards and assistive technologies.
- Associate a
<label>with the ghost input for screen readers. - Chips are focusable and keyboard navigable when initialized by the plugin.
- Remove buttons include
aria-label="Remove"by default. - Selected chips are reflected via
.activeandaria-selected. - Use a descriptive
aria-labelor<label>on the chip input container to communicate its purpose (e.g., “Add skills” or “Recipients”).
Customizing
CSS variables
Chips inputs use local CSS variables on .chip-input for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
--cui-chip-input-min-height: #{$chip-input-min-height};
--cui-chip-input-padding-y: #{$chip-input-padding-y};
--cui-chip-input-padding-x: #{$chip-input-padding-x};
--cui-chip-input-font-size: #{$chip-input-font-size};
--cui-chip-input-bg: #{$chip-input-bg};
--cui-chip-input-color: #{$chip-input-color};
--cui-chip-input-border-width: #{$chip-input-border-width};
--cui-chip-input-border-color: #{$chip-input-border-color};
--cui-chip-input-border-radius: #{$chip-input-border-radius};
--cui-chip-input-gap: #{$chip-input-gap};
--cui-chip-input-transition: #{$chip-input-transition};SASS variables
$chip-input-min-height: $input-height;
$chip-input-padding-y: .25rem;
$chip-input-padding-x: .75rem;
$chip-input-font-size: $input-font-size;
$chip-input-bg: var(--#{$prefix}body-bg);
$chip-input-color: var(--#{$prefix}body-color);
$chip-input-border-width: var(--#{$prefix}border-width);
$chip-input-border-color: var(--#{$prefix}border-color);
$chip-input-border-radius: var(--#{$prefix}border-radius);
$chip-input-gap: .375rem;
$chip-input-transition: $input-transition;
$chip-input-min-height-sm: $input-height-sm;
$chip-input-padding-y-sm: .125rem;
$chip-input-padding-x-sm: .5rem;
$chip-input-font-size-sm: $input-font-size-sm;
$chip-input-border-radius-sm: var(--#{$prefix}border-radius-sm);
$chip-input-gap-sm: .125rem;
$chip-input-min-height-lg: $input-height-lg;
$chip-input-padding-y-lg: .375rem;
$chip-input-padding-x-lg: 1rem;
$chip-input-font-size-lg: $input-font-size-lg;
$chip-input-border-radius-lg: var(--#{$prefix}border-radius-lg);
$chip-input-gap-lg: .5rem;

