Select2 is a jQuery based replacement for select boxes with searching, remote data sets, and infinite scrolling support
—
Appearance customization through themes, CSS classes, template functions, and custom rendering for both dropdown options and selections.
Built-in theme support with extensible theme architecture for consistent styling.
/**
* Theme configuration
*/
theme?: string; // Theme name (default: 'default')
// Available built-in themes
'default' // Standard Select2 theme
'classic' // Legacy Select2 v3.x appearance
'bootstrap4' // Bootstrap 4 integration (requires additional CSS)Usage Examples:
// Use default theme
$('#default-select').select2({
theme: 'default'
});
// Use Bootstrap 4 theme (requires select2-bootstrap4-theme CSS)
$('#bootstrap-select').select2({
theme: 'bootstrap4'
});
// Use classic theme
$('#classic-select').select2({
theme: 'classic'
});Direct CSS styling through inline styles and CSS classes for fine-grained control.
/**
* CSS customization options
*/
interface CssOptions {
containerCss?: object; // Inline CSS for main container
containerCssClass?: string; // CSS classes for main container
dropdownCss?: object; // Inline CSS for dropdown
dropdownCssClass?: string; // CSS classes for dropdown
dropdownParent?: jQuery; // Custom dropdown container element
dropdownAutoWidth?: boolean; // Auto-size dropdown width
}Usage Examples:
// Inline CSS styling
$('#styled-select').select2({
containerCss: {
'width': '300px',
'border-radius': '8px',
'border': '2px solid #007bff'
},
dropdownCss: {
'border-radius': '8px',
'box-shadow': '0 4px 6px rgba(0,0,0,0.1)'
}
});
// CSS class customization
$('#classed-select').select2({
containerCssClass: 'my-select-container custom-border',
dropdownCssClass: 'my-dropdown custom-shadow'
});
// Dropdown positioning
$('#modal-select').select2({
dropdownParent: $('#myModal'),
dropdownCssClass: 'modal-dropdown'
});
// Auto-width dropdown
$('#auto-width-select').select2({
dropdownAutoWidth: true,
width: 'element'
});Customize the rendering of dropdown options and selected items with complete HTML control.
/**
* Template function interfaces
*/
templateResult?: (result: DataObject) => string | jQuery | null;
templateSelection?: (selection: DataObject) => string | jQuery;
escapeMarkup?: (markup: string) => string;
/**
* Template function receives DataObject
*/
interface DataObject {
id: string | number;
text: string;
element?: HTMLOptionElement;
loading?: boolean; // True during AJAX loading
disabled?: boolean;
}Usage Examples:
// Custom dropdown option rendering
$('#template-results').select2({
templateResult: function(result) {
// Handle loading state
if (result.loading) {
return 'Loading...';
}
// Handle empty results
if (!result.id) {
return result.text;
}
// Custom HTML template
return $('<span><i class="icon-' + result.id + '"></i> ' + result.text + '</span>');
}
});
// Custom selection rendering
$('#template-selection').select2({
templateSelection: function(selection) {
// Simple text for placeholder
if (!selection.id) {
return selection.text;
}
// Custom selection display
return selection.text + ' (ID: ' + selection.id + ')';
}
});
// Rich HTML templates
$('#rich-templates').select2({
templateResult: function(result) {
if (result.loading) return 'Searching...';
if (!result.id) return result.text;
// Complex HTML with multiple elements
var $container = $(
'<div class="select2-result-item">' +
'<div class="item-title"></div>' +
'<div class="item-description"></div>' +
'</div>'
);
$container.find('.item-title').text(result.text);
$container.find('.item-description').text('Description for ' + result.text);
return $container;
},
templateSelection: function(selection) {
return selection.text || selection.id;
}
});
// Image templates with data attributes
$('#image-select').select2({
templateResult: function(result) {
if (!result.id || result.loading) {
return result.text;
}
var imageUrl = $(result.element).data('image');
if (imageUrl) {
return $(
'<span>' +
'<img src="' + imageUrl + '" style="width:20px;height:20px;margin-right:8px;" /> ' +
result.text +
'</span>'
);
}
return result.text;
}
});Control the dimensions and responsive behavior of Select2 components.
/**
* Width configuration options
*/
width?: string;
// Width values
'resolve' // Auto-detect from element, style, or compute (default)
'style' // Use CSS width from element
'element' // Use element's width
'off' // No width applied
'100%' // Percentage width
'300px' // Fixed pixel widthUsage Examples:
// Responsive width
$('#responsive-select').select2({
width: '100%'
});
// Fixed width
$('#fixed-select').select2({
width: '250px'
});
// Auto-detect width
$('#auto-select').select2({
width: 'resolve'
});
// Use element's computed width
$('#element-width-select').select2({
width: 'element'
});
// Responsive with max-width via CSS
$('#max-width-select').select2({
width: '100%',
containerCss: {
'max-width': '400px'
}
});Control HTML escaping for security and custom rendering needs.
/**
* Markup escaping function
*/
escapeMarkup?: (markup: string) => string;
// Default escaping function
function defaultEscapeMarkup(markup) {
var replaceMap = {
'\\': '\',
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"/": '/'
};
return String(markup).replace(/[&<>"'\/\\]/g, function(match) {
return replaceMap[match];
});
}Usage Examples:
// Disable escaping for trusted HTML content
$('#html-select').select2({
escapeMarkup: function(markup) {
return markup; // No escaping - USE WITH CAUTION
},
templateResult: function(result) {
if (!result.id) return result.text;
// Trusted HTML content
return '<strong>' + result.text + '</strong>';
}
});
// Custom escaping function
$('#custom-escape-select').select2({
escapeMarkup: function(markup) {
// Custom escaping logic
return markup
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"');
}
});
// Selective escaping
$('#selective-escape-select').select2({
escapeMarkup: function(markup) {
// Allow certain HTML tags
var allowedTags = ['<strong>', '</strong>', '<em>', '</em>'];
var escaped = Select2.util.escapeMarkup(markup);
allowedTags.forEach(function(tag) {
var escapedTag = Select2.util.escapeMarkup(tag);
escaped = escaped.replace(new RegExp(escapedTag, 'g'), tag);
});
return escaped;
}
});Complex styling scenarios and integration patterns.
// Theme-aware styling
$('#theme-aware-select').select2({
theme: 'bootstrap4',
templateResult: function(result) {
if (!result.id) return result.text;
var $option = $(
'<div class="custom-option d-flex align-items-center">' +
'<span class="option-text flex-grow-1"></span>' +
'<small class="text-muted option-meta"></small>' +
'</div>'
);
$option.find('.option-text').text(result.text);
$option.find('.option-meta').text('(' + result.id + ')');
return $option;
},
containerCssClass: 'select2-bootstrap4-theme'
});
// Conditional styling based on data
$('#conditional-style-select').select2({
templateResult: function(result) {
if (!result.id || result.loading) return result.text;
var $element = $(result.element);
var priority = $element.data('priority');
var category = $element.data('category');
var $container = $('<span class="custom-result"></span>');
$container.text(result.text);
// Add classes based on data attributes
if (priority === 'high') {
$container.addClass('high-priority');
}
if (category) {
$container.addClass('category-' + category);
}
return $container;
},
containerCssClass: function(element) {
// Dynamic container classes
return 'select2-' + element.attr('data-style');
}
});
// Responsive styling
$('#responsive-styled-select').select2({
width: '100%',
containerCss: {
'min-width': '200px',
'max-width': '100%'
},
dropdownCss: {
'min-width': '250px'
},
dropdownAutoWidth: true
});Key CSS classes for styling Select2 components.
/* Main container */
.select2-container { }
.select2-container--default { }
.select2-container--bootstrap4 { }
/* Selection area */
.select2-selection { }
.select2-selection--single { }
.select2-selection--multiple { }
/* Dropdown */
.select2-dropdown { }
.select2-dropdown--below { }
.select2-dropdown--above { }
/* Results */
.select2-results { }
.select2-results__options { }
.select2-results__option { }
.select2-results__option--highlighted { }
.select2-results__option--selected { }
/* Search */
.select2-search { }
.select2-search__field { }
/* Multiple selection */
.select2-selection__choice { }
.select2-selection__choice__remove { }
/* States */
.select2-container--disabled { }
.select2-container--open { }
.select2-container--focus { }Usage Examples:
/* Custom theme styling */
.my-custom-theme .select2-container {
border-radius: 8px;
}
.my-custom-theme .select2-selection {
border: 2px solid #007bff;
border-radius: 8px;
}
.my-custom-theme .select2-dropdown {
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.my-custom-theme .select2-results__option--highlighted {
background-color: #007bff;
color: white;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.select2-container {
width: 100% !important;
}
.select2-dropdown {
width: 100% !important;
}
}Install with Tessl CLI
npx tessl i tessl/npm-select2