A feature-rich code block web component with syntax highlighting, copy-to-clipboard, and extensive customization options. Designed for tutorials, documentation, and educational content.
See the live demo for all features in action
| Feature | Description |
|---|---|
| Multi-File Tabs | Tabbed interface for related code files with <code-block-group> |
| Line Highlighting | Draw attention to specific lines with highlight-lines="3,5-7" |
| Focus Mode | Dim non-highlighted lines with focus-mode for emphasis |
| Share & Download | One-click download or open in CodePen |
| Collapsible Blocks | Expandable code with "Show more" for long snippets |
| Lazy Loading | Defer syntax highlighting until visible for performance |
| Diff Support | Visualize code changes with +/- line highlighting |
| Custom Themes | Full CSS custom property support for branding |
| Light & Dark | GitHub-inspired color schemes |
- 13 Web Languages - HTML, CSS, JS, JSON, YAML, PHP, and more
- Line Numbers - Optional line number display
- Filename Headers - Show file paths in the header
- Copy to Clipboard - One-click copy with visual feedback
- Word Wrap - Toggle between scroll and wrap for long lines
- Shadow DOM - Encapsulated styles that won't conflict with your app
- Accessible - ARIA labels, keyboard focus, screen reader support
- TypeScript Support - Full type definitions included
npm install @profpowell/code-blockAdd this repository as a git submodule to your project:
git submodule add https://github.com/ProfPowell/code-block.git lib/code-block
cd lib/code-block && npm installThen import the component:
import './lib/code-block/code-block.js';Once imported, the <code-block> custom element is automatically registered:
<code-block language="javascript">
function greet(name) {
return `Hello, ${name}!`;
}
</code-block><code-block language="python" label="Data Processing">
import pandas as pd
df = pd.read_csv('data.csv')
print(df.head())
</code-block><code-block language="css" theme="dark">
.container {
display: grid;
gap: 1rem;
}
</code-block><code-block language="javascript" show-lines>
class EventEmitter {
constructor() {
this.events = new Map();
}
on(event, callback) {
if (!this.events.has(event)) {
this.events.set(event, []);
}
this.events.get(event).push(callback);
}
}
</code-block><code-block language="typescript" theme="dark" show-lines label="User Service">
interface User {
id: number;
name: string;
}
class UserService {
async getUser(id: number): Promise<User> {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
}
</code-block>The component includes an optimized bundle with 13 web development languages:
| Language | Values |
|---|---|
| HTML | html, markup |
| XML | xml |
| XHTML | xhtml |
| SVG | svg |
| CSS | css |
| JavaScript | javascript, js |
| JSON | json |
| YAML | yaml, yml |
| PHP | php |
| HTTP | http |
| Diff | diff |
| Plain Text | plaintext, text, txt |
| CSV | csv |
Additional languages can be added by importing them from highlight.js.
| Attribute | Type | Default | Description |
|---|---|---|---|
language |
string | 'plaintext' |
Programming language for highlighting |
label |
string | language |
Label displayed in the header |
theme |
'light' | 'dark' |
'light' |
Color theme |
show-lines |
boolean | false |
Display line numbers |
filename |
string | — | File path shown in header |
highlight-lines |
string | — | Lines to highlight (e.g., "3,5-7") |
focus-mode |
boolean | false |
Dim non-highlighted lines for emphasis |
collapsed |
boolean | false |
Start in collapsed state |
max-lines |
number | 10 |
Lines visible when collapsed |
max-height |
string | — | Max height with scrolling (e.g., "300px") |
wrap |
boolean | false |
Wrap long lines |
copy-text |
string | 'Copy' |
Custom copy button text |
copied-text |
string | 'Copied!' |
Custom success message |
show-share |
boolean | false |
Show share button |
show-download |
boolean | false |
Show download button |
lazy |
boolean | false |
Defer highlighting until visible |
| Method | Returns | Description |
|---|---|---|
copyCode() |
Promise<void> |
Copy code to clipboard |
setCode(code) |
void |
Update code content |
getCode() |
string |
Get current code |
downloadCode() |
void |
Download as file |
openInCodePen() |
void |
Open in CodePen |
toggleCollapsed() |
void |
Toggle collapsed state |
render() |
void |
Re-render the component |
The component exposes 60+ CSS custom properties for full theme control. Properties marked "theme-aware" adapt automatically to light/dark mode.
| Property | Default | Description |
|---|---|---|
--cb-bg |
theme-aware | Outer container background |
--cb-code-bg |
theme-aware | Code area background |
--cb-border-color |
theme-aware | Border color used throughout |
--cb-border-radius |
8px |
Outer container border radius |
--cb-margin |
1rem 0 |
Component outer margin |
--cb-shadow |
theme-aware | Box shadow on dropdown menus |
| Property | Default | Description |
|---|---|---|
--cb-font-family |
Consolas, Monaco, Courier New, monospace |
Code font |
--cb-ui-font-family |
-apple-system, BlinkMacSystemFont, Segoe UI, sans-serif |
UI font (buttons, menus) |
--cb-font-size |
0.875rem |
Base code font size |
--cb-text-color |
theme-aware | Default code text color |
--cb-line-height |
1.6 |
Code line height |
| Property | Default | Description |
|---|---|---|
--cb-header-bg |
theme-aware | Header bar background |
--cb-header-padding |
0.5rem 1rem |
Header padding |
--cb-label-color |
theme-aware | Language label and icon color |
--cb-filename-color |
theme-aware | Filename text color |
| Property | Default | Description |
|---|---|---|
--cb-button-bg |
theme-aware | Button background |
--cb-button-color |
theme-aware | Button text color |
--cb-button-border |
theme-aware | Button border color |
--cb-button-border-width |
1px |
Button border width |
--cb-button-border-style |
solid |
Button border style (solid, none, etc.) |
--cb-button-radius |
4px |
Border radius for copy and action buttons |
--cb-button-padding |
4px 12px |
Copy button padding |
--cb-button-font-size |
0.75rem |
Copy button font size |
--cb-button-hover-bg |
theme-aware | Copy button hover background |
--cb-button-hover-border |
theme-aware | Copy button hover border color |
--cb-action-button-hover-bg |
theme-aware | Icon button hover background |
--cb-success-color |
#238636 |
Copied-success state color |
--cb-error-color |
#da3633 |
Copy-failed state color |
--cb-focus-color |
theme-aware | Focus ring color |
| Property | Default | Description |
|---|---|---|
--cb-code-padding |
1rem |
Code area and gutter padding |
--cb-line-numbers-bg |
theme-aware | Line-numbers gutter background |
--cb-line-numbers-color |
theme-aware | Line-numbers text color |
| Property | Default (Light / Dark) | Description |
|---|---|---|
--cb-keyword |
#d73a49 / #ff7b72 |
Keywords |
--cb-string |
#22863a / #a5d6ff |
Strings |
--cb-comment |
theme-aware | Comments |
--cb-function |
#6f42c1 / #d2a8ff |
Function names |
--cb-number |
#005cc5 / #79c0ff |
Numbers |
--cb-attribute |
#005cc5 / #79c0ff |
HTML/XML attributes |
--cb-tag |
#22863a / #7ee787 |
HTML/XML tags |
--cb-meta |
#e36209 / #ffa657 |
Meta/preprocessor tokens |
--cb-builtin |
#d73a49 / #ffa198 |
Built-in names |
See docs/api.html for the complete reference including diff, expand/collapse, scrollbar, highlight, and focus-mode properties.
code-block {
--cb-button-radius: 0;
--cb-button-border-style: none;
--cb-border-radius: 0;
--cb-ui-font-family: 'Inter', sans-serif;
--cb-font-family: 'JetBrains Mono', monospace;
}// Get a reference to a code block
const codeBlock = document.querySelector('code-block');
// Copy code programmatically
await codeBlock.copyCode();
// Update code content dynamically
codeBlock.setCode('const updated = true;');
// Get current code
const code = codeBlock.getCode();
// Get all supported languages (static method)
const languages = CodeBlock.getSupportedLanguages();
console.log(`Supports ${languages.length} languages`);For static sites and documentation, code blocks can be pre-rendered at build time using the SSR module. This eliminates client-side syntax highlighting and displays code instantly using Declarative Shadow DOM.
The SSR module is included in the package — no extra install needed:
import { prerenderCodeBlock, prerenderCodeBlocksInHtml } from '@profpowell/code-block/ssr'const html = prerenderCodeBlock({
code: 'const x = 42;',
language: 'javascript',
theme: 'dark',
showLines: true,
filename: 'app.js',
})
// Returns complete <code-block data-ssr> with Declarative Shadow DOMconst page = prerenderCodeBlocksInHtml(rawHtml)
// Finds all <code-block> elements and pre-renders them
// Skips blocks with src attribute or data-ssr (already processed)The SSR module runs in Node.js and can be used as a build step in any static site generator:
// Example Cook plugin
import { prerenderCodeBlocksInHtml } from '@profpowell/code-block/ssr'
// Process HTML after all other transforms
file.src = prerenderCodeBlocksInHtml(file.src)- Build time:
prerenderCodeBlock()runs highlight.js in Node.js and generates the full shadow DOM HTML - Output: A
<code-block data-ssr>element with<template shadowrootmode="open">containing pre-rendered styles and highlighted code, plus a<textarea>preserving raw code for copy-to-clipboard - Browser: The Declarative Shadow DOM template is parsed into a real shadow root — code is visible immediately, before any JavaScript loads
- Hydration: When the component JS loads, it detects
data-ssr, skips re-rendering, and attaches interactive event listeners (copy, download, share, expand/collapse)
prerenderCodeBlock() accepts all the same options as the component's HTML attributes:
| Option | Type | Default | Description |
|---|---|---|---|
code |
string | required | Source code to highlight |
language |
string | 'plaintext' |
Language for highlighting |
theme |
string | 'light' |
'light' or 'dark' |
filename |
string | — | Filename in header |
label |
string | — | Custom label |
showLines |
boolean | false |
Show line numbers |
highlightLines |
string | — | Lines to highlight, e.g. "2,4-6" |
focusMode |
boolean | false |
Dim non-highlighted lines |
collapsed |
boolean | false |
Start collapsed |
maxLines |
number | 10 |
Visible lines when collapsed |
maxHeight |
string | — | Max height with scroll |
wrap |
boolean | false |
Word wrap |
noCopy |
boolean | false |
Hide copy button |
copyText |
string | 'Copy' |
Copy button text |
showShare |
boolean | false |
Show share button |
showDownload |
boolean | false |
Show download button |
Open demo.html in a browser to see all features in action:
- Multi-file tabbed interface
- Line highlighting
- Focus mode
- Share & download buttons
- Collapsible code blocks
- Lazy loading for performance
- Diff visualization
- CSS custom properties
- Light and dark themes
- Complete API reference
Works in all modern browsers that support:
- Custom Elements v1
- Shadow DOM v1
- ES6 Modules
- Clipboard API
- highlight.js ^11.11.1 - Syntax highlighting
MIT License - see LICENSE for details.