HTML in 2026: What Still Matters and What You Can Ignore

HTML still matters in 2026, but less of it. Use semantic landmarks, one h1 per page, and headings in order. Skip XHTML self-closing slashes, most ARIA roles, and div soup. Browsers and screen readers handle clean, meaningful markup better than clever workarounds.
Part of the complete web development guide.
On this page
- Semantic elements are not optional anymore
- The stuff you can finally stop doing
- Forms: where most sites still lose people
- Images, lazy loading, and the LCP trap
- Modern image formats, handled simply
- Templates and custom elements, without a framework
- Accessibility basics that overlap with good HTML
- What’s actually changed in 2026
- The short version
- FAQ
- Do I still need to validate my HTML?
- Is it worth converting a div-based layout to semantic tags?
- Should I use a framework or plain HTML for a new site?
HTML didn’t go anywhere. It just stopped being the thing people argue about. Frameworks come and go, but every one of them still compiles down to the same markup the browser parses, and the browser in 2026 is pickier and more capable than it was five years ago. If you’re maintaining a site or building one, here’s what’s actually worth your time now.
Semantic elements are not optional anymore
Ten years ago you could get away with a pile of <div> tags and call it a layout. You can still do that, and it’ll render fine. But you lose a lot: screen readers have to guess at structure, search engines have less to work with, and your own CSS gets harder to reason about. The semantic tags are not decoration. They carry meaning.
<header>
<nav aria-label="Main">
<ul>
<li><a href="/services/">Services</a></li>
<li><a href="/work/">Work</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>What we do</h1>
<p>...</p>
</article>
</main>
<footer>
<p>© 2026</p>
</footer>
One <h1> per page. Headings in order. Landmarks where they belong. That’s most of it.
The stuff you can finally stop doing
A lot of the old advice is dead weight now. If you’re still carrying it around, drop it:
- XHTML-style self-closing tags.
<br />works but<br>is fine. Pick one and stop thinking about it. - Type attributes on scripts and styles.
<script type="text/javascript">and<style type="text/css">do nothing. Remove them. - Wrapping everything in tables. If you inherited a site built this way, it’s a rewrite, not a patch.
- Separate mobile markup. Responsive CSS handles this. You do not need a second set of pages.
- Chasing perfect validation scores. Valid markup is good. Obsessing over a validator’s opinion of attributes you added on purpose is not.
Forms: where most sites still lose people
Native form validation got good and most people ignore it. You can skip a lot of JavaScript if you use the right attributes and let the browser do the work.
<form action="/contact" method="post">
<label for="email">Email</label>
<input
type="email"
id="email"
name="email"
required
autocomplete="email"
inputmode="email">
<label for="zip">ZIP code</label>
<input
type="text"
id="zip"
name="zip"
required
pattern="[0-9]{5}"
inputmode="numeric"
autocomplete="postal-code">
<button type="submit">Send</button>
</form>
inputmode is the one people forget. On a phone it’s the difference between a numeric keypad and fighting with a full keyboard to type a ZIP code. For a local business taking service requests, that single attribute cuts real friction.
Images, lazy loading, and the LCP trap
Native lazy loading is free and you should use it. But there’s a mistake I see constantly: lazy-loading the hero image. That image is usually your Largest Contentful Paint element, and deferring it makes your page feel slower, not faster.
<!-- Hero: load it now, prioritize it -->
<img
src="/img/hero.avif"
alt="Storefront on Main Street"
width="1200"
height="600"
fetchpriority="high">
<!-- Below the fold: lazy load -->
<img
src="/img/gallery-1.avif"
alt="Interior detail"
width="800"
height="600"
loading="lazy"
decoding="async">
Always set width and height. It reserves space so the layout doesn’t jump while the image loads. That’s not a nice-to-have, it’s a Core Web Vitals item.
Modern image formats, handled simply
AVIF and WebP have solid support now. The old advice was to build a pile of <source> fallbacks. That’s mostly unnecessary, but a single fallback is still cheap insurance:
<picture>
<source srcset="/img/photo.avif" type="image/avif">
<img src="https://i0.wp.com/www.kennykey.com/img/photo.jpg" alt="Team at work" width="800" height="600">
</picture>
Templates and custom elements, without a framework
If you need a small interactive piece, you don’t always need React. The <template> element plus a custom element gets you a long way, and it ships zero dependencies.
<template id="row-tpl">
<li class="row"><span class="name"></span></li>
</template>
<script type="module">
class NameList extends HTMLElement {
connectedCallback() {
const tpl = document.getElementById('row-tpl');
this.append(tpl.content.cloneNode(true));
}
}
customElements.define('name-list', NameList);
</script>
For a marketing site or a small internal tool, this is often the whole job. Reaching for a full framework to render a list is how projects get heavier than they need to be. If you’re weighing that tradeoff for a business site, that’s the kind of call that comes up in custom web development work all the time, and the answer is usually “use less.”
Accessibility basics that overlap with good HTML
Most accessibility problems are markup problems, not design problems. Fix these and you’ve handled the majority:
- Every image needs an
alt. Decorative images getalt="". - Every form input needs a
<label>tied byfor/id. - Buttons that do things are
<button>. Links that go somewhere are<a>. Don’t swap them. - Don’t remove focus outlines without replacing them with something visible.
- Use
langon the<html>element.
What’s actually changed in 2026
A few things worth knowing if you’ve been out of the weeds:
- Popover and dialog are standard.
popoverand<dialog>handle a lot of the modal work people used to write libraries for. - View transitions are broadly usable. Smooth page and element transitions without a JS animation library.
- Container queries are normal. Style components based on their container, not the viewport. This changed how people write CSS more than any HTML change.
- AI-generated markup is everywhere and often wrong. It writes invalid nesting, duplicate IDs, and missing labels constantly. Review it like you’d review a junior dev’s pull request.
The short version
Write semantic markup. Use native form validation and the right input modes. Set image dimensions, lazy-load below the fold, prioritize your hero. Reach for JavaScript only when the browser can’t do it. None of this is exciting, and that’s the point. Good HTML is boring, and boring markup is what makes everything built on top of it hold up.
FAQ
Do I still need to validate my HTML?
Run it through the W3C validator once in a while. It catches real mistakes like unclosed tags and duplicate IDs. Just don’t treat a warning about an attribute you added on purpose as a failure.
Is it worth converting a div-based layout to semantic tags?
If the site is otherwise fine, do it incrementally when you touch each page. A full rewrite just for semantics usually isn’t worth the risk. Fix it as you go.
Should I use a framework or plain HTML for a new site?
For a marketing site, a blog, or a small business site, plain HTML with a bit of CSS and light JavaScript is faster to build, faster to load, and easier to maintain. Save the frameworks for apps that genuinely need state management.


