Newsletter

Hear about new files and fixes

I send an email when I publish something new or release a fix for a file you might already use. There’s no fixed schedule.

Every email has a one-click unsubscribe link, and none of them contain tracking pixels.

Etch component

Code Block

Publish code people can use: syntax colors for 13 language options, one-click copy and download of the complete original, line numbers, highlighted, added and removed lines, and a collapsible preview in light, dark or automatic themes. Paste your code in the props panel; the component prepares it for Etch by itself.

Download .jsonSee the demo

Paste it on the Etch canvas with Ctrl+V or ⌘V, then click Save.

Stay up to date. Etch won’t update a pasted component for you. Subscribe and get one email when a new version is out.

Free on unlimited personal, client and commercial sites. Modify it however you like.License: FSL-1.1-MIT
Version
1.0.0-beta.2Changelog
Options
45 settings+ 57 CSS variablesSee all
Tested on Etch
1.7.1
Tested on WordPress
7.1.3
Live demo

21 code blocks in real layouts

Copy, download, expand and wrap the code, hover the icon buttons, or press Tab to reach every control. Switch to Mobile for a phone width.

Live
  • Instances: 21
  • Languages: 13
  • Themes: Auto, Light, Dark, Site
  • Toolbars: Text, Icons
Open in a new tab
Features

What it does

One pasted component and no setup. Highlight.js is bundled, so there is no plugin, no CDN and no request to another server: the CSS and the script travel with it.

  • Paste and done

    Paste code into the props panel and choose the language. Etch would read braces as dynamic data, so the component prepares them by itself, and the page, Copy and Download show your original. Every edit shows in the canvas at once.

  • 13 languages, bundled

    HTML, CSS, SCSS, JavaScript, TypeScript, PHP, JSON, YAML, SQL, Bash, Markdown and Diff, plus plain text, colored by Highlight.js. Nothing loads from a CDN.

  • Copy and download the original

    Copy always takes the complete code, even from a collapsed preview, and confirms on the button. Download saves it as a file named after File name, made in the browser.

  • Line numbers and marks

    Numbers from any first line, highlighted lines, and added or removed lines with + and − marks. Numbers and marks are never copied, and color is never the only cue.

  • Long code, short page

    A collapsed preview of any height with a fade and an Expand button. Readers can wrap long lines; copying and downloading stay unchanged.

  • Themes, toolbars, captions

    Auto follows the visitor’s system, Site follows your page’s color scheme, Light and Dark are fixed. Labelled buttons or compact icons, plus an optional title, file name and caption.

  • Accessible by default

    A named figure with a focusable code area, native buttons, one polite message after copying, and line marks described for screen readers. Tested with NVDA, VoiceOver and TalkBack.

  • 57 styling variables

    Colors, spacing, fonts, the toolbar, buttons, line marks and every syntax color, set on any parent class. ACSS 4 tokens with plain fallbacks, so it works without Automatic.css too.

Install

Add it in four steps

No plugin and no build step. The component brings its own CSS and script with Highlight.js bundled, and loads nothing from a CDN. It works with or without Automatic.css 4.

Shows without its styles? It was pasted but not saved, and pasting again won’t repair it. Delete ED Code Block from your components, paste it again and click Save.

  1. Copy the componentUse Copy component at the top of this page, or download the .json file.
  2. Paste it on the Etch canvasSelect where it should go, press Ctrl+V or ⌘V, then click Save. Etch adds the component to your list right away but stores its CSS only when you save.
  3. Paste your codeSelect the block, paste your code into Code and choose its Language. About 0.1 s later the braces are prepared for Etch; leave the field as it is.
  4. Name it and saveAdd a Title or File name so readers and screen readers know what the code is, turn on what you need, such as Show line numbers or Show download, and save.
Options

45 settings in the Etch props panel

In the order of the Etch props panel, where each setting has help text too. Only Code needs filling in: everything else has a working default, and the 22 interface labels fall back to English while they are empty.

How the Code field works

Etch reads curly braces in text props as dynamic data. So that your code publishes exactly as written, the component stores each brace in Code as Etch’s literal-brace expression right after you paste or type. The field then shows those expressions; the canvas, the page, Copy and Download show your original code.

A dynamic binding, such as an ACF field or a loop item, stays as it is when it is the whole value of Code. First line number, Collapsed lines and Tab size are text fields too: an invalid value falls back to the default.

Code

