One of the most frustrating UI failures is not a dramatic JavaScript bug. It is when CSS stops feeling explainable. You change one screen and another screen shifts. The same HTML looks different depending on where it appears. After a while, it becomes difficult to tell which style is actually responsible for what you are seeing.
The Real Problem Was Separation
At first, this looks like a CSS problem. In practice, it is usually a structure problem.
HTML defines the shape of the UI. CSS often lives somewhere else entirely. DOM behavior is then added from another place again. Each part may look reasonable on its own, but the unit they are supposed to describe no longer exists in one place.
That is where drift starts. The UI is assembled from related parts that are managed as if they were unrelated.
When a UI Unit Does Not Exist
This was the point that kept bothering me in real screens.
HTML alone does not fully describe the element as it actually behaves. CSS alone does not tell you which structural unit it truly belongs to. DOM code can modify the same area without carrying either the styling context or the original structural intent with it.
So the issue was not only that CSS was global, or that DOM code was scattered. 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. A selector is adjusted in one place. A style rule is added in another. A DOM patch appears elsewhere. Each change can be locally reasonable, but the screen as a whole becomes harder to understand.
The Turning Point
One thing that pushed my thinking forward was working with Razor Pages.
What mattered most was the cshtml and cshtml.css pairing. That model let me define CSS alongside the page and have it automatically scoped so it only applied inside that cshtml. The impact range was narrow by default, which meant I could implement styles without constantly worrying that they would damage some other part of the system.
That did not solve frontend structure by itself, but it made one point much clearer: related responsibilities become easier to manage when they stay attached to the unit they actually belong to.
That led me to a frontend question I had not framed clearly enough before:
what if HTML and CSS should also stay attached to a meaningful element boundary?
The Boundary Idea
The important shift was to stop thinking only in terms of DOM operations and start thinking in terms of element ownership.
Instead of treating HTML as markup, CSS as a separate styling concern, and DOM code as a loose behavior layer, I started thinking of them as one operational unit. One boundary should own one structural root, one local styling context, and one place where DOM behavior belongs. Because that boundary becomes the only place where structure, style, and behavior can meet, changes stop leaking across unrelated parts of the UI.
That does not mean every screen must become a component framework. It means the UI should have a unit small enough to own its own structure.
A Minimal Shape
The idea is easier to explain if you imagine implementing a small unit 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"); // get the screen boundary instead of accessing raw DOM
screen.append(profileCard);
The point here is not the constructor signature. The point is that one element unit owns both its HTML and its CSS, and that the existing screen container is treated through the same kind of boundary instead of dropping back to raw DOM access.
Here [root] is just a placeholder for the boundary's own root element. When the boundary is created, that placeholder can be rewritten to a boundary-specific selector automatically, so the CSS applies only inside that unit and does not leak into other parts of the screen.
This is also not the same point as Shadow DOM. The goal here is to keep working with the ordinary DOM flow and the same basic screen-building steps, while still gaining a narrower styling boundary that can be extended as the UI grows.
It also keeps creation, lookup, and placement within the same model, instead of treating those steps as unrelated DOM operations.
That is what I mean by a boundary: a unit where structure, style, and behavior are owned together, so changes no longer leak across unrelated parts of the UI.
Why This Changed Things
Once I started thinking this way, several UI problems became easier to control.
CSS became more local because it was tied to an element root instead of being treated as an unrelated global layer. DOM behavior became easier to place because it belonged to a specific unit instead of floating across the page. And the UI itself became easier to reason about because both existing areas and newly created areas could be handled through the same structural meaning.
Instead of asking which selector was responsible, I could ask which element owned the change.
The benefit was not just cleaner code. It was that the screen started having understandable structural ownership again.
What This Is Not
This is not a claim that every project should invent its own wrapper. It is also not a claim that global CSS should never exist.
The main point is smaller than that. If HTML, CSS, and DOM behavior are allowed to drift too far apart, the UI loses a meaningful unit of responsibility. Once that happens, fixing visible issues becomes much more reactive than structural.
Where This Led
I eventually refined this way of thinking into something I could publish as a real tool, and released it as Cotomy.
I’ve written more detailed notes about these failure patterns and their background here: https://blog.cotomy.net/
Top comments (0)