Electrons - Circuit design system

HTML guidelines

Semantics, UX & Accessibility

Core principle: Use the right HTML element for the job. Every native element ships with free keyboard support, screen reader compatibility, and browser UX that no custom component can fully replicate.


Native elements first

Frameworks make it easy to replace native elements with custom ones. Resist that temptation.

Instead ofUse
<div onclick="..."><button> or <a href="...">
<div class="heading"><h1><h6> → see Headings
<div class="list"><ul>, <ol>, <dl> → see List
<div class="form-group"><fieldset> + <legend>

A <span onclick> won’t appear in the screen reader link list, won’t receive focus via Tab, and won’t show a browser context menu. ARIA can’t fix that.

<span onclick="navigate()">Learn more</span><a href="/learn-more">Learn more</a>

Forms: let the browser help

Use the right input type — the browser validates and adapts the mobile keyboard automatically.

<label for="email">Email</label>
<input type="email" id="email" required>
<label for="phone">Phone</label> <input type="tel" id="phone" required>

Always link <label> to its <input> via for/id or by nesting. An unlinked label is invisible to screen readers and reduces the tap target size. Use required, min, max, and pattern before reaching for JS validation.
See also: Input, Checkbox, Select.


Heading hierarchy

One <h1> per page. Avoid skipping levels. → Use CSS for visual size, not the heading level.

Screen readers and search engines navigate by heading structure. A broken hierarchy breaks that navigation. → Headings


Focus & keyboard

All interactive elements must be reachable and operable by keyboard (WCAG 2.1 AA). → Accessibility Guidelines


Images

<!-- Informative image: -->
<img src="chart.png" alt="Revenue Q1–Q4 2024">
<!-- Decorative image: empty alt, never omitted -->
<img src="divider.png" alt="">

A missing alt attribute is not neutral — screen readers will read out the filename.


ARIA: supplement, don’t replace

“No ARIA is better than bad ARIA.” — W3C

Only use ARIA when no native element covers the use case. role="button" on a <div> does not give you keyboard behavior. Always add aria-label to icon-only interactive elements:

<!-- ❌ role="button" on a div — no keyboard support, ARIA doing unnecessary work -->
<div role="button" onclick="closeMenu()">
  <svg>...</svg>
</div>

<!-- ✅ Native button + aria-label to describe the icon's purpose -->
<button aria-label="Close menu">
  <svg aria-hidden="true">...</svg>
</button>

HTML-first before JavaScript

NeedNative solution
Accordion<details> + <summary>
Popup / overlaypopover API
Modal dialog<dialog>
Progress indicator<progress>
Responsive images<picture> with srcset

Pre-merge checklist


Further reading

HTML guidelines skill

Load the Markdown file as knowledge into your projects and prompts, whenever you create a DEHN UI.

html_guidelines_skill.md