0
# Styling and Themes
1
2
Comprehensive theming and styling system with JavaScript-based styles, CSS class alternatives, and extensive customization options. React Syntax Highlighter provides 146 pre-built themes across both engines (99 for highlight.js, 47 for Prism.js).
3
4
## Capabilities
5
6
### JavaScript-Based Styling
7
8
Default inline styling approach using JavaScript objects, eliminating external CSS dependencies.
9
10
```javascript { .api }
11
/**
12
* Style object structure for themes
13
*/
14
interface ThemeStyle {
15
[selector: string]: React.CSSProperties;
16
}
17
18
/**
19
* Common style selectors for highlight.js themes
20
*/
21
interface HljsThemeSelectors {
22
'hljs': React.CSSProperties;
23
'hljs-comment': React.CSSProperties;
24
'hljs-keyword': React.CSSProperties;
25
'hljs-string': React.CSSProperties;
26
'hljs-number': React.CSSProperties;
27
'hljs-function': React.CSSProperties;
28
'hljs-variable': React.CSSProperties;
29
'hljs-operator': React.CSSProperties;
30
'hljs-punctuation': React.CSSProperties;
31
[key: string]: React.CSSProperties;
32
}
33
34
/**
35
* Common style selectors for Prism themes
36
*/
37
interface PrismThemeSelectors {
38
'code[class*="language-"]': React.CSSProperties;
39
'pre[class*="language-"]': React.CSSProperties;
40
'token.comment': React.CSSProperties;
41
'token.keyword': React.CSSProperties;
42
'token.string': React.CSSProperties;
43
'token.number': React.CSSProperties;
44
'token.function': React.CSSProperties;
45
'token.operator': React.CSSProperties;
46
[key: string]: React.CSSProperties;
47
}
48
```
49
50
**Usage Examples:**
51
52
```javascript
53
import SyntaxHighlighter from 'react-syntax-highlighter';
54
import { docco, github, monokai } from 'react-syntax-highlighter/dist/esm/styles/hljs';
55
56
// Using pre-built themes
57
const ThemeExample = () => {
58
const code = `function fibonacci(n) {
59
if (n <= 1) return n;
60
return fibonacci(n - 1) + fibonacci(n - 2);
61
}`;
62
63
return (
64
<div>
65
{/* Docco theme */}
66
<SyntaxHighlighter language="javascript" style={docco}>
67
{code}
68
</SyntaxHighlighter>
69
70
{/* GitHub theme */}
71
<SyntaxHighlighter language="javascript" style={github}>
72
{code}
73
</SyntaxHighlighter>
74
75
{/* Monokai theme */}
76
<SyntaxHighlighter language="javascript" style={monokai}>
77
{code}
78
</SyntaxHighlighter>
79
</div>
80
);
81
};
82
```
83
84
### Highlight.js Themes
85
86
Extensive collection of highlight.js themes with various color schemes and styles.
87
88
```javascript { .api }
89
// Popular highlight.js themes
90
import {
91
// Light themes
92
docco,
93
github,
94
googlecode,
95
foundation,
96
xcode,
97
98
// Dark themes
99
monokai,
100
dracula,
101
atomOneDark,
102
nightOwl,
103
nord,
104
105
// High contrast themes
106
a11yDark,
107
a11yLight,
108
109
// Colorful themes
110
rainbow,
111
sunburst,
112
zenburn
113
} from 'react-syntax-highlighter/dist/esm/styles/hljs';
114
```
115
116
**Theme Showcase:**
117
118
```javascript
119
import SyntaxHighlighter from 'react-syntax-highlighter';
120
import * as hljsStyles from 'react-syntax-highlighter/dist/esm/styles/hljs';
121
122
const HljsThemeShowcase = () => {
123
const sampleCode = `class Calculator {
124
constructor() {
125
this.result = 0;
126
}
127
128
add(number) {
129
this.result += number;
130
return this;
131
}
132
133
multiply(number) {
134
this.result *= number;
135
return this;
136
}
137
138
getValue() {
139
return this.result;
140
}
141
}
142
143
const calc = new Calculator();
144
const result = calc.add(5).multiply(3).getValue(); // 15`;
145
146
const popularThemes = [
147
'docco', 'github', 'monokai', 'dracula',
148
'atomOneDark', 'solarizedLight', 'solarizedDark'
149
];
150
151
return (
152
<div>
153
{popularThemes.map(themeName => (
154
<div key={themeName} style={{ marginBottom: '2rem' }}>
155
<h3>{themeName}</h3>
156
<SyntaxHighlighter
157
language="javascript"
158
style={hljsStyles[themeName]}
159
>
160
{sampleCode}
161
</SyntaxHighlighter>
162
</div>
163
))}
164
</div>
165
);
166
};
167
```
168
169
### Prism.js Themes
170
171
Collection of Prism.js themes with modern styling and enhanced visual appeal.
172
173
```javascript { .api }
174
// Popular Prism themes
175
import {
176
// Light themes
177
prism,
178
coy,
179
solarizedlight,
180
base16AteliersulphurpoolLight,
181
182
// Dark themes
183
dark,
184
tomorrow,
185
twilight,
186
okaidia,
187
atomDark,
188
189
// Specialized themes
190
a11yDark,
191
cbTheme,
192
coldarkCold,
193
coldarkDark,
194
funky,
195
lucario,
196
materialDark,
197
materialLight,
198
nightOwl,
199
nord,
200
oneDark,
201
oneLight,
202
shadesOfPurple,
203
synthwave84,
204
vscDarkPlus
205
} from 'react-syntax-highlighter/dist/esm/styles/prism';
206
```
207
208
**Prism Theme Examples:**
209
210
```javascript
211
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
212
import { vscDarkPlus, oneLight, synthwave84 } from 'react-syntax-highlighter/dist/esm/styles/prism';
213
214
const PrismThemeDemo = () => {
215
const reactCode = `import React, { useState, useEffect } from 'react';
216
217
const UserProfile = ({ userId }) => {
218
const [user, setUser] = useState(null);
219
const [loading, setLoading] = useState(true);
220
221
useEffect(() => {
222
const fetchUser = async () => {
223
try {
224
const response = await fetch(\`/api/users/\${userId}\`);
225
const userData = await response.json();
226
setUser(userData);
227
} catch (error) {
228
console.error('Failed to fetch user:', error);
229
} finally {
230
setLoading(false);
231
}
232
};
233
234
fetchUser();
235
}, [userId]);
236
237
if (loading) return <div>Loading...</div>;
238
if (!user) return <div>User not found</div>;
239
240
return (
241
<div className="user-profile">
242
<h2>{user.name}</h2>
243
<p>{user.email}</p>
244
<p>Joined: {new Date(user.createdAt).toLocaleDateString()}</p>
245
</div>
246
);
247
};`;
248
249
return (
250
<div>
251
<h3>VS Code Dark Plus</h3>
252
<SyntaxHighlighter language="jsx" style={vscDarkPlus}>
253
{reactCode}
254
</SyntaxHighlighter>
255
256
<h3>One Light</h3>
257
<SyntaxHighlighter language="jsx" style={oneLight}>
258
{reactCode}
259
</SyntaxHighlighter>
260
261
<h3>Synthwave '84</h3>
262
<SyntaxHighlighter language="jsx" style={synthwave84}>
263
{reactCode}
264
</SyntaxHighlighter>
265
</div>
266
);
267
};
268
```
269
270
### Custom Styling
271
272
Creating and modifying themes with custom styles and overrides.
273
274
```javascript { .api }
275
/**
276
* Custom style properties for syntax highlighter components
277
*/
278
interface CustomStyleOptions {
279
/** Additional styles for the pre tag */
280
customStyle?: React.CSSProperties;
281
/** Props for the code tag including styles */
282
codeTagProps?: {
283
style?: React.CSSProperties;
284
className?: string;
285
[key: string]: any;
286
};
287
/** Use inline styles vs CSS classes */
288
useInlineStyles?: boolean;
289
}
290
```
291
292
**Custom Theme Creation:**
293
294
```javascript
295
import SyntaxHighlighter from 'react-syntax-highlighter';
296
import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs';
297
298
// Create custom theme by extending existing theme
299
const customTheme = {
300
...docco,
301
'hljs': {
302
...docco.hljs,
303
background: '#1e1e1e',
304
color: '#d4d4d4',
305
borderRadius: '8px',
306
padding: '16px'
307
},
308
'hljs-keyword': {
309
...docco['hljs-keyword'],
310
color: '#569cd6',
311
fontWeight: 'bold'
312
},
313
'hljs-string': {
314
...docco['hljs-string'],
315
color: '#ce9178'
316
},
317
'hljs-comment': {
318
...docco['hljs-comment'],
319
color: '#6a9955',
320
fontStyle: 'italic'
321
}
322
};
323
324
const CustomThemeExample = () => {
325
return (
326
<SyntaxHighlighter language="javascript" style={customTheme}>
327
{code}
328
</SyntaxHighlighter>
329
);
330
};
331
332
// Theme with custom styling overrides
333
const StyledExample = () => {
334
return (
335
<SyntaxHighlighter
336
language="javascript"
337
style={docco}
338
customStyle={{
339
margin: '20px 0',
340
borderRadius: '12px',
341
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
342
border: '1px solid #e1e5e9',
343
fontSize: '14px',
344
lineHeight: '1.5'
345
}}
346
codeTagProps={{
347
style: {
348
fontFamily: 'Fira Code, Menlo, Monaco, Consolas, monospace'
349
}
350
}}
351
>
352
{code}
353
</SyntaxHighlighter>
354
);
355
};
356
```
357
358
### CSS Class-Based Styling
359
360
Alternative styling approach using CSS classes instead of inline styles.
361
362
```javascript { .api }
363
/**
364
* Props for CSS class-based styling
365
*/
366
interface CSSClassStyleOptions {
367
/** Disable inline styles and use CSS classes */
368
useInlineStyles: false;
369
/** Additional CSS class for the pre element */
370
className?: string;
371
/** Props for code element including className */
372
codeTagProps?: {
373
className?: string;
374
[key: string]: any;
375
};
376
}
377
```
378
379
**CSS Class Examples:**
380
381
```javascript
382
// Using CSS classes instead of inline styles
383
const CSSClassExample = () => {
384
return (
385
<SyntaxHighlighter
386
language="javascript"
387
useInlineStyles={false}
388
className="custom-highlighter"
389
codeTagProps={{
390
className: "custom-code"
391
}}
392
>
393
{code}
394
</SyntaxHighlighter>
395
);
396
};
397
```
398
399
```css
400
/* External CSS file */
401
.custom-highlighter {
402
background-color: #2d3748;
403
border-radius: 8px;
404
padding: 16px;
405
margin: 16px 0;
406
overflow-x: auto;
407
}
408
409
.custom-code {
410
font-family: 'Fira Code', 'Monaco', 'Consolas', monospace;
411
font-size: 14px;
412
line-height: 1.5;
413
}
414
415
/* Highlight.js classes */
416
.hljs-keyword {
417
color: #f7fafc;
418
font-weight: bold;
419
}
420
421
.hljs-string {
422
color: #68d391;
423
}
424
425
.hljs-comment {
426
color: #a0aec0;
427
font-style: italic;
428
}
429
430
.hljs-number {
431
color: #f6ad55;
432
}
433
```
434
435
### Line Number Styling
436
437
Customizing the appearance and behavior of line numbers.
438
439
```javascript { .api }
440
/**
441
* Line number styling options
442
*/
443
interface LineNumberStyleOptions {
444
/** Show line numbers in left gutter */
445
showLineNumbers?: boolean;
446
/** Show line numbers inline with code */
447
showInlineLineNumbers?: boolean;
448
/** Starting line number */
449
startingLineNumber?: number;
450
/** Container styles for line numbers */
451
lineNumberContainerStyle?: React.CSSProperties;
452
/** Style for individual line numbers */
453
lineNumberStyle?: React.CSSProperties | ((lineNumber: number) => React.CSSProperties);
454
}
455
```
456
457
**Line Number Styling Examples:**
458
459
```javascript
460
const LineNumberStyling = () => {
461
// Basic line numbers
462
const basicExample = (
463
<SyntaxHighlighter
464
language="python"
465
style={docco}
466
showLineNumbers={true}
467
startingLineNumber={1}
468
>
469
{pythonCode}
470
</SyntaxHighlighter>
471
);
472
473
// Custom line number styling
474
const customLineNumbers = (
475
<SyntaxHighlighter
476
language="python"
477
style={docco}
478
showLineNumbers={true}
479
lineNumberContainerStyle={{
480
backgroundColor: '#f8f9fa',
481
borderRight: '2px solid #e9ecef',
482
paddingRight: '12px',
483
marginRight: '12px'
484
}}
485
lineNumberStyle={{
486
color: '#6c757d',
487
fontSize: '12px',
488
fontWeight: 'bold'
489
}}
490
>
491
{pythonCode}
492
</SyntaxHighlighter>
493
);
494
495
// Dynamic line number styling
496
const dynamicLineNumbers = (
497
<SyntaxHighlighter
498
language="python"
499
style={docco}
500
showLineNumbers={true}
501
lineNumberStyle={(lineNumber) => ({
502
color: lineNumber % 5 === 0 ? '#dc3545' : '#6c757d',
503
fontWeight: lineNumber % 5 === 0 ? 'bold' : 'normal',
504
backgroundColor: lineNumber % 10 === 0 ? '#fff3cd' : 'transparent'
505
})}
506
>
507
{pythonCode}
508
</SyntaxHighlighter>
509
);
510
511
return (
512
<div>
513
<h3>Basic Line Numbers</h3>
514
{basicExample}
515
516
<h3>Custom Line Numbers</h3>
517
{customLineNumbers}
518
519
<h3>Dynamic Line Numbers</h3>
520
{dynamicLineNumbers}
521
</div>
522
);
523
};
524
```
525
526
### Responsive and Adaptive Styling
527
528
Creating responsive themes that adapt to different screen sizes and user preferences.
529
530
```javascript
531
const ResponsiveExample = () => {
532
const [theme, setTheme] = useState('light');
533
const [fontSize, setFontSize] = useState(14);
534
535
// Theme switching
536
const lightTheme = github;
537
const darkTheme = atomOneDark;
538
const currentTheme = theme === 'light' ? lightTheme : darkTheme;
539
540
// Responsive custom styles
541
const responsiveStyles = {
542
fontSize: `${fontSize}px`,
543
borderRadius: '8px',
544
margin: '16px 0',
545
// Mobile styles
546
'@media (max-width: 768px)': {
547
fontSize: '12px',
548
margin: '8px 0',
549
borderRadius: '4px'
550
}
551
};
552
553
return (
554
<div>
555
<div style={{ marginBottom: '16px' }}>
556
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
557
Switch to {theme === 'light' ? 'Dark' : 'Light'} Theme
558
</button>
559
<input
560
type="range"
561
min="10"
562
max="20"
563
value={fontSize}
564
onChange={(e) => setFontSize(Number(e.target.value))}
565
/>
566
<span>Font Size: {fontSize}px</span>
567
</div>
568
569
<SyntaxHighlighter
570
language="javascript"
571
style={currentTheme}
572
customStyle={responsiveStyles}
573
>
574
{code}
575
</SyntaxHighlighter>
576
</div>
577
);
578
};
579
```
580
581
### Print Styling
582
583
Optimizing syntax highlighting for print media and PDF generation.
584
585
```javascript
586
const PrintOptimizedExample = () => {
587
const printStyles = {
588
backgroundColor: 'white',
589
color: 'black',
590
border: '1px solid #ccc',
591
fontSize: '10px',
592
lineHeight: '1.2',
593
// Print-specific styles
594
'@media print': {
595
backgroundColor: 'white !important',
596
color: 'black !important',
597
boxShadow: 'none',
598
border: '1px solid #000'
599
}
600
};
601
602
return (
603
<SyntaxHighlighter
604
language="javascript"
605
style={github} // Light theme works better for print
606
customStyle={printStyles}
607
showLineNumbers={true}
608
lineNumberStyle={{
609
color: '#666',
610
fontSize: '9px'
611
}}
612
>
613
{code}
614
</SyntaxHighlighter>
615
);
616
};
617
```
618
619
## Advanced Styling Techniques
620
621
### Theme Composition
622
623
```javascript
624
// Composing themes from multiple sources
625
const composeTheme = (baseTheme, overrides) => {
626
const composed = { ...baseTheme };
627
628
Object.keys(overrides).forEach(selector => {
629
composed[selector] = {
630
...composed[selector],
631
...overrides[selector]
632
};
633
});
634
635
return composed;
636
};
637
638
const myTheme = composeTheme(docco, {
639
'hljs': {
640
backgroundColor: '#1a1a1a',
641
color: '#f8f8f2',
642
borderRadius: '12px'
643
},
644
'hljs-keyword': {
645
color: '#ff79c6',
646
fontWeight: 'bold'
647
}
648
});
649
```
650
651
### Conditional Styling
652
653
```javascript
654
const ConditionalStyling = ({ isDark, isHighContrast }) => {
655
const getTheme = () => {
656
if (isHighContrast) {
657
return isDark ? a11yDark : a11yLight;
658
}
659
return isDark ? monokai : github;
660
};
661
662
const getCustomStyles = () => ({
663
fontSize: isHighContrast ? '16px' : '14px',
664
lineHeight: isHighContrast ? '1.8' : '1.5',
665
padding: isHighContrast ? '20px' : '16px'
666
});
667
668
return (
669
<SyntaxHighlighter
670
language="javascript"
671
style={getTheme()}
672
customStyle={getCustomStyles()}
673
>
674
{code}
675
</SyntaxHighlighter>
676
);
677
};
678
```