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

Comments

Native WordPress comments, styled for your Etch site. Light, dark or inherited colors, compact or comfortable spacing, your own wording for every label, and a sample discussion in the builder, so every setting shows before you save. WordPress keeps posting, moderation and replies.

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
27 settings+ 68 CSS variablesSee all
Tested on Etch
1.7.1
Tested on WordPress
7.1.3
Live demo

One discussion, every setting

Switch the theme, the page background, the density, the avatars, the Website field and the wording, then reply to a comment or post your own. Switch to Mobile for a phone width.

Live
  • Instances: 1
  • Themes: Inherit, Light, Dark
  • Live switches: 6
  • New comments: held for moderation
Open in a new tab
Features

What it does

One pasted component on top of WordPress’s own comments. No helper plugin, no PHP and no external script: the CSS and a small script travel with it.

  • Native WordPress inside

    The discussion is WordPress’s own comments block. Storage, moderation, threaded replies, validation and your anti-spam plugin keep working as they always have.

  • Light, dark or inherited

    Inherit takes the colors and color scheme of the section around it. Light and Dark draw a complete neutral palette that reads on any background.

  • Comfortable or compact

    Two spacing presets, for long reads and for tight layouts. Compact changes the spacing only; text, fields and buttons keep their size.

  • Your own wording

    18 Translations fields rename the title, the form, Reply, the button and the notes, with placeholders for the count, the author’s name and the required marker. Empty fields keep WordPress’s text.

  • Hide the Website field

    One switch hides and disables the optional Website field, so a remembered address is not sent. A Website field that a plugin makes required stays visible.

  • Previews in the builder

    Etch shows WordPress comments only as a placeholder, so the component adds a sample discussion to the canvas: replies, a pending comment, page links and the form. Every setting shows there before you save.

  • Accessible by default

    Native labels, required fields and validation, a visible focus ring, quotes and code that stay readable in every theme, and reply indents that leave room for words at 200% text size.

  • 68 styling variables

    Width, spacing, avatars, links, replies, the form, fields, the button, quotes and code, 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 a small script 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 Comments 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 into your post templateOpen the single post template, select the spot after the post content, press Ctrl+V or ⌘V and click Save. Etch adds the component to your list right away but stores its CSS only when you save. Use one instance per page and remove any other comment form there.
  3. Pick the look and the wordsIn the Properties panel choose a theme and a density. Rename any label in Translations, or leave them empty to keep WordPress’s wording.
  4. Check Settings → DiscussionWordPress decides who may comment, moderation, threading, avatars and page links. Save, open a post and try a reply.
Options

27 settings in the Etch props panel

Grouped as in the Etch props panel, where each setting has help text too, plus the intro slot. Nothing is required: pasted as it is, the discussion takes your page’s colors and WordPress’s wording. Every Translations field is empty by default and keeps WordPress’s text until you fill it.

One instance per page

WordPress gives the comment list and the form fixed IDs, so a page can hold only one ED Comments instance. Put it in the single post template, not in a query loop or an archive.

Etch cannot store an empty text field: clearing Empty Message or Closed Message brings the default back. To remove a message, set its visibility to Hidden.

Appearance

Themetheme
Inherit takes the colors and color scheme of the section around it. Light and Dark draw their own neutral surface, text and fields, so they work on any background.Default: Inherit
Densitydensity
Comfortable or Compact spacing. Compact keeps the text size and the size of fields and buttons.Default: Comfortable
Avatarsavatars
Follow WordPress shows avatars while Show Avatars is on in Settings → Discussion. Hidden removes the avatar column, but the images still download; turn Show Avatars off to stop those requests.Default: Follow WordPress

Messages

Empty HeadingemptyHeading
Heading of a post without approved comments. It is the discussion’s h2, so keep it meaningful.Default: Discussion
Empty MessageemptyMessage
Text below that heading.Default: No published comments yet.
Empty Message VisibilityemptyMessageVisibility
Show or Hidden. Hidden removes the empty-discussion message.Default: Show
Closed MessageclosedMessage
Shown when the post’s comments are closed, also when the age limit in Settings → Discussion closed them.Default: Comments are closed.
Closed Message VisibilityclosedMessageVisibility
Show or Hidden. Hidden removes the closed message.Default: Show

