0
# Theming and Customization
1
2
Appearance customization through themes, CSS classes, template functions, and custom rendering for both dropdown options and selections.
3
4
## Capabilities
5
6
### Theme System
7
8
Built-in theme support with extensible theme architecture for consistent styling.
9
10
```javascript { .api }
11
/**
12
* Theme configuration
13
*/
14
theme?: string; // Theme name (default: 'default')
15
16
// Available built-in themes
17
'default' // Standard Select2 theme
18
'classic' // Legacy Select2 v3.x appearance
19
'bootstrap4' // Bootstrap 4 integration (requires additional CSS)
20
```
21
22
**Usage Examples:**
23
24
```javascript
25
// Use default theme
26
$('#default-select').select2({
27
theme: 'default'
28
});
29
30
// Use Bootstrap 4 theme (requires select2-bootstrap4-theme CSS)
31
$('#bootstrap-select').select2({
32
theme: 'bootstrap4'
33
});
34
35
// Use classic theme
36
$('#classic-select').select2({
37
theme: 'classic'
38
});
39
```
40
41
### CSS Customization
42
43
Direct CSS styling through inline styles and CSS classes for fine-grained control.
44
45
```javascript { .api }
46
/**
47
* CSS customization options
48
*/
49
interface CssOptions {
50
containerCss?: object; // Inline CSS for main container
51
containerCssClass?: string; // CSS classes for main container
52
dropdownCss?: object; // Inline CSS for dropdown
53
dropdownCssClass?: string; // CSS classes for dropdown
54
dropdownParent?: jQuery; // Custom dropdown container element
55
dropdownAutoWidth?: boolean; // Auto-size dropdown width
56
}
57
```
58
59
**Usage Examples:**
60
61
```javascript
62
// Inline CSS styling
63
$('#styled-select').select2({
64
containerCss: {
65
'width': '300px',
66
'border-radius': '8px',
67
'border': '2px solid #007bff'
68
},
69
dropdownCss: {
70
'border-radius': '8px',
71
'box-shadow': '0 4px 6px rgba(0,0,0,0.1)'
72
}
73
});
74
75
// CSS class customization
76
$('#classed-select').select2({
77
containerCssClass: 'my-select-container custom-border',
78
dropdownCssClass: 'my-dropdown custom-shadow'
79
});
80
81
// Dropdown positioning
82
$('#modal-select').select2({
83
dropdownParent: $('#myModal'),
84
dropdownCssClass: 'modal-dropdown'
85
});
86
87
// Auto-width dropdown
88
$('#auto-width-select').select2({
89
dropdownAutoWidth: true,
90
width: 'element'
91
});
92
```
93
94
### Template Functions
95
96
Customize the rendering of dropdown options and selected items with complete HTML control.
97
98
```javascript { .api }
99
/**
100
* Template function interfaces
101
*/
102
templateResult?: (result: DataObject) => string | jQuery | null;
103
templateSelection?: (selection: DataObject) => string | jQuery;
104
escapeMarkup?: (markup: string) => string;
105
106
/**
107
* Template function receives DataObject
108
*/
109
interface DataObject {
110
id: string | number;
111
text: string;
112
element?: HTMLOptionElement;
113
loading?: boolean; // True during AJAX loading
114
disabled?: boolean;
115
}
116
```
117
118
**Usage Examples:**
119
120
```javascript
121
// Custom dropdown option rendering
122
$('#template-results').select2({
123
templateResult: function(result) {
124
// Handle loading state
125
if (result.loading) {
126
return 'Loading...';
127
}
128
129
// Handle empty results
130
if (!result.id) {
131
return result.text;
132
}
133
134
// Custom HTML template
135
return $('<span><i class="icon-' + result.id + '"></i> ' + result.text + '</span>');
136
}
137
});
138
139
// Custom selection rendering
140
$('#template-selection').select2({
141
templateSelection: function(selection) {
142
// Simple text for placeholder
143
if (!selection.id) {
144
return selection.text;
145
}
146
147
// Custom selection display
148
return selection.text + ' (ID: ' + selection.id + ')';
149
}
150
});
151
152
// Rich HTML templates
153
$('#rich-templates').select2({
154
templateResult: function(result) {
155
if (result.loading) return 'Searching...';
156
if (!result.id) return result.text;
157
158
// Complex HTML with multiple elements
159
var $container = $(
160
'<div class="select2-result-item">' +
161
'<div class="item-title"></div>' +
162
'<div class="item-description"></div>' +
163
'</div>'
164
);
165
166
$container.find('.item-title').text(result.text);
167
$container.find('.item-description').text('Description for ' + result.text);
168
169
return $container;
170
},
171
templateSelection: function(selection) {
172
return selection.text || selection.id;
173
}
174
});
175
176
// Image templates with data attributes
177
$('#image-select').select2({
178
templateResult: function(result) {
179
if (!result.id || result.loading) {
180
return result.text;
181
}
182
183
var imageUrl = $(result.element).data('image');
184
if (imageUrl) {
185
return $(
186
'<span>' +
187
'<img src="' + imageUrl + '" style="width:20px;height:20px;margin-right:8px;" /> ' +
188
result.text +
189
'</span>'
190
);
191
}
192
193
return result.text;
194
}
195
});
196
```
197
198
### Width and Sizing
199
200
Control the dimensions and responsive behavior of Select2 components.
201
202
```javascript { .api }
203
/**
204
* Width configuration options
205
*/
206
width?: string;
207
208
// Width values
209
'resolve' // Auto-detect from element, style, or compute (default)
210
'style' // Use CSS width from element
211
'element' // Use element's width
212
'off' // No width applied
213
'100%' // Percentage width
214
'300px' // Fixed pixel width
215
```
216
217
**Usage Examples:**
218
219
```javascript
220
// Responsive width
221
$('#responsive-select').select2({
222
width: '100%'
223
});
224
225
// Fixed width
226
$('#fixed-select').select2({
227
width: '250px'
228
});
229
230
// Auto-detect width
231
$('#auto-select').select2({
232
width: 'resolve'
233
});
234
235
// Use element's computed width
236
$('#element-width-select').select2({
237
width: 'element'
238
});
239
240
// Responsive with max-width via CSS
241
$('#max-width-select').select2({
242
width: '100%',
243
containerCss: {
244
'max-width': '400px'
245
}
246
});
247
```
248
249
### Custom Markup Escaping
250
251
Control HTML escaping for security and custom rendering needs.
252
253
```javascript { .api }
254
/**
255
* Markup escaping function
256
*/
257
escapeMarkup?: (markup: string) => string;
258
259
// Default escaping function
260
function defaultEscapeMarkup(markup) {
261
var replaceMap = {
262
'\\': '\',
263
'&': '&',
264
'<': '<',
265
'>': '>',
266
'"': '"',
267
"'": ''',
268
"/": '/'
269
};
270
271
return String(markup).replace(/[&<>"'\/\\]/g, function(match) {
272
return replaceMap[match];
273
});
274
}
275
```
276
277
**Usage Examples:**
278
279
```javascript
280
// Disable escaping for trusted HTML content
281
$('#html-select').select2({
282
escapeMarkup: function(markup) {
283
return markup; // No escaping - USE WITH CAUTION
284
},
285
templateResult: function(result) {
286
if (!result.id) return result.text;
287
288
// Trusted HTML content
289
return '<strong>' + result.text + '</strong>';
290
}
291
});
292
293
// Custom escaping function
294
$('#custom-escape-select').select2({
295
escapeMarkup: function(markup) {
296
// Custom escaping logic
297
return markup
298
.replace(/&/g, '&')
299
.replace(/</g, '<')
300
.replace(/>/g, '>')
301
.replace(/"/g, '"');
302
}
303
});
304
305
// Selective escaping
306
$('#selective-escape-select').select2({
307
escapeMarkup: function(markup) {
308
// Allow certain HTML tags
309
var allowedTags = ['<strong>', '</strong>', '<em>', '</em>'];
310
var escaped = Select2.util.escapeMarkup(markup);
311
312
allowedTags.forEach(function(tag) {
313
var escapedTag = Select2.util.escapeMarkup(tag);
314
escaped = escaped.replace(new RegExp(escapedTag, 'g'), tag);
315
});
316
317
return escaped;
318
}
319
});
320
```
321
322
### Advanced Styling Techniques
323
324
Complex styling scenarios and integration patterns.
325
326
```javascript
327
// Theme-aware styling
328
$('#theme-aware-select').select2({
329
theme: 'bootstrap4',
330
templateResult: function(result) {
331
if (!result.id) return result.text;
332
333
var $option = $(
334
'<div class="custom-option d-flex align-items-center">' +
335
'<span class="option-text flex-grow-1"></span>' +
336
'<small class="text-muted option-meta"></small>' +
337
'</div>'
338
);
339
340
$option.find('.option-text').text(result.text);
341
$option.find('.option-meta').text('(' + result.id + ')');
342
343
return $option;
344
},
345
containerCssClass: 'select2-bootstrap4-theme'
346
});
347
348
// Conditional styling based on data
349
$('#conditional-style-select').select2({
350
templateResult: function(result) {
351
if (!result.id || result.loading) return result.text;
352
353
var $element = $(result.element);
354
var priority = $element.data('priority');
355
var category = $element.data('category');
356
357
var $container = $('<span class="custom-result"></span>');
358
$container.text(result.text);
359
360
// Add classes based on data attributes
361
if (priority === 'high') {
362
$container.addClass('high-priority');
363
}
364
365
if (category) {
366
$container.addClass('category-' + category);
367
}
368
369
return $container;
370
},
371
containerCssClass: function(element) {
372
// Dynamic container classes
373
return 'select2-' + element.attr('data-style');
374
}
375
});
376
377
// Responsive styling
378
$('#responsive-styled-select').select2({
379
width: '100%',
380
containerCss: {
381
'min-width': '200px',
382
'max-width': '100%'
383
},
384
dropdownCss: {
385
'min-width': '250px'
386
},
387
dropdownAutoWidth: true
388
});
389
```
390
391
### CSS Classes Reference
392
393
Key CSS classes for styling Select2 components.
394
395
```css
396
/* Main container */
397
.select2-container { }
398
.select2-container--default { }
399
.select2-container--bootstrap4 { }
400
401
/* Selection area */
402
.select2-selection { }
403
.select2-selection--single { }
404
.select2-selection--multiple { }
405
406
/* Dropdown */
407
.select2-dropdown { }
408
.select2-dropdown--below { }
409
.select2-dropdown--above { }
410
411
/* Results */
412
.select2-results { }
413
.select2-results__options { }
414
.select2-results__option { }
415
.select2-results__option--highlighted { }
416
.select2-results__option--selected { }
417
418
/* Search */
419
.select2-search { }
420
.select2-search__field { }
421
422
/* Multiple selection */
423
.select2-selection__choice { }
424
.select2-selection__choice__remove { }
425
426
/* States */
427
.select2-container--disabled { }
428
.select2-container--open { }
429
.select2-container--focus { }
430
```
431
432
**Usage Examples:**
433
434
```css
435
/* Custom theme styling */
436
.my-custom-theme .select2-container {
437
border-radius: 8px;
438
}
439
440
.my-custom-theme .select2-selection {
441
border: 2px solid #007bff;
442
border-radius: 8px;
443
}
444
445
.my-custom-theme .select2-dropdown {
446
border-radius: 8px;
447
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
448
}
449
450
.my-custom-theme .select2-results__option--highlighted {
451
background-color: #007bff;
452
color: white;
453
}
454
455
/* Responsive adjustments */
456
@media (max-width: 768px) {
457
.select2-container {
458
width: 100% !important;
459
}
460
461
.select2-dropdown {
462
width: 100% !important;
463
}
464
}
465
```