I’ve been writing a bit of Web components code recently and used Shadow DOM. I am realizing that there’s a fairly useful pattern in incorporating Shadow DOM into Web apps that I will hereby name the “Shadow Gristle”.
First things first. If you don’t like Shadow DOM for one reason or another, this is not an attempt to convince you otherwise. If you have no idea what Shadow DOM is, this will be just a few paragraphs of gobbledygook. Sorry. However, if you do find yourself dabbling with the ye olde Shadow DOM even occasionally, you might find this pattern useful.
Very simply put, the idea is that we only put the necessary scaffolding code into the Shadow DOM, and leave most of our application code in the light DOM.
When we have the power of Shadow DOM at our fingertips, we have two choices about how we grow the subtree of the DOM elements: one is inside of the shadow tree (in the Shadow DOM), and the other on the outside (in the regular DOM).
So if we want to add another component as a child of our Web component, how do we decide which of the two places it should go into?
My intuition is that placing a child component into a shadow tree is a code smell. It indicates that we might have lessened our ability to compose elements. There are probably perfectly good reasons to put a component into a shadow tree, but more often than not, it’s probably not the right place.
Child components love light. If they stay in the regular DOM, they remain composable. I can rearrange them or replace them without having to muck with the innards of my component.
Thus, the rule of thumb is: seek to place child components into the regular DOM. Reduce occurrences of them being added to the shadow tree.
So what goes into the Shadow DOM? Mostly gristle. It’s the stuff that connects components together. There may need to be some routing or event handling, and perhaps a few styles to set the foundation. Everything else goes in the regular DOM. For example, I try to avoid styling in the shadow tree. Thanks to the CSS variables, I can use them as pointers and allow the regular DOM tree to supply the specifics.
I hope this little pattern helps you build better Web apps. And yes, the gobbledygook is over now. I promise I’ll write something less obtuse next time.