DEV Community

Lakshyaraj Dash
Lakshyaraj Dash

Posted on

10 useful html tags

10 Underrated HTML Tags That Will Replace Your Bloated JS Libraries

Live Demo: View the Interactive Docs

As web developers, we love custom JavaScript packages. We install third-party libraries for autocomplete dropdowns, modal managers, disclosure accordions, and custom progress indicators.

But every line of JavaScript we ship is code the browser has to download, parse, and execute. It increases page weight and introduces potential accessibility bugs.

Did you know that native HTML has built-in features that can replace a surprising amount of custom JS and CSS? In this post, we'll explore 10 underrated, highly semantic HTML elements that will help you write faster, cleaner, and more accessible code out of the box.


1. <datalist> (Native Autocomplete)

The Problem

Building a custom autocomplete dropdown usually requires a heavy select component library or complex JS event listeners to filter arrays and toggle menu visibility on keypress.

Why it matters

The <datalist> element acts as a native autocomplete menu linked to a standard <input> field.

  • Native Autocomplete: It filters values automatically based on user typing.
  • Custom entries allowed: Unlike a <select> drop-down, users can select an option or type their own custom text.
  • Form Integration: Works seamlessly inside any standard <form>.

Code Example

<label for="city-choice">Choose a city:</label>
<input id="city-choice" list="cities" placeholder="Start typing a city..." />

<datalist id="cities">
  <option value="Bhubaneswar" />
  <option value="Brahmapur" />
  <option value="Cuttack" />
  <option value="Puri" />
  <option value="Sambalpur" />
</datalist>
Enter fullscreen mode Exit fullscreen mode

2. <dialog> (Native Modals & Focus Trapping)

The Problem