Form

Website fieldwebsiteField
Hidden hides and disables the optional Website field, so a remembered address is not sent. Without JavaScript it stays visible, and so does a Website field that a plugin makes required.Default: Show

Translations

Discussion titlelabels.commentsTitle
Title above the comments. %count% inserts the number of approved comments, such as Comments (%count%).Empty by default.
Form titlelabels.formTitle
Title of the form for a new comment.Empty by default.
Reply titlelabels.replyTitle
Title of the form while replying. %name% inserts the name of the person being answered.Empty by default.
Comment fieldlabels.commentLabel
Label of the comment field. The required marker stays.Empty by default.
Name fieldlabels.nameLabel
Label of the name field. The required marker stays.Empty by default.
Email fieldlabels.emailLabel
Label of the email field. The required marker stays.Empty by default.
Website fieldlabels.websiteLabel
Label of the optional Website field.Empty by default.
Submit buttonlabels.submitLabel
Text on the submit button.Empty by default.
Reply linklabels.replyLabel
Visible text of each Reply link.Empty by default.
Reply accessible namelabels.replyAccessibleLabel
What screen readers announce for Reply, such as Reply to %name%. It always keeps the visible Reply text.Empty by default.
Cancel replylabels.cancelReplyLabel
Text of the Cancel reply link.Empty by default.
Email privacy notelabels.emailNote
The note that the email address will not be published.Empty by default.
Required fields notelabels.requiredNote
Note about the required fields. %required% inserts the required marker; without it, the marker is added at the end.Empty by default.
Remember details labellabels.cookiesLabel
Label of the checkbox that remembers the name, email and website.Empty by default.
Moderation messagelabels.pendingMessage
Shown to the author of a comment that waits for moderation.Empty by default.
Previous comments pagelabels.previousLabel
Link to older comments when WordPress splits them into pages.Empty by default.
Next comments pagelabels.nextLabel
Link to newer comments.Empty by default.
Edit comment linklabels.editLabel
The Edit link that moderators see on each comment.Empty by default.

Slot

Introintro
Optional content above the discussion, such as house rules or a link to your comment policy. Don’t put another comment form in it; its links and buttons keep your site’s styling.Empty by default.
Styling: 68 CSS variables

Set them on the instance, on any parent element or class, or on :root for the whole site. They take precedence over the theme and density presets, so no extra selectors or !important are needed. Check contrast when you change colors.

Discussion

--ed-comments-width
Maximum width of the discussion.Default: 70ch
--ed-comments-padding
Outer padding. None in Inherit; Light and Dark take it from the density.Default: 0 in Inherit
--ed-comments-radius
Outer corner radius of the Light and Dark surfaces.Default: var(--radius, 0.75rem)
--ed-comments-background
Outer background. Set it to replace the Light or Dark surface.Default: transparent in Inherit
--ed-comments-color
Base text color. Set it to replace the theme’s text color.Default: inherit
--ed-comments-font-family
Font of the discussion.Default: inherit
--ed-comments-text-size
Text size.Default: var(--text-m, 1rem)
--ed-comments-line-height
Line height.Default: var(--text-line-height, 1.6)
--ed-comments-heading-size
Size of the discussion title.Default: var(--h4, 1.5rem)
--ed-comments-heading-weight
Weight of the titles.Default: var(--heading-font-weight, 600)
--ed-comments-transition
Color, background and border transitions. Reduced motion turns them off.Default: var(--transition, 180ms)

Spacing and replies

--ed-comments-comment-gap
Space around the title, the page links and the form.Default: var(--space-m, 1.5rem)
--ed-comments-content-gap
Gap between the parts of a comment.Default: var(--space-s, 1rem)
--ed-comments-comment-padding
Block padding of each comment. Compact uses var(–space-s, 1rem).Default: var(--space-m, 1.5rem)
--ed-comments-border
Color of the lines between comments: a color, not a border shorthand.Default: 14% currentColor
--ed-comments-reply-gap
Gap between a comment and its replies.Default: density gap × 0.75
--ed-comments-reply-indent
Indent of the first reply level. Deeper levels stay bounded, so replies keep room for text.Default: min(var(--space-s, 1rem), 6%)
--ed-comments-reply-border-width
Width of the line beside replies.Default: 1px
--ed-comments-reply-border-color
Color of the line beside replies.Default: var(--ed-comments-border)

