Code Block
FreeA syntax-highlighted code display component with a language label, line numbers, and a copy-to-clipboard button. Supports multiple programming languages with theme-aware syntax colouring. Ideal for documentation, tutorials, and API reference pages.
6 variants
Variants
| Variant | Description | When to use |
|---|---|---|
| Default | Standard code block with syntax highlighting, language label, and copy button. | Use for multi-line code examples in documentation or technical content. |
| With Title | ||
| With Line Numbers | Code block with numbered lines for referencing specific lines. | Use when users need to reference or discuss specific lines of code. |
Usage Guidelines
Do
Always include the language label so users know the syntax.
Don't
Use code blocks for non-code content — use a blockquote or callout instead.
Do
Provide a copy button for code that users will paste into their projects.
Don't
Omit the language label — syntax context helps readability.
Do
Use line highlighting to draw attention to the most relevant lines.
Don't
Allow code blocks to stretch beyond a reasonable max-width.
Do
Ensure the code block scrolls horizontally rather than wrapping long lines.
Don't
Code
HTML
<div class="lex-code-block" aria-label="Code example">
<div class="lex-code-block__header">
<span class="lex-code-block__lang">TypeScript</span>
<button class="lex-code-block__copy" aria-label="Copy code to clipboard">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2">
<rect x="9" y="9" width="13" height="13" rx="2" />
<path d="M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1" />
</svg>
</button>
</div>
<pre class="lex-code-block__pre"><code class="lex-code-block__code language-typescript"><span class="token keyword">interface</span> <span class="token class-name">User</span> <span class="token punctuation">{</span>
id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span>
name<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span>
email<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">getUser</span><span class="token punctuation">(</span>id<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token builtin">Promise</span><span class="token operator"><</span>User<span class="token operator">></span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> fetch<span class="token punctuation">(</span><span class="token template-string"><span class="token string">`/api/users/${id}`</span></span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>r <span class="token operator">=></span> r<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
</div>CSS Custom Properties
.lex-code-block {
background: var(--lex-code-bg);
border: 1px solid var(--lex-code-border, var(--lex-border-default));
border-radius: var(--lex-code-radius, var(--lex-radius-lg));
overflow: hidden;
font-family: var(--lex-font-mono);
}
.lex-code-block__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--lex-space-8) var(--lex-space-16);
border-bottom: 1px solid var(--lex-code-border, var(--lex-border-default));
background: var(--lex-code-header-bg, var(--lex-bg-surface-subtle));
}
.lex-code-block__lang {
font-size: var(--lex-font-size-xs);
font-weight: 500;
color: var(--lex-text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.lex-code-block__copy {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border: none;
background: transparent;
color: var(--lex-text-muted);
border-radius: var(--lex-radius-sm);
cursor: pointer;
transition: color 150ms ease, background 150ms ease;
}
.lex-code-block__copy:hover {
color: var(--lex-text-default);
background: var(--lex-bg-surface-subtle);
}
.lex-code-block__pre {
margin: 0;
padding: var(--lex-space-16);
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.lex-code-block__code {
font-size: var(--lex-code-font-size, var(--lex-font-size-sm));
line-height: var(--lex-line-height-code, 1.6);
color: var(--lex-code-text);
tab-size: 2;
}React
// Using Lexicon CSS classes with React
export function ApiExample() {
const code = `interface User {
id: string;
name: string;
email: string;
}
function getUser(id: string): Promise<User> {
return fetch(\`/api/users/\${id}\`).then(r => r.json());
}`;
return (
<CodeBlock
language="typescript"
showLineNumbers
highlightLines={[7, 8]}
copyable
>
{code}
</CodeBlock>
);
}Design Tokens
| Token | Value (dark) | Value (light) | CSS property |
|---|---|---|---|
| --lex-code-bg | — | — | bg |
| --lex-code-text | — | — | text |
| --lex-code-border | — | — | border |
| --lex-code-radius | — | — | radius |
| --lex-code-font | — | — | font |
| --lex-code-font-size | — | — | size |
| --lex-code-padding | — | — | padding |
Accessibility
- Wrap the code block with aria-label="Code example" to provide context for screen readers.
- The copy button must have aria-label="Copy code to clipboard" and announce success via an aria-live region.
- Use a <pre><code> structure to preserve whitespace and signal code semantics.
- Ensure syntax-highlighted text meets 4.5:1 contrast against the code background.
- Line numbers should be presentational (aria-hidden) to avoid cluttering screen reader output.