SolutionsCase StudiesAI ToolsResourcesAboutContact
Get Your Free AI Automation Audit Book a Free 30-Minute Strategy Call
Playground~/frontend Open editor

~/css/code-blocks

8 CSS Code Blocks

6 Pure CSS2 with JSPublished 2026-10-04Free · no sign-up

Eight ways to present code: a block with a Copy button, CSS-counter line numbers, highlighted and diff lines, tabbed snippets, a terminal window, inline code with keyboard keys, before and after panels and a collapsible long sample.

01. Code Block with Copy Button

CodeCopy

A code block with a language label and a Copy button in its header. The button copies the text with the Clipboard API and confirms with a status message, the pre is focusable so keyboard users can scroll it, and long lines scroll sideways.

View code
<figure class="cbk">
  <figcaption><span>CSS</span><button>Copy</button></figcaption>
  <pre tabindex="0"><code>.card {
  display: grid;
  gap: 12px;
  padding: clamp(16px, 4vw, 32px);
}</code></pre>
  <p class="st" role="status"></p>
</figure>
.cbk { box-sizing: border-box; max-width: 100%; width: 380px; margin: 0; overflow: hidden; border: 1px solid #262d3e; border-radius: 12px; background: #0b0d14; font-family: Inter, system-ui, sans-serif; }
.cbk figcaption { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; border-bottom: 1px solid #262d3e; color: #9aa4b8; font-size: 12px; font-weight: 700; }
.cbk button { padding: 4px 10px; border: 1px solid #343c51; border-radius: 6px; background: none; color: #e7ebf5; font: 600 12px Inter, sans-serif; cursor: pointer; }
.cbk button:focus-visible, .cbk pre:focus-visible { outline: 2px solid #7c9cff; }
.cbk pre { margin: 0; padding: 14px; overflow-x: auto; color: #e6ebf7; font: 13.5px/1.6 "JetBrains Mono", monospace; }
.st { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
const btn = document.querySelector('.cbk button');
btn.addEventListener('click', () => {
  if (!navigator.clipboard) return;
  navigator.clipboard.writeText(document.querySelector('.cbk code').textContent).then(() => {
    btn.textContent = 'Copied'; document.querySelector('.st').textContent = 'Code copied to clipboard';
    setTimeout(() => btn.textContent = 'Copy', 1500);
  });
});

02. Code Block with Line Numbers

CodeCounter

Line numbers made with CSS counters on spans, so they are never copied with the code and are not read aloud. The gutter is a pseudo-element on each line, and a light theme keeps it readable in documentation pages.

View code
<pre class="ln" tabindex="0"><code><span>function total(items) {</span>
<span>  return items.reduce((sum, i) =&gt; {</span>
<span>    return sum + i.price * i.qty;</span>
<span>  }, 0);</span>
<span>}</span></code></pre>
.ln { box-sizing: border-box; max-width: 100%; width: 380px; margin: 0; padding: 14px 0; overflow-x: auto; border: 1px solid #e4e7ec; border-radius: 12px; background: #f9fafb; color: #101828; font: 13.5px/1.7 "JetBrains Mono", monospace; counter-reset: ln; }
.ln span { display: block; padding-right: 14px; counter-increment: ln; }
.ln span::before { content: counter(ln); display: inline-block; width: 2.5em; margin-right: 14px; padding-right: 10px; border-right: 1px solid #e4e7ec; color: #5d6679; text-align: right; user-select: none; }
.ln:focus-visible { outline: 2px solid #2563eb; }

03. Highlighted Lines

CodeDocs

A code block that draws attention to the important lines with a tinted background and a coloured edge, marked with a class on each line. Inserted and deleted lines get plus and minus markers in text, so the change is clear without colour.

View code
<pre class="hl" tabindex="0"><code><span>.button {</span>
<span class="del">  background: blue;</span>
<span class="add">  background: var(--brand);</span>
<span>  border-radius: 8px;</span>
<span class="mark">  transition: background .2s;</span>
<span>}</span></code></pre>
.hl { box-sizing: border-box; max-width: 100%; width: 380px; margin: 0; padding: 12px 0; overflow-x: auto; border: 1px solid #262d3e; border-radius: 12px; background: #0b0d14; color: #e6ebf7; font: 13.5px/1.7 "JetBrains Mono", monospace; }
.hl span { display: block; padding: 0 14px 0 26px; }
.hl .add { background: rgba(52,211,153,.12); box-shadow: inset 3px 0 0 #34d399; }
.hl .add::before { content: "+"; margin-left: -16px; margin-right: 8px; color: #34d399; }
.hl .del { background: rgba(248,113,113,.12); box-shadow: inset 3px 0 0 #f87171; color: #fca5a5; }
.hl .del::before { content: "\2212"; margin-left: -16px; margin-right: 8px; color: #f87171; }
.hl .mark { background: rgba(124,156,255,.14); box-shadow: inset 3px 0 0 #7c9cff; }
.hl:focus-visible { outline: 2px solid #7c9cff; }

04. Tabbed Code Snippets

TabsCode

The same example in several languages with tabs for HTML, CSS and JavaScript, following the ARIA tabs pattern. Arrow keys switch tabs, only the active snippet is shown, and each panel is a focusable pre labelled by its tab.

View code
<div class="ct">
  <div role="tablist" aria-label="Snippet language">
    <button role="tab" aria-selected="true" aria-controls="ct1" id="cth1">HTML</button>
    <button role="tab" aria-selected="false" aria-controls="ct2" id="cth2" tabindex="-1">CSS</button>
    <button role="tab" aria-selected="false" aria-controls="ct3" id="cth3" tabindex="-1">JS</button>
  </div>
  <pre role="tabpanel" id="ct1" aria-labelledby="cth1" tabindex="0"><code>&lt;button class="btn"&gt;Save&lt;/button&gt;</code></pre>
  <pre role="tabpanel" id="ct2" aria-labelledby="cth2" tabindex="0" hidden><code>.btn { padding: 8px 14px; }</code></pre>
  <pre role="tabpanel" id="ct3" aria-labelledby="cth3" tabindex="0" hidden><code>btn.addEventListener('click', save);</code></pre>
</div>
.ct { box-sizing: border-box; max-width: 100%; width: 380px; overflow: hidden; border: 1px solid #d0d5dd; border-radius: 12px; background: #fff; font-family: Inter, system-ui, sans-serif; }
.ct [role=tablist] { display: flex; border-bottom: 1px solid #e4e7ec; background: #f9fafb; }
.ct [role=tab] { padding: 9px 14px; border: 0; border-bottom: 2px solid transparent; background: none; color: #475467; font: 600 13px Inter, sans-serif; cursor: pointer; }
.ct [aria-selected=true] { border-bottom-color: #2563eb; color: #101828; }
.ct [role=tab]:focus-visible, .ct pre:focus-visible { outline: 2px solid #2563eb; outline-offset: -2px; }
.ct pre { margin: 0; padding: 14px; overflow-x: auto; color: #101828; font: 13.5px "JetBrains Mono", monospace; }
const tabs = [...document.querySelectorAll('.ct [role=tab]')];
function pick(t) { tabs.forEach(x => { const on = x === t; x.setAttribute('aria-selected', on); x.tabIndex = on ? 0 : -1; document.getElementById(x.getAttribute('aria-controls')).hidden = !on; }); t.focus(); }
tabs.forEach((t, i) => { t.addEventListener('click', () => pick(t)); t.addEventListener('keydown', e => { const d = e.key === 'ArrowRight' ? 1 : e.key === 'ArrowLeft' ? -1 : 0; if (d) pick(tabs[(i + d + tabs.length) % tabs.length]); }); });

05. Terminal Window

TerminalShell

A terminal-style block with window dots, a prompt symbol and output lines in a muted colour. The prompt is added with CSS so it is not copied with the command, which lets people paste commands straight into their own terminal.

View code
<figure class="term">
  <div class="bar" aria-hidden="true"><i></i><i></i><i></i><span>bash</span></div>
  <pre tabindex="0"><code><span class="cmd">npm install</span>
<span class="out">added 214 packages in 6s</span>
<span class="cmd">npm run build</span>
<span class="out">Build finished in 1.8s</span></code></pre>
</figure>
.term { box-sizing: border-box; max-width: 100%; width: 380px; margin: 0; overflow: hidden; border-radius: 12px; background: #0a0c10; box-shadow: 0 20px 40px -20px #000; font-family: Inter, system-ui, sans-serif; }
.bar { display: flex; align-items: center; gap: 6px; padding: 10px 12px; background: #161a22; }
.bar i { width: 11px; height: 11px; border-radius: 50%; background: #f87171; }
.bar i:nth-child(2) { background: #fbbf24; } .bar i:nth-child(3) { background: #34d399; }
.bar span { margin-left: auto; color: #8b95a9; font-size: 12px; }
.term pre { margin: 0; padding: 14px; overflow-x: auto; font: 13.5px/1.7 "JetBrains Mono", monospace; }
.term span { display: block; }
.cmd { color: #e6ebf7; }
.cmd::before { content: "$ "; color: #34d399; user-select: none; }
.out { color: #8b95a9; }
.term pre:focus-visible { outline: 2px solid #34d399; outline-offset: -2px; }

06. Inline Code and Keyboard Keys

TypographyInline

Styles for code inside running text: inline code with a subtle tint and kbd elements for keyboard shortcuts with a raised bottom edge. Both keep the line height steady so paragraphs do not get uneven gaps around them.

View code
<p class="inl">Set <code>display: grid</code> on the parent, then press <kbd>Ctrl</kbd> + <kbd>S</kbd> to save. The <code>gap</code> property spaces the items.</p>
.inl { box-sizing: border-box; max-width: 100%; width: 380px; margin: 0; color: #344054; font: 16px/1.7 Inter, system-ui, sans-serif; }
.inl code { padding: .1em .35em; border-radius: 5px; background: #eef2ff; color: #3730a3; font: .88em "JetBrains Mono", monospace; }
.inl kbd { padding: .05em .4em; border: 1px solid #d0d5dd; border-bottom-width: 3px; border-radius: 5px; background: #fff; color: #101828; font: 600 .82em "JetBrains Mono", monospace; }

07. Before and After Code

ComparisonCode

Two code panels side by side labelled Before and After, which stack on narrow screens. Each panel is a figure with a caption, so the labels are associated with the code, and both panels scroll independently when lines are long.

View code
<div class="ba">
  <figure><figcaption>Before</figcaption><pre tabindex="0"><code>.box {
  margin-left: auto;
  margin-right: auto;
}</code></pre></figure>
  <figure><figcaption>After</figcaption><pre tabindex="0"><code>.box {
  margin-inline: auto;
}</code></pre></figure>
</div>
.ba { box-sizing: border-box; max-width: 100%; width: 460px; display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 10px; font-family: Inter, system-ui, sans-serif; }
.ba figure { margin: 0; min-width: 0; overflow: hidden; border: 1px solid #262d3e; border-radius: 10px; background: #0b0d14; }
.ba figcaption { padding: 6px 12px; border-bottom: 1px solid #262d3e; color: #9aa4b8; font-size: 12px; font-weight: 700; }
.ba figure:last-child figcaption { color: #6ee7b7; }
.ba pre { margin: 0; padding: 12px; overflow-x: auto; color: #e6ebf7; font: 13px/1.6 "JetBrains Mono", monospace; }
.ba pre:focus-visible { outline: 2px solid #7c9cff; outline-offset: -2px; }

08. Collapsible Long Code Block

CodeDetails

A long code sample shown with only the first lines visible and a Show full code toggle. It uses a details element, so the expand control is native and accessible, and a fade at the bottom hints that more code is hidden.

View code
<details class="lc">
  <summary>Show full code (5 lines)</summary>
  <pre tabindex="0"><code>const cart = [];
function add(item) { cart.push(item); render(); }
function remove(id) { cart.splice(cart.findIndex(i =&gt; i.id === id), 1); render(); }
function total() { return cart.reduce((s, i) =&gt; s + i.price, 0); }
function render() { document.querySelector('#total').textContent = total(); }</code></pre>
</details>
.lc { box-sizing: border-box; max-width: 100%; width: 380px; overflow: hidden; border: 1px solid #d0d5dd; border-radius: 12px; background: #f9fafb; font-family: Inter, system-ui, sans-serif; }
.lc pre { margin: 0; padding: 14px; overflow-x: auto; color: #101828; font: 13px/1.7 "JetBrains Mono", monospace; }
.lc:not([open]) { position: relative; }
.lc:not([open])::before { content: "const cart = [];\Afunction add(item) { cart.push(item); render(); }"; display: block; padding: 14px 14px 0; color: #101828; font: 13px/1.7 "JetBrains Mono", monospace; white-space: pre; overflow: hidden; -webkit-mask-image: linear-gradient(#000 40%, transparent); mask-image: linear-gradient(#000 40%, transparent); }
.lc summary { padding: 10px 14px; color: #1d4ed8; font-weight: 700; font-size: 13.5px; cursor: pointer; }
.lc summary:focus-visible { outline: 2px solid #2563eb; outline-offset: -2px; }

About these CSS Code Blocks

Scrollable and focusable

Long lines should scroll sideways rather than wrap or break the layout. Give the <pre> tabindex="0" so keyboard users can focus and scroll it.

Numbers that do not copy

Line numbers and terminal prompts added with CSS pseudo-elements are not copied with the code, so readers can paste commands straight into their editor or terminal.

Changes without colour alone

For diffs, add plus and minus markers in text next to the green and red backgrounds, so the change is clear in high contrast mode and to colour blind readers.

Copy buttons

Use the Clipboard API and confirm with a status message that screen readers announce, then reset the button label after a moment.

Frequently asked questions

Do these include syntax highlighting?

No. They are layout styles; add a highlighter such as Prism or Shiki if you need token colours.

Which demos need JavaScript?

The copy button and the tabbed snippets.

How do I stop line numbers being copied?

Generate them with CSS counters on pseudo-elements and add user-select: none.