HTML / CSS
Published 2 Jun 2025 · Updated 11 Jul 2026

8 Underused HTML Elements for Better UX

Native HTML can solve disclosure, modal, suggestion, progress, date, highlighting, and caption problems before you reach for another component library. The eight groups below are useful because they add browser behavior and semantic meaning, not because they guarantee accessibility or SEO by themselves. Each example includes the case it fits, the detail most likely to cause trouble, and a living MDN support reference instead of a browser-usage percentage that will go stale.

1. <details> and <summary>

When to use them

Use a disclosure widget for optional explanations, troubleshooting steps, or compact FAQ answers. The first summary child becomes the control, and the remaining content expands without a custom click handler.

Accessibility and common pitfall

Write a summary that describes what will open. Do not place essential instructions behind a closed disclosure, and do not remove the browser's focus indicator. The element supplies disclosure semantics, but the content still needs useful headings and link text.
<details>
  <summary>Why did my deployment fail?</summary>
  <p>The build requires Node.js 20.9 or newer.</p>
</details>
MDN reference for details and summary

2. <dialog>

When to use it

Use dialog when the user must complete or dismiss a focused task, such as confirming a destructive action. Calling showModal() places the dialog in the top layer and makes the rest of the page inert while it is open.

Accessibility and common pitfall

Give the dialog a visible heading and connect it with aria-labelledby. Always provide a clear close path. Avoid opening a modal automatically on page load, and do not build a modal by toggling the open attribute when you need the modal focus and top-layer behavior of showModal().
<button type="button" id="open-delete-dialog">Delete project</button>

<dialog id="delete-dialog" aria-labelledby="delete-dialog-title">
  <h2 id="delete-dialog-title">Delete this project?</h2>
  <p>This action cannot be undone.</p>
  <form method="dialog">
    <button value="cancel">Cancel</button>
    <button value="confirm">Delete</button>
  </form>
</dialog>

<script>
  const dialog = document.querySelector("#delete-dialog");
  const openButton = document.querySelector("#open-delete-dialog");

  openButton.addEventListener("click", () => dialog.showModal());
  dialog.addEventListener("close", () => {
    if (dialog.returnValue === "confirm") deleteProject();
  });
</script>
MDN reference for dialog

3. <template>

When to use it

Use template to keep an inert fragment of markup that JavaScript will clone later. It works well for small repeated UI fragments or Web Component internals when rendering on the client is intentional.

Accessibility and common pitfall

Template contents are not rendered, focused, or exposed as page content until cloned into the document. Do not put critical fallback information only inside a template. After cloning, update IDs and accessible names so repeated instances remain unique.
<template id="user-card-template">
  <article class="user-card">
    <h2></h2>
    <p></p>
  </article>
</template>

<script>
  const template = document.querySelector("#user-card-template");
  const card = template.content.cloneNode(true);

  card.querySelector("h2").textContent = "Ada Lovelace";
  card.querySelector("p").textContent = "Frontend engineer";
  document.querySelector("main").append(card);
</script>
MDN reference for template

4. <datalist>

When to use it

Use datalist when an input should suggest common values while still allowing the user to type another valid value. It is not the same as a required select menu.

Accessibility and common pitfall

Browser and assistive-technology behavior varies, so keep a visible label and accept manual input. Validate the submitted value on the server; a datalist is a suggestion source, not a validation rule. Use select when the value must come from a closed list.
<label for="deployment-region">Deployment region</label>
<input id="deployment-region" name="region" list="region-suggestions">

<datalist id="region-suggestions">
  <option value="Amsterdam"></option>
  <option value="Frankfurt"></option>
  <option value="London"></option>
</datalist>
MDN reference for datalist

5. <progress>

When to use it

Use progress for the completion state of a task, such as an upload or multi-step calculation. Include valuefor determinate progress; omit it when the total progress is unknown.

Accessibility and common pitfall

Provide a visible label and a text value that still communicates the state when the bar is not visible. Do not use progressfor a static measurement such as disk usage or a score; the meter element represents a value within a known range.
<label for="upload-progress">Uploading video: 62%</label>
<progress id="upload-progress" value="62" max="100">62%</progress>

<label for="processing-progress">Processing video</label>
<progress id="processing-progress">Processing</progress>
MDN reference for progress

6. <time>

When to use it

Use time when a human-readable date, time, duration, or timezone-aware timestamp should also have a machine-readable value. It is useful for event schedules, publication dates, and durations.

Accessibility and common pitfall

The visible text should make sense to a person without relying on the datetime attribute. Use a valid machine-readable value and include a timezone when the exact instant matters.
<p>
  Published on <time datetime="2026-07-11">July 11, 2026</time>
</p>

<p>
  Livestream starts at
  <time datetime="2026-07-11T18:00:00+03:00">6:00 PM in Istanbul</time>
</p>
MDN reference for time

7. <mark>

When to use it

Use mark to show text that is relevant in the current context, such as matching terms in search results or the passage a review comment refers to.

Accessibility and common pitfall

Do not use mark only to make text yellow, and do not use it as a substitute for strong emphasis. Screen readers do not consistently announce highlighting, so the surrounding text must explain why the marked phrase matters.
<p>
  Three results contain <mark>hydration mismatch</mark>.
</p>
MDN reference for mark

8. <figure> and <figcaption>

When to use them

Use figure for self-contained content referenced from the main prose, including an image, chart, code listing, or diagram. A figcaption supplies the caption for that complete unit.

Accessibility and common pitfall

A caption does not replace image alternative text. The alt text describes the meaningful visual information; the figcaption provides context, interpretation, or attribution for the whole figure.
<figure>
  <img
    src="bundle-size-chart.png"
    alt="Bundle size falls from 180 KB to 124 KB after code splitting"
  >
  <figcaption>
    Figure 1: Production JavaScript before and after route-level splitting.
  </figcaption>
</figure>
MDN reference for figure and figcaption

A practical native HTML checklist

Before shipping a custom component

  • Start with the semantic element: Confirm whether HTML already models the interaction or content.
  • Test keyboard behavior: Reach, operate, close, and leave the component without a pointer.
  • Keep visible labels: Native behavior does not replace clear instructions and accessible names.
  • Test the failure path: Check disabled JavaScript, rejected requests, invalid input, and repeated actions.
  • Verify current support: Use the living MDN reference instead of copying a browser percentage into documentation.
HTML & CSS: semantic markup, modern styling, and browser capabilities.