Why Semantic HTML Still Matters

## Metadata
- Author: [[Jono Alderson]]
- Full Title: Why Semantic HTML Still Matters
- Category: #articles
- Document Note: ---
tags: [#SEO, #SemanticHTML, #Accessibility, #Performance]
Author: Jono Alderson
Source: JonoAlderson.com
Reference: [Why Semantic HTML Still Matters](https://www.jonoalderson.com/conjecture/why-semantic-html-still-matters/)
date created: 2025-07-28 08:30
---
# Title: Why Semantic HTML Still Matters
## Table of Contents:
- [📝 Summary](#-summary)
- [📖 Main Content](#-main-content)
- [🗒️ Notes](#️-notes)
- [📖 References](#-references)
- [🗣️ Paraphrase](#️-paraphrase)
- [📰 Newsletter](#-newsletter)
- [✅ Action Items](#-action-items)
- [🧪 Hypotheses](#-hypotheses)
- [📊 Methodology](#-methodology)
- [❓ Questions](#-questions)
- [🔮 Future Research](#-future-research)
- [💡 Implications](#-implications)
- [🧠 Learning Styles Assessment](#-learning-styles-assessment)
- [📊 Accessibility Assessment](#-accessibility-assessment)
- [🌍 DEIB (Diversity, Equity, Inclusion, and Belonging) Assessment](#-deib-diversity-equity-inclusion-and-belonging-assessment)
- [✅ Logical validity](#-logical-validity)
- [🔍 DARVO Analysis](#-darvo-analysis)
- [🔍 SEO Evaluation](#-seo-evaluation)
- [🎯 Conclusion](#-conclusion)
## 📝 Summary:
Jono Alderson argues that the modern web has deprioritized semantic HTML, resulting in performance, accessibility, and resilience issues. He emphasizes HTML as a language of meaning, not just layout, showing how semantic tags benefit search engines, assistive tech, and AI agents. He critiques “div soup,” CSS bloat, and hashed class names for undermining performance and maintainability, and outlines how semantic structure enhances rendering efficiency, accessibility, and future-proofing in an era of AI-driven content parsing.
## 📖 Main Content:
Alderson highlights:
- Semantic HTML as a core for meaning, accessibility, and performance.
- Modern component-based development often strips markup of intent.
- Proper structure enables assistive tech, AI agents, and search engines to interpret content correctly.
- Excessive abstraction, hashed classes, and redundant CSS harm performance and maintainability.
- Semantic tags provide natural layout segmentation aiding browser rendering pipelines.
- Clean markup ensures resilience when JavaScript or CSS fail.
### 🗒️ Notes
- **Semantic HTML as Language**
- HTML tags express intent, not just structure.
- `<article>`, `<nav>`, `<section>` inform hierarchy and relationships.
- Machines and people benefit from meaningful markup.
- **“Div Soup” Problem**
- Utility-class-heavy markup loses meaning.
- Screen readers, crawlers, and scrapers cannot infer context.
- Semantic equivalents are more accessible and maintainable.
- **Accessibility**
- Clean markup critical for assistive technologies.
- Screen readers and keyboard users rely on structural cues.
- **Performance Costs**
- Large DOMs increase rendering overhead.
- Deep nesting and wrapper bloat cause layout thrashing.
- Redundant CSS leads to high recalculation costs.
- Ephemeral classes break caching and increase churn.
- **Rendering and Animations**
- Semantic structure allows effective GPU compositing.
- Messy DOMs cause layout shifts and animation jank.
- Tools like `contain` and `content-visibility` require structural coherence.
- **AI and Agents**
- Web content is now parsed by AI, assistants, and scrapers.
- Semantic structure creates a competitive edge in machine interpretation.
- **Resilience**
- Semantic HTML provides a usable baseline when assets fail.
- Clean markup aids debugging and progressive enhancement.
## 📖 References:
- Alderson, Jono. “Why Semantic HTML Still Matters.” *JonoAlderson.com*, 21 July 2025.
## 🗣️ Paraphrase:
1. *Original*: “If everything is a `<div>` or a `<span>`, then nothing is meaningful.”
*Paraphrase*: When markup is only generic containers, the content loses all semantic value.
2. *Original*: “Semantic HTML is a foundation. It’s fast. It’s robust. It’s self-descriptive. It’s future-facing.”
*Paraphrase*: Structured, meaningful markup forms the core of performant, resilient, and adaptable web design.
## 📰 Newsletter:
**🎨 Why Semantic HTML Still Rules the Web**
In this week’s newsletter, we revisit the foundation of web development: semantic HTML. Jono Alderson reminds us that meaningful markup isn’t just nostalgia—it’s the key to performance, accessibility, and making your site ready for AI-driven search. Skip the “div soup,” embrace `<article>` and `<section>`, and build sites that both humans and machines understand. [Read more →](https://www.jonoalderson.com/conjecture/why-semantic-html-still-matters/)
## ✅ Action Items:
- Integrate semantic HTML guidance into WordPress contributor education materials.
- Advocate for accessibility-first markup in GoDaddy’s OSPO initiatives.
- Incorporate semantic HTML checks into developer onboarding and training.
- Use Alderson’s insights to align open-source projects with sustainable, inclusive development practices.
## 🧪 Hypotheses:
- Sites using semantic HTML achieve lower INP (Interaction to Next Paint) scores.
- Semantic markup improves AI agent content extraction accuracy.
- Structured HTML reduces long-term maintenance costs in large projects.
### 📊 Methodology:
- Perform A/B testing comparing semantic vs. non-semantic markup on identical content.
- Measure INP, LCP, and accessibility scores via Lighthouse.
- Use AI agents to extract structured data and compare accuracy.
### ❓ Questions:
- How does semantic HTML impact SEO in AI-driven search engines?
- Can frameworks enforce semantic defaults without slowing teams?
- What are effective tooling strategies to prevent “div soup” in large-scale apps?
### 🔮 Future Research:
- AI parsing models trained on semantic vs. generic markup.
- Longitudinal studies on maintainability and bug rates in semantically structured codebases.
- Accessibility outcomes in semantic vs. utility-class-heavy sites.
### 💡 Implications:
- Strengthening semantic markup standards could influence web frameworks and policy.
- Improved accessibility aligns with inclusive design mandates.
- Performance gains reduce energy use, aiding sustainable web initiatives.
## 🧠 Learning Styles Assessment:
- **Visual**: Code examples provide visual structure; could benefit from diagrams of DOM trees.
- **Aural**: No audio; adding a podcast or audio summary would help.
- **Verbal**: Rich explanations and analogies present.
- **Physical**: Could add exercises for refactoring non-semantic markup.
- **Logical**: Clear cause/effect reasoning on performance impacts.
- **Social**: Could encourage group code reviews for semantic HTML.
- **Solitary**: Reflection prompts on personal code habits could be added.
- **Naturalistic**: Lacks environmental analogies; could draw parallels to ecosystems and structure.
## 📊 Accessibility Assessment:
- Advocates for proper semantic structure aiding screen readers.
- Improvement: Include explicit ARIA examples and alt-text guidelines.
## 🌍 DEIB (Diversity, Equity, Inclusion, and Belonging) Assessment:
- **Inclusive Language**: Neutral and accessible.
- **Neurodiversity Support**: Clear structure and headers support ADHD/ASD readers.
- **Representation**: Technical; could include diverse use cases (e.g., accessibility for different disabilities).
## ✅ Logical validity:
- **Sound Deductive Reasoning**: Semantic HTML → Better accessibility → Better UX.
- **Causal Reasoning**: Explains performance bottlenecks tied to DOM structure.
- **Appeal to Facts/Evidence**: References Chrome DevTools and browser rendering pipelines.
- **No major fallacies detected**: Arguments are grounded in technical reasoning, not emotion.
## 🔍 DARVO Analysis:
- **Deny**: None present.
- **Attack**: Critiques practices, not individuals.
- **Reverse Victim and Offender**: Not applicable. Tone is constructive, not defensive.
## 🔍 SEO Evaluation:
- **Keywords**: “Semantic HTML,” “performance,” “accessibility” naturally integrated.
- **Meta Description**: Should summarize benefits of semantic HTML.
- **Headers**: Effective H1 and subheadings.
- **Content Length**: Meets long-form SEO standards.
- **Internal/External Links**: Could link to MDN and W3C specs for authority.
- **Image Optimization**:
- Summary: If you want to build for performance, accessibility, discoverability, or resilience, you must start with HTML that means something.
- URL: https://www.jonoalderson.com/conjecture/why-semantic-html-still-matters/?%20Migrating%20Legacy%20WP%20-%2018426795#utm_source=convertkit&utm_medium=email&utm_campaign=A%20New%20WordPress%20Dashboard,%20Remote%20Data%20Blocks%20

Somewhere along the way, we forgot how to write HTML – or why it mattered in the first place.
Modern development workflows prioritise components, utility classes, and JavaScript-heavy rendering. HTML becomes a *byproduct*, not a *foundation*.
And that shift comes at a cost – in performance, accessibility, resilience, and how machines (and people) interpret your content.
I’ve written elsewhere about [how JavaScript is killing the web](https://www.jonoalderson.com/conjecture/javascript-broke-the-web-and-called-it-progress/). But one of the most fixable, overlooked parts of that story is **semantic HTML**.
This piece is about what we’ve lost – and why it still matters.
#### Semantic HTML is how machines understand meaning
HTML isn’t just how we place elements on a page. It’s a *language* – with a vocabulary that expresses meaning
Tags like `<article>`, `<nav>` and `<section>` aren’t *decorative*. They express *intent*. They signal *hierarchy*. They tell machines what your content *is*, and how it *relates* to everything else.
Search engines, accessibility tools, AI agents, and task-based systems all rely on structural signals – sometimes explicitly, sometimes heuristically. Not every system requires perfect markup, but when they can take advantage of it, semantic HTML can give them clarity. And in a web full of structurally ambiguous pages, that clarity can be a competitive edge.
Semantic markup doesn’t guarantee better indexing or extraction – but it creates a foundation that systems can use, now and in the future. It’s a signal of *quality*, *structure*, and *intent*.
If everything is a `<div>` or a `<span>`, then nothing is *meaningful*.
#### It’s not just bad HTML – it’s meaningless markup
It’s easy to dismiss this as a purity issue. Who cares whether you use a `<div>` or a `<section>`, as long as it looks right?
But this isn’t about pedantry. Meaningless markup doesn’t just make your site harder to read – it makes it harder to *render*, harder to *maintain*, and harder to *scale*.
This kind of abstraction leads to markup that often looks like this:
```
<div class="tw-bg-white tw-p-4 tw-shadow tw-rounded-md">
<div class="tw-flex tw-flex-col tw-gap-2">
<div class="tw-text-sm tw-font-semibold tw-uppercase tw-text-gray-500">ACME Widget</div>
<div class="tw-text-xl tw-font-bold tw-text-blue-900">Blue Widget</div>
<div class="tw-text-md tw-text-gray-700">Our best-selling widget for 2025. Lightweight, fast, and dependable.</div>
<div class="tw-mt-4 tw-flex tw-items-center tw-justify-between">
<div class="tw-text-lg tw-font-bold">$49.99</div>
<button class="tw-bg-blue-600 tw-text-white tw-px-4 tw-py-2 tw-rounded hover:tw-bg-blue-700">Buy now</button>
</div>
</div>
</div>
```
Sure, this works. It’s styled. It renders. But it’s semantically dead.
It gives you no sense of what this content is. Is it a product listing? A blog post? A call to action?
You can’t tell at a glance – and neither can a screen reader, a crawler, or an agent trying to extract your pricing data.
Here’s the same thing with meaningful structure:
```
<article class="product-card">
<header>
<p class="product-brand">ACME Widget</p>
<h2 class="product-name">Blue Widget</h2>
</header>
<p class="product-description">Our best-selling widget for 2025. Lightweight, fast, and dependable.</p>
<footer class="product-footer">
<span class="product-price">$49.99</span>
<button class="buy-button">Buy now</button>
</footer>
</article>
```
Now it tells a *story*. There’s *structure*. There’s *intent*. You can target it in your CSS. You can extract it in a scraper. You can navigate it in a screen reader. It means something.
Semantic HTML is the foundation of accessibility. Without structure and meaning, assistive technologies can’t parse your content. Screen readers don’t know what to announce. Keyboard users get stuck. Voice interfaces can’t find what you’ve buried in divs. Clean, meaningful HTML isn’t just good practice – it’s how people access the web.
That’s not to say frameworks are inherently bad, or inaccessible. Tailwind, atomic classes, and inline styles can absolutely be useful – especially in complex projects or large teams where consistency and speed matter. They can reduce cognitive overhead. They can improve velocity.
But they’re *tools*, not *answers*. And when every component devolves into a soup of near-duplicate utility classes – tweaked for every layout and breakpoint – you lose the plot. The structure disappears. The purpose is obscured.
This isn’t about abstraction. It’s about what you lose in the process.
And that loss doesn’t just hurt semantics – it hurts *performance*. In fact, it’s one of the biggest reasons the modern web feels slower, heavier, and more fragile than ever.
#### Semantic rot wrecks performance
We’ve normalised the idea that HTML is just a render target – that we can throw arbitrary markup at the browser and trust it to figure it out. And it does. Browsers are astonishingly good at fixing our messes.
But that forgiveness has a *cost*.
Rendering engines are designed to be fault-tolerant. They’ll infer roles, patch up bad structure, and try to render things as you intended. But every time they have to do that – every time they have to guess what your `<div>` soup is *trying* to be – it costs time. That’s CPU cycles. That’s GPU time. That’s power, especially on mobile.
Let’s break down where and how the bloat hits hardest – and why it matters.
##### Big DOMs are slow to render
Every single node in the DOM adds overhead. During rendering, the browser walks the DOM tree, builds the CSSOM, calculates styles, resolves layout, and paints pixels. More nodes mean more work at each stage.
It’s not just about download size (though that matters too – more markup means more bytes, and *potentially* less efficient compression). It’s about render performance. A bloated DOM means longer layout and paint phases, more memory usage, and higher energy usage.
Even simple interactions – like opening a modal or expanding a list – can trigger reflows that crawl through your bloated DOM. And suddenly your “simple” page lags, stutters, or janks.
You can see this in Chrome DevTools. Open the *Performance* tab, record a trace, and watch the flame chart light up every time your layout engine spins it’s wheels.
> Fun fact: parsing isn’t the bottleneck — browsers like Chromium can process HTML at tens of GB/s on modern CPUs. The real cost comes during CSSOM construction, layout, paint, and composite. Also, HTML parsing is blocking only when you hit a non-deferred `<script>` or unlinked stylesheet – which again underscores why clean markup still matters, but you also need smart loading order.
>
>
##### Complex trees cause layout thrashing
But it’s not just about how much markup you have – it’s about how it’s structured. Deep nesting, wrapper bloat, and overly abstracted components create DOM trees that are hard to reason about and costly to render. The browser has to work harder to figure out what changes affect what – and that’s where things start to fall apart.
Toggle a single class, and you might invalidate layout across the entire viewport. That change cascades through parent-child chains, triggering layout shifts and visual instability. Components reposition themselves unexpectedly. Scroll anchoring fails, and users lose their position mid-interaction. The whole experience becomes unstable.
And because this all happens in real time – on every interaction – it hits your frame budget. Targeting 60fps? That gives you just ~16ms per frame. Blow that budget, and users feel the lag instantly.
You’ll see it in Chrome’s DevTools – in the “*Layout Shift Regions*” or in the “*Frames*” graph as missed frames stack up.
> When you mutate the DOM, browsers don’t *always* re-layout the whole tree – there’s incremental layout processing. But deeply nested or ambiguous markup still triggers expensive ancestor checks. Projects like Facebook’s “Spineless Traversal” show that browsers still pay a performance penalty when many nodes need checking.
>
>
##### Redundant CSS increases recalculation cost
A bloated DOM is bad enough – but bloated stylesheets make things even worse.
Modern CSS workflows – especially in componentised systems – often lead to duplication. Each component declares its own styles – even when they repeat. There’s no cascade. No shared context. Specificity becomes a mess, and overrides are the default.
For example, here’s what that often looks like:
```
/* button.css */
.btn {
background-color: #006;
color: #fff;
font-weight: bold;
}
/* header.css */
.header .btn {
background-color: #005;
}
/* card.css */
.card .btn {
background-color: #004;
}
```
Each file redefines the same thing. The browser has to parse, apply, and reconcile all of it. Multiply this by *hundreds* of components, and your CSSOM – the browser’s internal model of all CSS rules – balloons.
Every time something changes (like a class toggle), the browser has to re-evaluate which rules apply where. More rules, more recalculations. And on lower-end devices, that becomes a bottleneck.
Yes, atomic CSS systems like Tailwind can reduce file size and increase reuse. But only when used intentionally. When every component gets wrapped in a dozen layers of utility classes, and each utility is slightly tweaked (margin here, font there), you end up with thousands of unique combinations – many of which are nearly identical.
The cost isn’t just size. It’s churn.
> Browsers match selectors from right to left (e.g., for `div.card p span`, they check → parent → etc). This is efficient for clear, specific selectors – but bloated deep trees or generic cascading rules force lots of overs canning.
>
>
##### Autogenerated classes break caching and targeting
It’s become common to see class names like `.sc-a12bc`, `.jsx-392hf`, or `.tw-abc123`. These are often the result of CSS-in-JS systems, scoped styles, or build-time hashing. The intent is clear: localise styles to avoid global conflicts. And that’s not a bad idea.
But this approach comes with a different kind of *fragility*.
If your classes are ephemeral – if they change with every build – then:
* Your analytics tags break.
* Your end-to-end tests need constant maintenance.
* Your caching strategies fall apart.
* Your markup diffs become unreadable.
* And your CSS becomes non-reusable by default.
From a performance perspective, that last point is critical. Caching only works when things are predictable. The browser’s ability to cache and reuse parsed stylesheets depends on consistent selectors. If every component, every build, every deployment changes its class names, the browser has to reparse and reapply everything.
Worse, it forces tooling to rely on brittle workarounds. Want to target a button in your checkout funnel via your tag manager? Good luck if it’s wrapped in three layers of hashed components.
This isn’t hypothetical. It’s a common pain point in modern frontend stacks, and one that bloats everything – code, tooling, rendering paths.
Predictable, semantic class names don’t just make your life easier. They make the web faster.
##### Semantic tags can provide layout hints
Semantic HTML isn’t just about meaning or accessibility. It’s scaffolding. Structure. And that structure gives both you and the browser something to work with.
Tags like `<main>`, `<nav>`, `<aside>`, and `<footer>` aren’t just semantic – they’re block-level by default, and they naturally segment the page. That segmentation often lines up with how the browser processes and paints content. They don’t guarantee performance wins, but they create the conditions for them.
When your layout has clear boundaries, the browser can scope its work more effectively. It can isolate style recalculations, avoid unnecessary reflows, and better manage things like scroll containers and sticky elements.
More importantly: in the *paint* and *composite* phases, the browser can distribute rendering work across multiple threads. GPU compositing pipelines benefit from well-structured DOM regions – especially when they’re paired with properties like `contain: paint` or `will-change: transform`. By creating isolated layers, you reduce the overhead of re-rasterising large portions of the page.
If everything is a giant stack of nested `<div>`s, there’s no clear opportunity for this kind of isolation. Every interaction, animation, or resize event risks triggering a reflow or repaint that affects the entire tree. You’re not just making it harder for yourself – you’re bottlenecking the rendering engine.
Put simply: semantic tags help you work *with* the browser instead of *fighting* it. They’re not magic, but they make the magic possible.
##### Animations and the compositing catastrophe
Animations are where well-structured HTML either shines… or fails catastrophically.
Modern browsers aim to offload animation work to the GPU. That’s what enables silky-smooth transitions at 60fps or higher. But for that to happen, the browser needs to isolate the animated element onto its own compositing layer. Only certain CSS properties qualify for this kind of GPU-accelerated treatment – most notably `transform` and `opacity`.
If you animate something like `top`, `left`, `width`, or `margin`, you’re triggering the layout engine. That means recalculating layout for everything downstream of the change. That’s main-thread work, and it’s expensive.
On a simple page? Maybe you get away with it.
On a deeply nested component with dozens of siblings and dependencies? Every animation becomes a layout thrash. And once your animation frame budget blows past 16ms (the limit for 60fps), things get janky. Animations stutter. Interactions lag. Scroll becomes sluggish.
You can see this in DevTools’ Performance panel – layout recalculations, style invalidations, and paint operations lighting up the flame chart.
Semantic HTML helps here too. Proper structural boundaries allow for more effective use of modern CSS containment strategies:
`contain: layout;` tells the browser it doesn’t need to recalculate layout outside the element.
`will-change: transform;` hints that a compositing layer is needed.
`isolation: isolate;` and `contain: paint;` can help prevent visual spillover and force GPU layers.
But these tools only work when your DOM is rational. If your animated component is nested inside an unpredictable pile of generic `<div>`s, the browser can’t isolate it cleanly. It doesn’t know what might be affected – so it plays it safe and recalculates everything.
That’s not a browser flaw. It’s a developer failure.
Animation isn’t just about what moves. It’s about what *shouldn’t*.
> Rendering and painting are parallel operations in modern engines. But DOM/CSS changes often force main-thread syncs, killing that advantage.
>
>
> CSS layering via `will-change: transform` or the newer `layer()` syntax tells the GPU to handle composites separately. That avoids layout and paint in the main thread – but only when the DOM structure allows distinct layering containers.
>
>
##### CSS containment and visibility: powerful, but fragile
Modern CSS gives us powerful tools to manage performance – but they’re only effective when your HTML gives them room to breathe.
Take `contain`. You can use `contain: layout`, `paint`, or even `size` to tell the browser “*don’t look outside this box – nothing in here affects the rest of the page.*” This can drastically reduce the cost of layout recalculations, especially in dynamic interfaces.
But that only works when your markup has clear structural boundaries.
If your content is tangled in a nest of non-semantic wrappers, or if containers inherit unexpected styles or dependencies, then containment becomes unreliable. You can’t safely contain what you can’t isolate. The browser won’t take the risk.
Likewise, `content-visibility: auto` is one of the most underrated tools in the modern CSS arsenal. It lets the browser skip rendering elements that aren’t visible on-screen – effectively “virtualising” them. That’s huge for long pages, feeds, or infinite scroll components.
But it comes with caveats. It requires predictable layout, scroll anchoring, and structural coherence. If your DOM is messy, or your components leak styles and dependencies up and down the tree, it backfires – introducing layout jumps, rendering bugs, or broken focus states.
These aren’t magic bullets. They’re performance contracts. And messy markup breaks those contracts.
Semantic HTML – and a clean, well-structured DOM – is what makes these tools viable in the first place.
> MDN’s docs highlight how `contain: content` (shorthand for `layout`+`paint`+`style`) lets browsers optimize entire subtrees independently
> Real-world A/B tests show INP latency improvements on e‑commerce pages using `content-visibility: auto`.
>
>
#### Agents are the new users – and they care about structure
The web isn’t just for humans anymore.
Search engines were the first wave – parsing content, extracting meaning, and ranking based on structure and semantics. But now we’re entering the era of AI agents, assistants, scrapers, task runners, and LLM-backed automation. These systems don’t browse your site. They don’t scroll. They don’t click. They parse.
They look at your markup and ask:
* What is this?
* How is it structured?
* What’s important?
* How does it relate to everything else?
A clean, semantic DOM answers those questions clearly. A soup of `<div>`s does not.
And when these agents have to choose between ten sites that all claim to sell the same widget, the one that’s easier to interpret, extract, and summarise will win.
That’s not hypothetical. Google’s shopping systems, summarisation agents like Perplexity, AI browsers like Arc, and assistive tools for accessibility are all examples of this shift in motion. Your site isn’t just a visual experience anymore – it’s an interface. An API. A dataset.
If your markup can’t support that? You’re out of the conversation.
And yes – smart systems can and do infer structure when they have to. But that’s extra work. That’s imprecise. That’s risk.
In a competitive landscape, well-structured markup isn’t just an optimisation – it’s a differentiator.
#### Structure is resilience
Semantic HTML isn’t just about helping machines understand your content. It’s about building interfaces that hold together under pressure.
Clean markup is easier to debug. Easier to adapt. Easier to progressively enhance. If your JavaScript fails, or your stylesheets don’t load, or your layout breaks on an edge-case screen – semantic HTML means there’s still something usable there.
That’s not just good practice. It’s how you build software for the real world.
Because real users have flaky connections. Real devices have limited power. Real sessions include edge cases you didn’t test for.
Semantic markup gives you a baseline. A fallback. A foundation.
#### Structure isn’t optional
If you want to build for performance, accessibility, discoverability, or resilience – if you want your site to be fast, understandable, and adaptable – start with HTML that means something.
Don’t treat markup as an afterthought. Don’t let your tooling bury the structure. Don’t build interfaces that only work when the stars align and the JavaScript loads.
Semantic HTML is a foundation. It’s fast. It’s robust. It’s self-descriptive. It’s future-facing.
It doesn’t stop you using Tailwind. It doesn’t stop you using React. But it does ask you to be deliberate. To design your structure with intent. To write code that tells a story – not just to humans, but to browsers, bots, and agents alike.
This isn’t nostalgia. This is infrastructure.
And if the web is going to survive the next wave of complexity, automation, and expectation – we need to remember how to build it properly., Why Semantic HTML Still Matters, Jono Alderson, 01k18ezrqxwvjjsdbmp3k7kpmp.