Blinded By the Light DOM – Eric’s Archived Thoughts
For a while now, Web Components (which I’m not going to capitalize again, you’re welcome) have been one of those things that pop up in the general web conversation, seem intriguing, and then fade into the background again.
I freely admit a lot of this experience is due to me, who is not all that thrilled with the Shadow DOM in general and all the shenanigans required to cross from the Light Side to the Dark Side in particular. I like the Light DOM. It’s designed to work together pretty well. This whole high-fantasy-flavored Shadowlands of the DOM thing just doesn’t sit right with me.
If they do for you, that’s great! Rock on with your bad self. I say all this mostly to set the stage for why I only recently had a breakthrough using web components, and now I quite like them. But not the shadow kind. I’m talking about Fully Light-DOM Components here.
It started with a one-two punch: first, I read Jim Nielsen’s “Using Web Components on My Icon Galleries Websites”, which I didn’t really get the first few times I read it, but I could tell there was something new (to me) there. Very shortly thereafter, I saw Dave Rupert’s CodePen, and that’s when the Light DOM Bulb went off in my head. You just take some normal HTML markup, wrap it with a custom element, and then write some JS to add capabilities which you can then style with regular CSS! Everything’s of the Light Side of the Web. No need to pierce the Vale of Shadows or whatever.
Kindly permit me to illustrate at great length and in some depth, using a thing I created while developing a tool for internal use at Igalia as the basis. Suppose you have some range inputs, just some happy little slider controls on your page, ready to change some values, like this:
Title font size
The idea here is that you use the slider to change the font size of an element of some kind. Using HTML’s built-in attributes for range inputs, I set a minimum, maximum, and initial value, the step size permitted for value changes, and an ID so a can be associated with it. Dirt-standard HTML stuff, in other words. Given that this markup exists in the page, then, it needs to be hooked up to the thing it’s supposed to change.
In Ye Olden Days, you’d need to write a function to go through the entire DOM looking for these controls (maybe you’d add a specific class to the ones you need to find), figure out how to associate them with the element they’re supposed to affect (a title, in this case), add listeners, and so on. It might go something like:
let sliders = document.querySelectorAll('input[id]');<br>for (i = 0; i
Then you’d have to stuff all that into a window.onload observer or otherwise defer the script until the document is finished loading.
To be clear, you can absolutely still do it that way. Sometimes, it’s even the most sensible choice! But fully-light-DOM components can make a lot of this easier, more reusable, and robust. We can add some custom elements to the page and use those as a foundation for scripting advanced behavior.
Now, if you’re like me (and I know I am), you might think of converting everything into a completely bespoke element and then forcing all the things you want to do with it into its attributes, like this:
Title font size
Don’t do this. If you do, then you end up having to reconstruct the HTML you want to exist out of the data you stuck on the custom element. As in, you have to read off the type, min, max, step, and value attributes of the element, then create an element and add the attributes and their values you just read off , create a and insert the ’s text content into the label’s text content, and why? Why did I do this to myse — uh, I mean, why do this to yourself?
Do this instead:
Title font size
This is the pattern I got from , and the moment that really broke down the barrier I’d had to understanding what makes web components so valuable. By taking this approach, you get everything HTML gives you with the and elements for free, and you can add things on top of it. It’s pure progressive enhancement.
Side note: keep in mind that the name was chosen, just as with , because custom elements must (in the RFC 2119 sense of that word) have a hyphen within their name. You can’t call your element or and have it work; you’d have to call them and instead.
Also, don’t @ me about the H1 being uppercase. Element names can be capitalized however you want; we lowercase them out of historical inertia and unexamined habit.
To figure out how all this goes together, I found MDN’s page “Using custom elements” really quite valuable. That’s where I internalized the reality that instead of having to scrape the DOM for custom elements and then run through a loop, I could extend HTML itself:
class superSlider extends HTMLElement {<br>connectedCallback() {<br>//<br>// the magic happens here!<br>//
customElements.define("super-slider",superSlider);
What that last line does is tell the browser,...