Avatars, names and dates

--ed-comments-avatar-size
Width of the avatar column. Narrow containers use min(2rem, 32px).Default: 2.5rem
--ed-comments-avatar-gap
Gap between the avatar and the comment.Default: var(--space-s, 1rem)
--ed-comments-avatar-radius
Avatar corner radius.Default: 50%
--ed-comments-author-size
Size of the author name.Default: 1em
--ed-comments-author-weight
Weight of the author name.Default: 600
--ed-comments-meta-size
Size of the date and the Edit link.Default: var(--text-s, 0.875rem)
--ed-comments-meta-color
Color of the date and the Edit link. Light and Dark mute it to 72%.Default: inherit
--ed-comments-meta-gap
Gap between the date and the Edit link.Default: 0.5em
--ed-comments-note-color
Color of notes, such as the required fields note. Light and Dark mute it to 72%.Default: inherit

Links and actions

--ed-comments-link-color
Links in comments and notes. Light uses #3659ae, Dark #a9c2ff.Default: currentColor in Inherit
--ed-comments-link-hover-color
Link hover color. Light uses #234186, Dark #d1dfff.Default: currentColor in Inherit
--ed-comments-action-color
Reply, Edit and Cancel reply.Default: inherit
--ed-comments-action-hover-color
Hover color of those actions.Default: var(--ed-comments-action-color)
--ed-comments-action-hover-background
Hover background of those actions.Default: 7% currentColor

Focus

--ed-comments-focus
Keyboard focus outline color. Dark uses #93c5fd.Default: var(--focus-color, #2563eb)
--ed-comments-focus-width
Focus outline width.Default: 3px
--ed-comments-focus-offset
Focus outline offset.Default: 3px

Page links

--ed-comments-pagination-gap
Gap between the page links.Default: 0.5em
--ed-comments-pagination-radius
Corner radius of the page links.Default: var(--radius, 0.375rem)
--ed-comments-pagination-current-background
Background of the current page.Default: subtle theme surface
--ed-comments-pagination-current-color
Text color of the current page.Default: theme text color

Form

--ed-comments-form-padding
Inner spacing of the form panel. Compact uses var(–space-s, 1rem).Default: var(--space-m, 1.5rem)
--ed-comments-form-background
Background of the form panel.Default: subtle theme surface
--ed-comments-form-radius
Corner radius of the form panel.Default: var(--radius, 0.75rem)
--ed-comments-form-gap
Gap between the fields.Default: var(--space-s, 1rem)
--ed-comments-form-heading-size
Size of the form title: never smaller than the text, never larger than the discussion title.Default: var(--h5, 1.25rem)
--ed-comments-label-color
Field label color.Default: inherit
--ed-comments-label-weight
Field label weight.Default: 500

Fields

--ed-comments-field-min-height
Minimum height of the fields and the submit button.Default: 2.75rem
--ed-comments-field-padding
Inner spacing of the fields.Default: 0.65em 0.8em
--ed-comments-control-border
Field border color.Default: 55% text color
--ed-comments-field-radius
Field corner radius.Default: var(--radius, 0.5rem)
--ed-comments-field-background
Field background.Default: theme surface
--ed-comments-field-color
Field text color.Default: theme text color
--ed-comments-textarea-min-height
Starting and minimum height of the comment field.Default: 9rem
--ed-comments-field-placeholder-color
Placeholder text color.Default: 75% field text color

Submit button