Codecode
Your code. Paste it as it is: the builder prepares its braces for Etch automatically, and readers get the original back. A dynamic binding, such as an ACF field or a loop item, works when it is the whole value.Empty by default.
Languagelanguage
Syntax colors: Plain text, HTML, CSS, SCSS, JavaScript, TypeScript, PHP, JSON, YAML, SQL, Bash, Markdown or Diff. The badge shows its name; an unknown value shows plain text.Default: Plain text
Titletitle
Optional title in the toolbar. It also names the code area for screen readers. Empty hides it.Empty by default.
File namefileName
Optional file name in the toolbar and the name of the downloaded file. A path is reduced to a safe file name; without a name, the download is called code plus the language’s extension, such as code.js.Empty by default.
Captioncaption
Optional caption below the code. It becomes the figure’s caption and names the figure. Empty hides it.Empty by default.

Toolbar and theme

Show languageshowLanguage
Shows the language badge in the toolbar.Default: On
Themetheme
Auto follows the visitor’s system setting. Site follows your page’s color scheme, such as an ACSS dark section or a light and dark switch. Light and Dark are fixed.Default: Auto
Toolbar styletoolbarStyle
Text shows labelled buttons. Icons shows square icon buttons whose labels appear as tooltips on mouse hover and keyboard focus; Escape hides them.Default: Text
Show copyshowCopy
A button that copies the complete original code, even from a collapsed preview, and shows Copied. for 2 seconds. If the browser blocks copying, the code is selected instead, ready for Ctrl+C, ⌘C or the device’s Copy command.Default: On
Show downloadshowDownload
A button that saves the complete original code as a file. The file is made in the browser: nothing is uploaded or requested.Default: Off

Line numbers and marks

Show line numbersshowLineNumbers
Numbers the lines. A wrapped line keeps one number. Numbers are never copied, downloaded or read aloud.Default: Off
First line numberstartLine
Number of the first line, from 1 to 1,000,000, for an excerpt from a longer file. Highlight, Added and Removed lines use these numbers.Default: 1
Highlight lineshighlightLines
Lines to emphasize, as numbers and ranges such as 2,4-6. They get an edge marker and a tint, and screen readers hear which lines they are.Empty by default.
Added linesaddedLines
Lines marked as added, with a + and a green edge, such as 3-4. Works in every language.Empty by default.
Removed linesremovedLines
Lines marked as removed, with a − and a red edge. A line in both lists counts as removed.Empty by default.

Preview and wrapping

Collapsiblecollapsible
Shows a shorter preview of long code, with a fade and an Expand button. Off always shows the full height.Default: On
Initial stateinitialState
Collapsed or Expanded when the page loads.Default: Collapsed
Collapsed linescollapsedLines
Height of the preview in lines, from 1 to 100. When lines wrap, every wrapped row counts.Default: 12
Wrap lineswrapLines
Wraps long lines from the start. Off scrolls them sideways. The copied code never changes.Default: Off
Show wrap toggleshowWrapToggle
A button that lets readers turn wrapping on and off.Default: On

Text

Tab sizetabSize
Width of a tab character in spaces, from 0 to 256, such as 2 or 8. Display only: copied tabs stay tabs.Default: 4
Text sizetextSize
Small, Normal or Large, from the ACSS text-s, text-m and text-l sizes.Default: Normal

Manual converter

Manual convertershowConverter
Only needed when the builder could not prepare your code, for example in an older Etch. It shows a converter on the page preview: paste the original, copy the result into Code, then turn this off and save.Default: Off

Interface labels and translations

Copylabels.copy
Copy button text and accessible name.Default: Copy code
Copiedlabels.copySuccess
Shown on the Copy button for 2 seconds and announced once after copying.Default: Copied.
Copy failedlabels.copyError
Status when copying fails; the complete code is then selected for copying by hand.Default: Code selected. Copy it with Ctrl+C, Command+C or your device's Copy command.
Downloadlabels.download
Download button text and accessible name.Default: Download code
Download errorlabels.downloadError
Status when the download fails.Default: Download failed. Copy the code instead.
Expandlabels.expand
Expand button text and accessible name.Default: Expand code
Collapselabels.collapse
Collapse button text and accessible name.Default: Collapse code
Wrap onlabels.wrapOn
Wrap button text while lines are not wrapped.Default: Enable line wrapping
Wrap offlabels.wrapOff
Wrap button text while lines are wrapped.Default: Disable line wrapping
Code namelabels.region
Screen-reader name of the code area, read after the title or file name.Default: Code sample
Plain textlabels.plainText
Language badge for plain text.Default: Plain text
Highlightedlabels.highlightedLines
Read before the list of highlighted lines.Default: Highlighted lines
Addedlabels.addedLines
Read before the list of added lines.Default: Added lines
Removedlabels.removedLines
Read before the list of removed lines.Default: Removed lines
Too many lineslabels.annotationsUnavailable
Shown instead of line numbers and marks when the code has more than 5,000 lines.Default: Line annotations are unavailable for more than 5,000 lines. The complete code is still available.
Converterlabels.prepareTitle
Heading of the manual converter.Default: Prepare code for Etch
Converter helplabels.prepareHelp
Instructions in the manual converter.Default: The builder prepares pasted code automatically. Use this converter only when it did not: paste the original code below, copy the prepared result into Code, then turn off Manual converter and save. Always paste the original, not a previously prepared result.
Originallabels.prepareSource
Label of the field for the original code.Default: 1. Original code
Resultlabels.prepareOutput
Label of the field with the prepared result.Default: 2. Prepared code for the Code field
Copy resultlabels.prepareCopy
Text of the button that copies the result.Default: Copy prepared code
Result copiedlabels.prepareSuccess
Status after the result was copied.Default: Copied. Paste into the Code field in Etch.
Result errorlabels.prepareError
Status when copying the result fails; the result is then selected.Default: Result selected. Press Ctrl+C or Command+C to copy it manually.
Styling: 57 CSS variables

