What if the real problem with your CSS isn’t that it’s global—it’s that you’ve never actually defined what a UI unit is?
You know the feeling. You tweak padding on one screen. Suddenly a button 10 files away looks wrong. The same HTML renders differently in different contexts. You can’t tell anymore which rule is responsible for what’s on screen. So you add another selector to be safe. Then another. Until your stylesheet becomes a archaeology dig and your component looks like it was written by committee.
Most teams blame CSS for this. They’re wrong.
The Real Problem Isn’t CSS—It’s Structure
Here’s what’s actually happening: your HTML lives in one place, your CSS in another, and your DOM behavior in a third. Each part seems fine independently. But they’re describing the same visual unit without ever being in the same room.
That gap is where drift lives.
HTML alone doesn’t tell you how an element behaves. CSS doesn’t tell you which structural unit it belongs to. DOM code modifies the same area without carrying either the styling context or the original intent with it. You’ve got three different teams working on the same employee, speaking different languages, never synchronized.
“The issue was that there was no clear UI unit that held those responsibilities together. Without that unit, small fixes accumulate in the gaps between files.”
Small fixes do accumulate. A selector gets adjusted. A rule gets added. A DOM patch appears. Each one is locally reasonable. The screen as a whole becomes incomprehensible.
One developer working with Razor Pages noticed something. The .cshtml and .cshtml.css pairing forced a relationship—CSS automatically scoped to live inside that page. The impact radius was small by default. You could implement styles without constantly wondering if you’d just broken something three layers deep in another file.
It wasn’t perfect. But it made one thing obvious: when related responsibilities stay attached to the unit they belong to, they stop leaking everywhere else.
What Does a Real UI Unit Actually Own?
That realization led to a different question: what if HTML and CSS should stay attached to a meaningful boundary in frontend code, the way Razor Pages showed they could?
Instead of thinking in loose layers—markup here, styling there, behavior floating around—you start thinking in terms of element ownership. One boundary owns one structural root, one local styling context, and one place where DOM behavior lives. Because that boundary becomes the only place where structure, style, and behavior can meet, changes stop leaking.
This isn’t about turning everything into a component framework. It’s about having a unit small enough to own its own structure.
Imagine something simple called ElementBoundary:
const profileCard = new ElementBoundary(
/* html */ `
<section>
<h2 class="title">Profile</h2>
<p class="value">Active</p>
</section>
`,
/* css */ `
[root] {
padding: 12px;
border: 1px solid #d0d7de;
}
[root] .title {
font-size: 14px;
margin: 0 0 8px;
}
`
);
const screen = ElementBoundary.first("#screen");
screen.append(profileCard);
The constructor doesn’t matter. What matters is that one element unit owns both its HTML and CSS. The screen container gets treated through the same boundary model instead of dropping back to raw DOM access. The [root] placeholder gets rewritten automatically to a boundary-specific selector, so CSS only applies inside that unit.
This isn’t Shadow DOM. Shadow DOM takes you out of normal DOM flow. This keeps you in it while giving you a narrower styling boundary that scales as the UI grows. Creation, lookup, and placement all follow the same model instead of being unrelated DOM operations scattered across your codebase.
Why This Actually Solves the Drift Problem
Once you start thinking this way, three things change.
CSS becomes local because it’s tied to an element root instead of being treated as a separate global layer. DOM behavior gets easier to place because it belongs to a specific unit instead of floating across the page. The UI itself becomes reasoned about coherently—both existing areas and newly created areas follow the same structural meaning.
You stop asking which selector is responsible? and start asking which boundary owns this? That’s a different conversation entirely.
The gap between what your HTML describes and what your CSS does and what your DOM code does—that gap vanishes. Not because you’ve used a framework. Because you’ve defined what a unit is.
This matters because scaling frontends don’t fail because of CSS syntax. They fail because teams have never agreed on where responsibility begins and ends. When you define a clear boundary, that ambiguity dies. You can change things without fear. You can add features without creating tech debt. And you can onboard new developers without them needing to reverse-engineer your entire styling strategy.
It’s not revolutionary. It’s structural.
🧬 Related Insights
- Read more: Higress Joins CNCF as Alibaba’s AI Gateway Bet—And Nginx Has Until 2026 to Worry
- Read more: Claude Code’s Token Collapse: When AI Pricing Models Break Developer Workflows
Frequently Asked Questions
Will DOM boundaries replace component frameworks like React? No. This is about structural organization within whatever framework you use. React components could adopt this pattern. Plain JavaScript could too. The boundary is about responsibility, not tooling.
Does this work with existing CSS? Yes, if you can refactor your selectors to respect the boundary scope. New projects adopt it immediately. Legacy code requires some rewriting, but it’s scoped to one unit at a time.
Is this the same as CSS modules? Similar goal, different approach. CSS modules use naming conventions and tooling. Boundaries make the structural unit explicit in your JavaScript, tying HTML, CSS, and behavior together conceptually, not just technically.