webdevpuneet.com

Code Block — Free HTML CSS JS Snippet

Code Block · Layouts · Plain HTML, CSS & JS · Live preview

CategoryLayouts

Copy & paste

Source Code

<div class="wrap">

  <div class="code-block">
    <div class="cb-header">
      <div class="cb-dots">
        <span class="dot red"></span>
        <span class="dot yellow"></span>
        <span class="dot green"></span>
      </div>
      <span class="cb-lang" id="lang-label">JavaScript</span>
      <div class="cb-actions">
        <button class="cb-btn" onclick="copyCode()" id="copy-btn" title="Copy code">
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
          <span id="copy-label">Copy</span>
        </button>
        <div class="lang-tabs" id="lang-tabs">
          <button class="lang-tab active" onclick="setLang('js')"  data-lang="js">JS</button>
          <button class="lang-tab" onclick="setLang('py')" data-lang="py">Python</button>
          <button class="lang-tab" onclick="setLang('ts')" data-lang="ts">TS</button>
        </div>
      </div>
    </div>
    <div class="cb-body">
      <div class="line-nums" id="line-nums"></div>
      <pre class="cb-pre" id="cb-pre"><code id="cb-code"></code></pre>
    </div>
  </div>

</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

CSS syntax highlighting: .kw .fn .str .cm .num .op span classes — no library
Colour scheme matches VSCode Dark+ — familiar to all developers
Line numbers: separate div with matched font/line-height, user-select:none
Copy button: Clipboard API + .copied class green feedback + 2s reset
Language tabs: data-lang attribute, setLang() swaps SNIPPETS object entry
macOS-style dots: red/yellow/green circles in header bar
Dark terminal frame: #0f172a background, overflow-x: auto for long lines
Monospace font stack: Fira Code → Consolas → monospace fallback

About this UI Snippet

Code Block — Syntax Highlighting, Copy Button, Language Tabs & Line Numbers

Screenshot of the Code Block snippet rendered live

Every developer blog, documentation site, tutorial, and technical landing page needs a well-styled code block. Syntax highlighting makes code dramatically more readable — keywords, strings, function names, and comments in distinct colours allow the reader to parse structure visually before reading text. This snippet provides a complete styled code block: a dark terminal frame with macOS-style dots, CSS-based syntax highlighting using span classes, line numbers, a copy-to-clipboard button with success feedback, and language tab switching.

CSS-based syntax highlighting without a library

The syntax highlighting uses CSS classes applied via span elements inline in the HTML: .kw (keywords, purple), .fn (function names, blue), .str (strings, green), .cm (comments, muted grey italic), .num (numbers, orange), .op (operators, light grey). These map to the classic VSCode Dark+ colour scheme that developers recognise immediately. No Prism.js, no Highlight.js — just CSS classes on span elements.

Line numbers with CSS

The line numbers column uses a separate div with textContent set to numbers joined by newlines: lines.map((_,i) => i+1).join('\n'). It uses the same font-family, font-size, and line-height as the code block to ensure perfect vertical alignment. user-select: none prevents accidental line number selection when users copy code.

The copy button feedback pattern

navigator.clipboard.writeText() returns a Promise. On resolve, the button label changes to "Copied!" and a .copied class applies a green colour scheme. A setTimeout resets both after 2 seconds. The Clipboard API is available in all modern browsers over HTTPS. The code text is extracted via code element textContent, which strips HTML tags from the span elements.

Language tab switching

Three SNIPPETS objects hold pre-highlighted HTML for each language. setLang(lang) updates the active tab, re-renders the code and line numbers, and updates the language label. The pre-highlighted HTML approach avoids runtime parsing — the highlighting is applied at author time.

Adapting for your content

Replace the SNIPPETS objects with your own code. Apply the .kw, .fn, .str, .cm, .num span classes to your code tokens. For automatic syntax highlighting at scale, use Prism.js or Shiki server-side to generate the highlighted HTML that replaces the span-based approach in this snippet.

Extending with a filename tab

Add a filename display between the browser dots and the language label: <span class="cb-filename">api/users.js</span>. This is standard in documentation sites where the same code block appears across multiple files. Update via JavaScript when the language tab changes: setLang() updates both the lang-label and filename spans simultaneously.

