Development Tips

HTML in 2026: What Still Matters When You Hand-Code a Page

By Ken Key Jul 22, 2025 5 min read Updated Oct 16, 2026

HTML in 2026: What Still Matters When You Hand-Code a Page
The short answer

Hand-code with semantic elements first: nav, main, article, header, dialog, and time do the work divs and libraries used to. Use native HTML before reaching for ARIA or JavaScript. Keep markup clean, machine-readable, and accessible, and most modern browsers handle the rest.

Part of the complete web development guide.

On this page

Most HTML tutorials you find online were written years ago and never updated. They teach you to wrap everything in divs, load a JavaScript library for a date picker, and reach for ARIA on elements that already have semantics built in. That advice was questionable then and it’s worse now. Here’s what actually matters when you write markup in 2026.

Semantic elements aren’t decoration

A <div> tells the browser nothing. A <nav>, <main>, or <article> tells it everything. Screen readers use these to build a page outline. Search engines use them to figure out what your content actually is. And you get free keyboard behavior in some cases without writing a line of JavaScript.

The rule I follow: if a native element exists for the job, use it. Reach for a div only when nothing else fits. That single habit fixes a surprising amount of accessibility debt before it starts.

<article>
 <header>
 <h1>Fixing a leaky roof in Commack</h1>
 <p>Published <time datetime="2026-03-14">March 14, 2026</time></p>
 </header>
 <p>The first thing to check is...</p>
</article>

Notice the <time> element with a machine-readable datetime. That’s the kind of small detail that helps crawlers and assistive tech alike.

The native elements that replaced a lot of JavaScript

This is the biggest shift in the last few years. Things we used to build with libraries are now plain HTML, and they work without a bundle.

Dialog

The <dialog> element gives you a real modal with focus trapping, backdrop, and Escape-to-close handled by the browser. No focus-trap library needed.

<dialog id="contact">
 <form method="dialog">
 <h2>Get in touch</h2>
 <label>Email <input type="email" name="email" required></label>
 <button value="cancel">Cancel</button>
 <button value="send">Send</button>
 </form>
</dialog>

<script>
 const dlg = document.getElementById('contact');
 document.querySelector('#open').addEventListener('click', () => dlg.showModal());
</script>

Popover

The popover attribute gives you tooltips, dropdowns, and menus with top-layer rendering and light-dismiss behavior. It’s supported across all major browsers now.

<button popovertarget="menu">Options</button>
<div id="menu" popover>
 <a href="/settings">Settings</a>
 <a href="/logout">Log out</a>
</div>

Details and summary

Accordions without JavaScript. The name attribute even makes them behave as an exclusive group, so opening one closes the others.

<details name="faq">
 <summary>Do you ship internationally?</summary>
 <p>Yes, to most countries.</p>
</details>

Forms got genuinely better

Client-side validation used to mean a validation library and a pile of event handlers. Native constraint validation covers most of it. Input types like email, url, and tel pull up the right mobile keyboard and validate for free.

<form>
 <label>
 Email
 <input type="email" name="email" required
 pattern=".+@.+..+">
 </label>
 <label>
 Zip
 <input type="text" name="zip" inputmode="numeric"
 pattern="d{5}" title="Five digit ZIP">
 </label>
 <button>Submit</button>
</form>

Two things people get wrong here. First, inputmode changes the on-screen keyboard without changing the field type, which is what you want for numeric codes. Second, never rely on client-side validation alone. It’s a convenience for the user, not a security boundary. Validate again on the server, always.

Lazy loading and modern image handling

The loading="lazy" attribute is still the simplest performance win on a content-heavy page. Pair it with srcset and you stop shipping a 3000px image to a phone.

<img
 src="photo-800.jpg"
 srcset="https://i0.wp.com/www.kennykey.com/photo-400.jpg 400w, https://i0.wp.com/www.kennykey.com/photo-800.jpg 800w, https://i0.wp.com/www.kennykey.com/photo-1600.jpg 1600w"
 sizes="(max-width: 600px) 100vw, 800px"
 width="800" height="600"
 loading="lazy"
 decoding="async"
 alt="A backyard deck in Commack after refinishing">

Always set width and height. That reserves space and stops the layout from jumping as images load, which is one of the biggest causes of a bad Core Web Vitals score.

What about ARIA?

The first rule of ARIA is don’t use ARIA if a native element already does the job. A <button> is keyboard focusable and announces as a button on its own. A <div role="button"> does none of that unless you rebuild the behavior by hand, and most people get it wrong.

Use ARIA for the gaps: live regions for dynamic content, aria-expanded on a toggle, labels for controls without visible text. Not as a patch for the wrong element.

Where hand-written HTML still wins

If you’re building a small site, a landing page, or a marketing site, hand-written semantic HTML is often faster to ship and easier to maintain than pulling in a framework. It loads quicker, it’s easier to debug, and you don’t inherit a build step you didn’t ask for. That’s the approach I take on most of the work I do as a custom web development project, whether it’s a local business site or something bigger.

Frameworks have their place. But the foundation is still HTML, and it’s worth knowing it well enough to not need a library for a dialog box.

FAQ

Do I still need a JavaScript framework to build a modern site?

No. For content sites, marketing pages, and most small business sites, semantic HTML plus a little vanilla JavaScript covers everything. Reach for a framework when you have real application state to manage, not by default.

Is ARIA required for accessibility?

Less than you’d think. Start with correct native elements and a logical heading order. Add ARIA only where the native options don’t exist, like live regions or custom widgets.

How do I check my markup is actually correct?

Run it through the W3C validator, then test with a keyboard only and a screen reader. Those three steps catch the overwhelming majority of problems before they reach a real user.

Have a project like this?

I do custom web development for Long Island businesses. If you need this done right, let’s talk.