From "Div Soup" to Modular Markup: The Evolution of HTML
In the old web publishing world, it was common for the frontend team to have **zero control** over markup. HTML was generated by the CMS, by backend developers who had already moved on to other tasks.
Thiago Saraiva

From "Div Soup" to Modular Markup: The Evolution of HTML
Let me show you something that will give you chills if you've ever worked with legacy CMSs:
Ten levels of nesting just to reach a simple navigation link.
This, my friends, is the infamous "div soup" — and for a long time, it was the industry standard. Let's understand how we got here and, more importantly, how we got out.
The Three Eras of Markup
Era 1: Procedural Markup (100% Automation, 0% Control)
In the old web publishing world, it was common for the frontend team to have zero control over markup. HTML was generated by the CMS, by backend developers who had already moved on to other tasks.
The result of this approach:
- CMSs added divs and classes "just in case"
- Backend developers erred on the side of "more markup"
- Nobody knew where certain classes came from
- Changing anything was risky
The fundamental problem: The markup belonged to nobody. It was output from a system, not a conscious design decision.
Era 2: Static Markup (0% Automation, 100% Control)
In smaller projects or pages with "free body" content, we had total control. We wrote semantic HTML, without unnecessary classes:
Beautiful, right? The problem came with CSS. Without classes, how do we differentiate identical elements in different contexts?
Each new variation required an even more specific selector. And God help us if the HTML structure changed.
The fundamental problem: Total control meant manual maintenance. Simple changes required alterations in dozens of files.
Era 3: Modular Markup (100% Automation, 100% Control)
The ideal state — and possible today — is when:
- All HTML is generated programmatically
- Frontend developers have total control over templates
- Changes propagate automatically
This is possible with component-based architectures.
Components: The Modern Solution
Instead of thinking in pages, we think in reusable blocks:
Each component:
- Is an independent unit
- Controls its own markup
- Can be tested in isolation
- Is reusable in any context
Design Systems: The Natural Evolution
When you have well-defined components, the next question is: "how do we organize all of them?"
The answer is a Design System — a collection of components, patterns, and guidelines that define how interfaces are built.
CSS Methodologies That Support Modularity
BEM (Block Element Modifier)
CSS Modules
Tailwind CSS
CSS-in-JS (styled-components, Emotion)
Each approach has trade-offs. The important thing is to choose one and be consistent.
Anatomy of a Good Component
A well-architected component has:
1. Single Responsibility
Does one thing and does it well. A <Button> shouldn't also make HTTP requests.
2. Clear Interface
Well-defined props with sensible defaults:
3. Style Isolation
Styles don't leak out or suffer external interference.
4. Composability
Can be combined with other components in predictable ways.
In Practice: Migrating from Soup to System
If you're stuck in a project with legacy markup, migration is possible but gradual:
Step 1: Identify Patterns
Map out repeating elements. That card appears on 15 pages? It's a component candidate.
Step 2: Create Isolated Components
Start with the most used ones. Create the component with its own styles, without depending on context.
Step 3: Replace Gradually
Don't try to rewrite everything at once. Replace one instance at a time, testing with each change.
Step 4: Document
Each new component should have documentation. Use Storybook or similar to create a visual catalog.
Does Perfect Markup Exist?
No. But good enough markup does. Good markup is:
- Semantic — uses appropriate HTML elements
- Accessible — works with screen readers
- Predictable — follows consistent conventions
- Maintainable — can be changed without fear
- Performant — has no unnecessary divs
Conclusion
The evolution of HTML from "div soup" to modular markup reflects a larger change in how we think about frontend:
| Before | After |
|---|---|
| Pages | Components |
| Global | Isolated |
| Implicit | Explicit |
| Backend controls | Frontend controls |
| Fear of change | Confidence to refactor |
Well-architected components are the foundation of any scalable Design System. Without them, you're building on quicksand.