No, seriously, the shadow DOM sucks

Yesterday’s article on why the shadow DOM sucks may have been one of the most hated pieces I’ve written in a while.
But I stand by what I said, and today I wanted to respond to some of the comments I got.
Let’s dig in!
“Global styles can break your component.” This is true… if CSS is badly written.
If your component relies on very generic class names, global CSS with the same name can break it.


This content originally appeared on Go Make Things and was authored by Go Make Things

Yesterday’s article on why the shadow DOM sucks may have been one of the most hated pieces I’ve written in a while.

But I stand by what I said, and today I wanted to respond to some of the comments I got.

Let’s dig in!

“Global styles can break your component.”

This is true… if CSS is badly written.

If your component relies on very generic class names, global CSS with the same name can break it.

<accordion-group>
	<h2 class="heading" aria-expanded="true"><button>Some heading</button></h2>
	<div>Some content...</div>
	<!-- ... -->
</accordion-group>
.heading button:after {
	/* ... */
}

accordion-group div {
	/* ... */
}

These styles are really easily broken by global CSS. But like, we solved for this a decade ago, back in the jQuery era, with…

  1. Better class naming conventions, and
  2. Customizable classes on internals.
<!-- Here, the attributes let you change the default class names -->
<accordion-group 
	content-class="accordion-content" 
	btn-class="accordion-heading-btn"
>
	<h2 class="accordion-group-heading" aria-expanded="true">
		<button class="accordion-heading-btn">Some heading</button>
	</h2>
	<div class="accordion-content">Some content...</div>
	<!-- ... -->
</accordion-group>
/**
 * These selectors have much tighter scoping, but can still be overridden without !important
 */
accordiong-group .accordion-heading-btn:after {
	/* ... */
}

accordion-group .accordion-content {
	/* ... */
}

The other issue could be badly written CSS on the site loading the component.

Frankly… that shouldn’t be the component author’s problem to fix. If the site using the component has CSS riddled with !important and grossly over-specific selectors, they should fix that.

It shouldn’t be on you to encapsulate your component such that it cannot every be broken, because…

“You can make shadow DOM externally styleable with parts and CSS variables”

You can.

But again, you’re not benefiting from global styles. The site owner has to apply existing global styles to the internal shit inside your component, rather than just letting your component look like the rest of the site.

Consider you have a set of components for a show-hide widget, a dropdown menu, and an off-canvas menu. All three use buttons.

<!-- The rendered shadow DOM looks something like this... -->
<show-hide>
	<button>Show more</button>
	<div>...</div>
</show-hide>

<dropdown-menu>
	<button></button>
	<ul>
		<!-- ... -->
	</ul>
</dropdown-menu>

<off-canvas>
	<button>Menu</button>
	<dialog>...</dialog>
</off-canvas>

The host site has global styles for <button> elements. All of their buttons have a cohesive look already.

But your shadow DOM <button>’s? They either look like hideous browser-native unstyled buttons, or whatever default style you wanted for the component.

Either way, they don’t look like they belong on the same site.

But fear not, you’ve used the [part] attribute to let users style things.

Great, now they have to specify every single <button> part in their CSS and add all of their existing button styles to it.

button,
::part(show-hide-btn),
::part(dropdown-menu-btn),
::part(off-canvas-btn) {
	/* ... */
}

button:hover,
::part(show-hide-btn):hover,
::part(dropdown-menu-btn):hover,
::part(off-canvas-btn):hover {
	/* ... */
}

/* ... */

Or maybe you used CSS variables. Same deal.

Either way, you’ve given developers a whole lot more work.

“Developer should only be able to modify certain things.”

Why?

I hear this one a lot. That the shadow DOM lets you expose just the things that developers should be able to customize.

I’ve been making public plugins and components for over a decade, and I can confidently say that developers will always have use cases for your code that you didn’t anticipate or account for when you built it.

What you think they should do may not be what they want to do.

Letting devs openly target and style code makes it easier for people to implement use-cases you didn’t think of without you needing to go back and add more style hooks (or them having to modify the core code).

Write documentation, explain possible foot guns, and let people do what they want.

“Developers shouldn’t have to worry about internals.”

Relate to the previous item, there seems to be this dual concern about…

  1. If the internal structure of your web component changes, you’ll break things for people using it.
  2. Developers shouldn’t have to think about how the internal HTML looks.

I find both of these really weird, for different reasons.

First, semantic versioning exists for a reason.

If a change is going to break the component, that’s a major version upgrade, and you can communicate that through version numbers very easily. This danger also forces you to think about the structure and how the component will be used a bit more before implementing it.

A majority of my time spent building Kelp UI was not spent writing code, but instead thinking through the different ways people might want to use something and how to structure the code for maximum flexibility.

And second… developers should think about HTML. It is literally the backbone of the web.

Yesterday, when I said that an obsession with shadow DOM is React-thinking creeping into the native web, this is what I meant.

I think the right way to build most web components is to start with usable HTML, and progressively enhance it into something better.

But if you don’t do that… you can still render internal HTML with JS, and developer won’t have to think about it. This is a non-concern.

“Shadow DOM is better for performance.”

This was a new one to me.

When a site has lots of DOM nodes, rendering (and more specifically, re-rendering) becomes very slow and expensive. Because shadow DOM is its own separate DOM, the repaints become far less expensive.

This does not feel like a web component problem.

This feels like a site architecture/design problem that you’re using a different tool as a band-aid to fix. The issue is that the site uses a bad DOM structure or tries to do too much in one place.

That’s the problem you should fix, in my opinion.

The part where I cede some ground

The shadow DOM does have situational uses.

As someone pointed out to me yesterday, the shadow DOM let’s you replace iframes, which can be notoriously difficult to make look good.

So it’s not “death to the shadow DOM” so much as “please stop using it for fucking everything!”

But it being situationally useful I think underscores my original point: it’s an anti-pattern, not a best practice.

Like this? A Lean Web Club membership is the best way to support my work and help me create more free content.


This content originally appeared on Go Make Things and was authored by Go Make Things


Print Share Comment Cite Upload Translate Updates
APA

Go Make Things | Sciencx (2025-12-23T14:30:00+00:00) No, seriously, the shadow DOM sucks. Retrieved from https://www.scien.cx/2025/12/23/no-seriously-the-shadow-dom-sucks/

MLA
" » No, seriously, the shadow DOM sucks." Go Make Things | Sciencx - Tuesday December 23, 2025, https://www.scien.cx/2025/12/23/no-seriously-the-shadow-dom-sucks/
HARVARD
Go Make Things | Sciencx Tuesday December 23, 2025 » No, seriously, the shadow DOM sucks., viewed ,<https://www.scien.cx/2025/12/23/no-seriously-the-shadow-dom-sucks/>
VANCOUVER
Go Make Things | Sciencx - » No, seriously, the shadow DOM sucks. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/12/23/no-seriously-the-shadow-dom-sucks/
CHICAGO
" » No, seriously, the shadow DOM sucks." Go Make Things | Sciencx - Accessed . https://www.scien.cx/2025/12/23/no-seriously-the-shadow-dom-sucks/
IEEE
" » No, seriously, the shadow DOM sucks." Go Make Things | Sciencx [Online]. Available: https://www.scien.cx/2025/12/23/no-seriously-the-shadow-dom-sucks/. [Accessed: ]
rf:citation
» No, seriously, the shadow DOM sucks | Go Make Things | Sciencx | https://www.scien.cx/2025/12/23/no-seriously-the-shadow-dom-sucks/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.