Set them on any parent element or class to style the code blocks inside it, or uncomment a line in the guide at the top of the component’s root style to set it for every block. Defaults written as light-dark() follow the theme. Check contrast when you change colors.

Container and code

--ed-code-block-bg
Code background.Default: light-dark(var(--bg-ultra-light, #fff), #101828)
--ed-code-block-color
Code text, and the default text of the toolbar and buttons.Default: light-dark(var(--text-dark, #1d2939), #f2f4f7)
--ed-code-block-border-width
Outer border width.Default: var(--border-size, 1px)
--ed-code-block-border-color
Outer border and the borders of the controls.Default: light-dark(var(--border-color-dark, #d0d5dd), #475467)
--ed-code-block-divider-color
Line below the toolbar and around the converter.Default: light-dark(var(--border-color-dark, #e4e7ec), #344054)
--ed-code-block-radius
Outer corner radius.Default: var(--radius, .75rem)
--ed-code-block-padding
Padding around the code, the converter and the status, one to four values.Default: var(--space-s, 1rem)
--ed-code-block-shadow
Subtle elevation. Set none to remove it.Default: 0 .25rem 1rem rgb(0 0 0 / .06)
--ed-code-block-font
Code font. ACSS has no monospace role, so this is a plain font stack.Default: ui-monospace, SFMono-Regular, Consolas, monospace
--ed-code-block-text-size
Code size. The Text size prop sets it to the ACSS text-s, text-m or text-l size.Default: var(--text-m, 1rem)
--ed-code-block-line-height
Code line height, also used to measure the collapsed preview.Default: var(--text-line-height, 1.5)

Toolbar, title, badge and caption

--ed-code-block-ui-font
Font of the toolbar, caption and converter.Default: var(--text-font-family, system-ui, sans-serif)
--ed-code-block-ui-size
Text size of the toolbar and status.Default: var(--text-s, .875rem)
--ed-code-block-toolbar-bg
Toolbar background.Default: light-dark(var(--bg-light, #f2f4f7), #1d2939)
--ed-code-block-toolbar-color
Toolbar text.Default: var(--ed-code-block-color)
--ed-code-block-toolbar-padding
Toolbar padding.Default: var(--space-xs, .75rem) var(--space-s, 1rem)
--ed-code-block-gap
Gap between toolbar items, buttons and converter fields.Default: var(--space-xs, .5rem)
--ed-code-block-title-color
Title color.Default: currentColor
--ed-code-block-title-size
Title size, relative to the toolbar text.Default: 1em
--ed-code-block-title-weight
Title weight.Default: 700
--ed-code-block-muted
File name and converter instructions.Default: light-dark(var(--text-dark, #475467), #b4bdcd)
--ed-code-block-badge-bg
Language badge background.Default: var(--ed-code-block-bg)
--ed-code-block-badge-color
Language badge text.Default: var(--ed-code-block-muted)
--ed-code-block-caption-color
Caption text.Default: var(--ed-code-block-muted)
--ed-code-block-caption-size
Caption size.Default: var(--text-s, .875rem)
--ed-code-block-converter-bg
Background of the manual converter.Default: var(--ed-code-block-toolbar-bg)

Buttons, icons and focus

--ed-code-block-button-padding
Padding of buttons and converter fields.Default: calc(var(--space-xs, 1rem) / 2) var(--space-xs, .75rem)
--ed-code-block-button-radius
Corner radius of buttons, fields and the badge.Default: var(--radius, .375rem)
--ed-code-block-button-bg
Button background.Default: var(--ed-code-block-bg)
--ed-code-block-button-color
Button text.Default: var(--ed-code-block-color)
--ed-code-block-button-hover-bg
Background on hover and while pressed.Default: 10% currentColor over the button background
--ed-code-block-button-hover-border
Border on hover and while pressed.Default: currentColor
--ed-code-block-icon-size
Icon size in the Icons toolbar.Default: 1.25em
--ed-code-block-focus-width
Focus outline width.Default: 3px
--ed-code-block-focus-color
Focus outline color.Default: var(--focus-color, light-dark(#175cd3, #fdb022))

Motion, scrolling and selection

--ed-code-block-transition
Button and preview transitions. Reduced motion turns them off.Default: var(--transition, .22s ease)
--ed-code-block-scrollbar-width
Scrollbar size: thin or auto.Default: thin
--ed-code-block-scrollbar-thumb
Scrollbar thumb color.Default: light-dark(var(--text-dark-muted, #667085), #98a2b3)
--ed-code-block-scrollbar-track
Scrollbar track color.Default: transparent
--ed-code-block-selection-bg
Background of selected code.Default: Highlight
--ed-code-block-selection-color
Text of selected code.Default: HighlightText
--ed-code-block-fade-size
Height of the fade at the bottom of a collapsed preview. 0 turns it off.Default: 2.5rem

Line numbers and marks

--ed-code-block-line-number-color
Line numbers.Default: light-dark(#475467, #b4bdcd)
--ed-code-block-line-number-gap
Gap between the numbers and the code.Default: var(--space-xs, .75rem)
--ed-code-block-highlight-bg
Background of highlighted lines.Default: light-dark(#f0f4ff, #1b2940)
--ed-code-block-highlight-border
Edge marker of highlighted lines.Default: light-dark(#175cd3, #84caff)
--ed-code-block-added-bg
Background of added lines.Default: light-dark(#ecfdf3, #0c2a1c)
--ed-code-block-added-color
The + mark and edge of added lines.Default: light-dark(#067647, #75e0a7)
--ed-code-block-removed-bg
Background of removed lines.Default: light-dark(#fef3f2, #3a1414)
--ed-code-block-removed-color
The − mark and edge of removed lines.Default: light-dark(#b42318, #fda29b)

Syntax colors

--ed-code-block-syntax-keyword
Keywords, and true, false and null in JSON.Default: light-dark(#6941c6, #d6bbfb)
--ed-code-block-syntax-string
Strings.Default: light-dark(#05603a, #6ce9a6)
--ed-code-block-syntax-number
Numbers.Default: light-dark(#93370d, #fec84b)
--ed-code-block-syntax-tag
Tags, attributes and JSON keys.Default: light-dark(#b42318, #fda29b)
--ed-code-block-syntax-function
Functions and built-ins.Default: light-dark(#175cd3, #84caff)
--ed-code-block-syntax-comment
Comments.Default: light-dark(#475467, #98a2b3)
--ed-code-block-syntax-meta
Meta lines, such as a doctype.Default: light-dark(#344054, #d0d5dd)
Good to know

Before you publish code

Things that are easy to miss when code goes onto a real site.

  • Leave the prepared braces alone. After you paste, Code shows each brace as a short Etch expression. That is what keeps your code intact: the page, Copy and Download show the original.
  • Code that contains Etch expressions needs the Manual converter. Documentation about Etch itself, with literal-brace expressions in the original, and code that is exactly one binding-like expression are not prepared automatically. Convert them once with the Manual converter.
  • Etch’s console message is expected. For the moment a raw brace sits in Code, about 0.1 s, Etch logs “Error formatting HTML” in the builder console. The message comes from Etch, not from the component.
  • Long code stays complete. Syntax colors stop above 20,000 characters, or 250,000 for JSON, and line numbers and marks above 5,000 lines. The code is still shown, copied and downloaded in full.
  • Without JavaScript, readers still get the code. It is in the page’s HTML and shows in full, without colors and buttons.
  • Printing shows everything. A printed page shows the whole code on a light background, wraps long lines and leaves out the buttons. Line numbers and marks stay.
  • Cloudflare can hide email addresses in code. Its Email Address Obfuscation rewrites addresses in the HTML, such as the one in an rsync or git command. Its script restores them, so the page and Copy stay correct, but readers without JavaScript see an “email protected” placeholder. Turn it off if your code shows addresses.
  • Not tested yet: VoiceOver on iOS. It was checked in Chrome, Firefox, Safari and Microsoft Edge, with NVDA, VoiceOver on macOS, TalkBack on an Android emulator and Safari in the iOS Simulator. TalkBack doesn’t read the instruction shown when copying is blocked; the code is still selected.
License

Free to use. Not for resale.

Licensed under FSL-1.1-MIT, the Functional Source License with an MIT future license. Each version becomes MIT-licensed two years after its release.

You can
  • Use it on unlimited personal, client and commercial websites
  • Modify and adapt it however you like
  • Use it in paid design and development work for your clients
You can’t
  • Sell it, or a modified version, as a component: in a library, bundle, template kit, plugin or marketplace listing
  • Offer it in another commercial product or service that competes with it

Keep the copyright and license notices in the code, and link to this page instead of re-hosting the download, so everyone gets fixes and updates. Read the full license

Third-party code

This component bundles the open-source library below. It keeps its own license, and FSL-1.1-MIT does not apply to it. Its full license notice is included in the component’s script; keep it when you use or change the component.

  • Highlight.js11.12.0© 2006 Ivan Sagalaev
    BSD-3-ClauseLicense text
Updates

How to update

Etch has no update button for pasted components. Pasting a newer version over an installed one changes nothing: Etch keeps the component and the CSS it already has. To update, reinstall in five steps.

  1. Note what you setWrite down the settings of each code block and keep a copy of its code. Copy any CSS you changed in the component’s own styles.
  2. Delete the componentIn Etch, delete ED Code Block from your components. Every code block disappears from every page that used it.
  3. Delete its stylesIn the Style Manager, search for ed-code-block and delete the 22 styles listed below.
  4. Paste the new versionCopy or download the new JSON from this page, paste it on the canvas and click Save. Etch creates the component and its CSS fresh.
  5. Put your code blocks backInsert a code block wherever one was, paste its code, re-enter its settings and save. Reload any other open builder tab.

Styles to delete in step 3

  • .ed-code-block
  • .ed-code-block__prepare
  • .ed-code-block__prepare-help
  • .ed-code-block__prepare-label
  • .ed-code-block__prepare-input
  • .ed-code-block__prepare-output
  • .ed-code-block__button
  • .ed-code-block__prepare-copy
  • .ed-code-block__prepare-status
  • .ed-code-block__toolbar
  • .ed-code-block__title
  • .ed-code-block__file-name
  • .ed-code-block__language
  • .ed-code-block__controls
  • .ed-code-block__copy
  • .ed-code-block__download
  • .ed-code-block__wrap
  • .ed-code-block__expand
  • .ed-code-block__source
  • .ed-code-block__labels
  • .ed-code-block__status
  • .ed-code-block__caption

Trade-offs

  • Placements are not kept. Etch doesn’t link old code blocks to the new component, so you insert each one again with its code and settings.
  • Edits inside the component’s CSS are replaced. Keep overrides on a parent class with the --ed-code-block-* variables; those survive an update.
  • Skipping a step leaves a mix. Without step 2, Etch keeps the old component. Without step 3, the new version runs on the old CSS.

Coming from 1.0.0-beta.1? Follow the five steps above. Settings, classes and styling variables are unchanged, so you can re-enter your settings as they were. Subscribe and you’ll get one email when the next version is out.

Changelog

What changed

Versions follow semantic versioning. When an update changes how existing options behave, its entry says so.

1.0.0-beta.2Latest
  • FixedAfter Expand and then Collapse, the fade at the bottom of a collapsed preview now comes back as soon as the height animation ends. Before, it stayed hidden until the reader scrolled the code.
  • ChangedThe default message when the browser blocks copying is now “Code selected. Copy it with Ctrl+C, Command+C or your device’s Copy command.” The old one named only keyboard shortcuts, which a phone doesn’t have. A text you entered yourself is kept.
  • FixedOn phones and tablets, a tap on an icon button no longer leaves its label tooltip open. Tooltips show on mouse hover and keyboard focus, as before.
  • ChangedThe script and the CSS of .ed-code-block changed, so update the component and its styles together (see How to update). Props, classes and the 57 styling variables are the same.
  • TestedTalkBack on Android, Safari on iPhone and iPad in the iOS Simulator, and Chrome, Firefox, Microsoft Edge and WebKit on the desktop. TalkBack doesn’t read the instruction shown when copying is blocked; the code is still selected and the message stays visible. It stays a beta until it’s checked with VoiceOver on a real iPhone.
1.0.0-beta.1
  • ReleasedFirst public version. It stays a beta until iOS, Android and Microsoft Edge are tested.
Feedback

Tell me what this component needs

A bug, a missing option, or anything that made the component awkward to use in a real build — it all belongs here. The versions above are the ones it was tested on; if yours differ, say so.