Creating accessible modal overlays from scratch is notoriously difficult. You have to write custom JavaScript to handle background scroll blocking, trap the keyboard focus inside the modal (so users don't tab out into the background), and listen for the Escape key to close it.

Why it matters

The <dialog> tag represents a native overlay box that solves these challenges natively:

  • Automatic Focus Management: Tabbing is naturally restricted to the modal elements when opened with showModal().
  • Keyboard support: Pressing Escape closes the modal natively without a single line of JS.
  • Semantic backdrop: Style the background dimming using the ::backdrop CSS pseudo-element.
  • Clean API: Controlled using native methods: .show(), .showModal(), and .close().

Code Example

<button commandfor="contact-modal" command="show-modal">Open Modal</button>

<dialog id="contact-modal">
  <h2>Contact Form</h2>
  <form method="dialog">
    <label for="name">Name</label><br>
    <input type="text" id="name" required><br><br>

    <label for="email">Email</label><br>
    <input type="email" id="email" required><br><br>

    <button type="submit">Submit</button>
    <button type="button" commandfor="contact-modal" command="close">Close</button>
  </form>
</dialog>
Enter fullscreen mode Exit fullscreen mode

3. <details> + <summary> (No-JS Accordions)

The Problem

For collapsible cards, FAQs, or disclosures, developers often write JavaScript toggle functions, toggling classes like .is-open or .hidden.

Why it matters

The <details> and <summary> tags create a disclosure widget out-of-the-box:

  • Zero JS Accordions: Clicking the <summary> automatically expands the nested contents.
  • CSS hooks: The browser appends the open attribute natively. You can style the open state using the CSS details[open] selector.
  • SEO & Search Friendly: Text inside closed details tags is still indexed by search engine crawlers and is natively searchable using Ctrl+F.

Code Example

<details>
  <summary>What is HTML?</summary>
  <p>HTML (HyperText Markup Language) is the standard markup language used to structure pages on the web.</p>
</details>
Enter fullscreen mode Exit fullscreen mode

4. <progress> (Semantic Status Indicators)

The Problem

Creating progress bars usually involves nested <div> tags, a custom width style in CSS, and ARIA roles added manually for screen reader compatibility.

Why it matters

The <progress> element semantically represents the completion progress of a task:

  • Accessibility built-in: Screen readers inherently announce the value and max bounds without manually setting role="progressbar".
  • Indeterminate states: If you omit the value attribute, it natively renders a bouncing animation indicating a pending state (perfect for page loading spinners).

Code Example

<h2>File Upload</h2>
<progress value="75" max="100"></progress>
Enter fullscreen mode Exit fullscreen mode

5. <meter> (Scalar Range Gauges)

The Problem

Often, developers use <progress> or custom bars to display scalar values (e.g., password strength, disk usage, or ratings). This is semantically incorrect because a progress bar is meant to track completion, not a fixed measurement.

Why it matters

The <meter> tag is specifically designed for scalar measurements within a known range:

  • Intelligent thresholds: Supports advanced attributes: min, max, low, high, and optimum.
  • Auto-coloring: Browsers natively change the gauge color (e.g. Green for optimum, Yellow/Red for low/high) depending on the value and thresholds.

Code Example

<h2>Password Strength</h2>
<meter min="0" max="100" low="35" high="70" optimum="85" value="80">Strong</meter>
Enter fullscreen mode Exit fullscreen mode

6. <output> (Semantic Form Resulting)

The Problem

Form calculation results (like a shopping cart total) are usually outputted inside generic <span> or <div> tags, making it hard for screen readers to notice when the numbers update dynamically.

Why it matters

The <output> element represents the outcome of a user calculation:

  • Implicit ARIA live-region: Many screen readers treat the tag as a live region (aria-live="polite"), automatically reading the new calculation aloud to users when it changes.
  • Logical link: You can link it to the input fields that generated the value using the for attribute.

Code Example

<form oninput="result.value=Number(a.value)+Number(b.value)">
  <input type="number" id="a" value="10">
  +
  <input type="number" id="b" value="20">
  =
  <output name="result" for="a b">30</output>
</form>
Enter fullscreen mode Exit fullscreen mode

7. <mark> (Contextual Highlighting)

The Problem

Highlighting search query matches in text usually involves wrapping strings in a <span class="highlight"> styled with a yellow background.

Why it matters

The <mark> tag indicates text highlighted for reference or relevance:

  • Semantic meaning: Communicates relevance to search engine crawlers and accessibility utilities, not just visual styling.
  • Default Styles: Instantly applies a readable yellow background that is compatible with user dark mode preferences.

Code Example

<p>Modern developers should learn how to write <mark>semantic HTML</mark> first.</p>
Enter fullscreen mode Exit fullscreen mode

8. <kbd> (Keyboard Input Formatting)

The Problem

When writing technical documentation or tutorials, formatting keyboard shortcuts can look inconsistent if we only rely on generic inline code tags.

Why it matters

The <kbd> tag represents user keyboard input:

  • Nesting support: Nesting tags (like <kbd><kbd>Ctrl</kbd> + <kbd>C</kbd></kbd>) represents multi-key shortcuts clearly.
  • Monospace rendering: Rendered in monospace font by default for instant visual recognition.

Code Example

<p>Press <kbd>Ctrl</kbd> + <kbd>S</kbd> to save the document.</p>
Enter fullscreen mode Exit fullscreen mode

9. <time> (Machine-Readable Dates)

The Problem

Humans read dates in diverse formats (e.g. "December 25, 2026", "25/12/26"). Search engines and calendar APIs struggle to parse these correctly without semantic annotations.

Why it matters

The <time> element associates human-friendly dates with a standardized ISO date-time string:

  • SEO Benefits: Crawlers can index publication dates and schedule timings with 100% confidence.
  • Integration: Browsers and reader apps can parse the datetime attribute to add events straight to the user's calendar.

Code Example

<p>The conference is scheduled for <time datetime="2026-12-25">December 25, 2026</time>.</p>
Enter fullscreen mode Exit fullscreen mode

10. <template> (Inert DOM Fragments)

The Problem

Before framework components, creating reusable HTML fragments in vanilla JavaScript required writing long, unsafe innerHTML strings or hiding elements using display: none (which still downloaded active images and executed inline scripts).

Why it matters

The <template> tag holds HTML content that is not rendered when the page loads:

  • Inert content: Any media inside (images, video) doesn't load and scripts don't run until the template is instantiated.
  • Safe & Fast: Cloning the template node using document.importNode() or cloneNode(true) is significantly safer and faster than executing innerHTML.

Code Example

<!-- The markup below remains hidden and inert until cloned -->
<template id="productCard">
  <article style="border: 1px solid #ccc; padding: 15px; border-radius: 8px;">
    <h3>Wireless Mouse</h3>
    <p>Price: $10.00</p>
    <button>Add to Cart</button>
  </article>
</template>

<script>
  const temp = document.getElementById('productCard');
  const container = document.body;

  // Clone the template content (true for deep clone)
  const clone = temp.content.cloneNode(true);
  container.appendChild(clone);
</script>
Enter fullscreen mode Exit fullscreen mode

Wrap-up

These elements show that HTML is not just a layout tool; it is a feature-rich application layer. By choosing semantic HTML first, you:

  • Reduce your JS bundle size (making pages load faster).
  • Improve accessibility (a11y) out-of-the-box for assistive technologies.
  • Boost search engine indexability (SEO).

The next time you reach for a custom JS library to handle common UI interactions, check if native HTML can solve it first!

Happy coding! 🚀

Top comments (0)