--ed-comments-button-padding
Inner spacing.Default: var(--btn-padding-block, 0.65em) var(--btn-padding-inline, 1.25em)
--ed-comments-button-radius
Corner radius.Default: var(--btn-radius, 0.5rem)
--ed-comments-button-background
Background. Follows the ACSS button color when your site has one.Default: var(--btn-background), else theme text color
--ed-comments-button-color
Text color.Default: var(--btn-text-color), else theme surface
--ed-comments-button-font-size
Text size.Default: var(--btn-font-size, 1em)
--ed-comments-button-font-weight
Text weight.Default: var(--btn-font-weight, 500)
--ed-comments-button-hover-background
Hover background.Default: var(--btn-background-hover), else a mix
--ed-comments-button-hover-color
Hover text color.Default: var(--btn-text-color-hover)

Quotes and code

--ed-comments-quote-background
Background of quotes in comments.Default: 6% currentColor
--ed-comments-quote-color
Text color of quotes.Default: inherit
--ed-comments-quote-border
Color of the line beside quotes.Default: var(--ed-comments-border)
--ed-comments-code-background
Background of inline and block code.Default: 7% currentColor
--ed-comments-code-color
Text color of code.Default: inherit
Good to know

Before you place it

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

  • One instance per page. WordPress gives the comment list and the form fixed IDs, so Reply works with one discussion per page. Put it in the single post template, not in a query loop or an archive.
  • WordPress decides who can comment. Open or closed comments, moderation, threading, page links, avatars and required name and email come from Settings → Discussion and from each post.
  • Inherit needs a color scheme on dark sections. Declare color-scheme: dark on the dark section, or choose Dark, so the fields and the focus ring switch too.
  • Custom wording needs JavaScript. Without it, visitors see WordPress’s wording in the site language and the Website field stays visible. Posting and replies work either way.
  • Translations rename text; they don’t switch the language. Dates, login notices, error pages, browser validation and plugin text keep the WordPress site language. %count% has no plural forms, so choose wording such as Comments (%count%).
  • Hidden avatars still download. Avatars: Hidden hides the column only. To stop the requests to Gravatar, turn off Show Avatars in Settings → Discussion.
  • Your anti-spam plugin stays in charge. The component never sends comments itself. Spam filters, captchas and moderation run as usual, and some of them need JavaScript to post.
  • Not tested yet: NVDA and real phones. It was checked in Chrome, Firefox, Safari and Microsoft Edge, with VoiceOver on macOS, TalkBack on an Android emulator and Safari in the iOS Simulator.
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

None. This component is all my own code under FSL-1.1-MIT. WordPress supplies the comments themselves; the component bundles no library and loads no external script.

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 and Translations of your instance, and copy any CSS you changed in the component’s own styles.
  2. Delete the componentIn Etch, delete ED Comments from your components. The discussion disappears from the template that used it; the comments stay in WordPress.
  3. Delete its stylesIn the Style Manager, search for ed-comments and delete the four 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 the discussion backInsert ED Comments in your single post template again, re-enter its settings and save. Reload any other open builder tab.

Styles to delete in step 3

  • .ed-comments
  • .ed-comments__intro
  • .ed-comments__empty-heading
  • .ed-comments__notice

Trade-offs

  • Placements are not kept. Etch doesn’t link the old instance to the new component, so you insert it again and re-enter its settings. Your comments are untouched.
  • Edits inside the component’s CSS are replaced. Keep overrides on a parent class with the --ed-comments-* 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, Translations, 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
  • FixedThe date link under each author name and the Edit link are now at least 24 px high, the minimum target size of WCAG 2.2. On Etch sites the date link was only as tall as its line, right below a linked author name.
  • FixedOn phones and tablets, a tapped Reply link no longer keeps its hover background. Hover styles now need a mouse or trackpad; on the desktop nothing changes.
  • ChangedOnly the CSS of .ed-comments changed, so update the component and its styles together (see How to update). Props, classes and the 68 styling variables are the same.
  • TestedTalkBack on an Android emulator, Safari on iPhone and iPad in the iOS Simulator, and Microsoft Edge, on a live page. Two things are WordPress’s own and stay as they are: after Cancel reply, focus drops back to the page, and TalkBack doesn’t read the “Reply to …” title. It stays a beta until NVDA and real phones are tested.
1.0.0-beta.1
  • ReleasedFirst public version. It stays a beta until NVDA, iOS and Android devices 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.