or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ajax.mdconfiguration.mddata-management.mdevents.mdindex.mdinitialization.mdtheming.md

theming.mddocs/

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

'\\': '&#92;',

263

'&': '&amp;',

264

'<': '&lt;',

265

'>': '&gt;',

266

'"': '&quot;',

267

"'": '&#39;',

268

"/": '&#47;'

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, '&amp;')

299

.replace(/</g, '&lt;')

300

.replace(/>/g, '&gt;')

301

.replace(/"/g, '&quot;');

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

```