Step by step

How to Use

  1. 1
    Click the language tabs to switch code examplesClick JS, Python, or TS to switch between language examples. The code, line numbers, and language label update immediately. Each language shows the same fetch-and-render logic in different syntax.
  2. 2
    Click Copy to copy the code to clipboardClick the Copy button to copy the current code to clipboard. The button turns green and shows "Copied!" for 2 seconds, then resets. The textContent is copied without HTML tags.
  3. 3
    Replace the code contentUpdate the code strings in the SNIPPETS object. Apply .kw, .fn, .str, .cm, .num CSS classes via span elements to add syntax highlighting to your own code. Or paste plain code without spans for an unstyled code block.
  4. 4
    Add or remove language tabsAdd a new entry to SNIPPETS and a matching .lang-tab button with data-lang and onclick="setLang('newlang')". Remove unused language objects and their tab buttons.
  5. 5
    Use Shiki or Prism.js for automatic highlightingFor production documentation sites, replace the manual span approach with server-side highlighting. In Next.js, use Shiki createHighlighter() to generate highlighted HTML from raw code strings at build time. This snippet's CSS colour variables stay compatible with both approaches.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component accepting code and language props, or "Tailwind" for a React + Tailwind CSS version.

Real-world uses

Common Use Cases

Developer blog and tutorial code examples
Every technical blog post needs syntax-highlighted code blocks. This snippet provides the complete visual treatment — dark background, line numbers, copy button, language label — that readers expect from professional technical writing platforms.
Documentation site and API reference pages
API documentation requires code blocks for request/response examples, integration snippets, and configuration samples. The language tab switcher lets documentation show the same concept in multiple languages side by side.
Landing pages showing integration snippets
SaaS product landing pages frequently show a code snippet as the primary hero element ("Add this to your project in 3 lines"). The terminal frame communicates developer credibility and positions the product as technical and well-engineered.
Interactive coding tutorials and learning platforms
Coding education platforms show code blocks at every step. Wire the copy button to a tracking event to measure which snippets users copy most. Add a "Run" button that passes the code to a sandboxed evaluation environment.
Portfolio projects and case study technical sections
Developer portfolios showcase technical depth with code samples. The styled code block signals attention to detail and design quality — it communicates that you care about presenting your code well, not just writing it.
Onboarding flows showing setup and installation commands
SaaS and developer tool onboarding frequently shows installation commands (npm install, pip install, curl commands). The copy button is essential here — users expect one-click copy for any command they need to run in their terminal.
Related: CSS aspect-ratio Playground
See the CSS aspect-ratio Playground for a related layouts pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The copy function reads code element textContent (not innerHTML): const text = document.getElementById("cb-code").textContent. textContent returns only the visible characters without any HTML markup — the span tags used for syntax highlighting are stripped automatically. This gives the user clean, pasteable code without any markup artifacts.

For production use, use a server-side highlighting library. In Next.js: import { createHighlighter } from "shiki"; const hl = await createHighlighter({ themes: ["github-dark"], langs: ["javascript"] }); const html = hl.codeToHtml(code, { lang: "javascript", theme: "github-dark" }). Set the returned HTML as innerHTML of your code element. The Shiki output is compatible with this code block's CSS structure — just remove the manual span classes and use Shiki's classes instead.

Add a data-highlight attribute listing which lines to highlight: <pre data-highlight="3,7,8">. In JavaScript, after render(), read the attribute: const highlighted = pre.dataset.highlight?.split(",").map(Number) || []. Then wrap those line numbers in the code HTML: split the code by newline, wrap lines at highlighted indexes in <span class="hl-line">...</span>, rejoin. Add .hl-line { background: rgba(99,102,241,0.1); display: block; margin: 0 -16px; padding: 0 16px; } to the CSS.

Click "JSX" to download. Accept code (string), lang (string), and language (display label string) as props. Use dangerouslySetInnerHTML={{ __html: highlightedCode }} for the code element to render the pre-highlighted HTML. In Next.js, use Shiki in getStaticProps or a Server Component to generate the highlighted HTML at build time, passing it as a prop. For React without SSR, use Prism.js or highlight.js in a useEffect to highlight after mount.