Chris’ Corner: Let’s Talk Web Components

Last week I linked up a Web Component (feels like we should do Captial W and Captial C when referring to the official technology, yes?) that would take an image and output a “dithered” version of it.

Why did Andrew make it a Web Component? I can’t be sure, but check out how you use it:

  1. Link up a JavaScript file that has one job: instantiate usage of the Web Component.
  2. Use the Web Component in HTML alone.

Like…

<script src="./as-dithered-image.js"></script>

<as-dithered-image 
   crunch="1" 
   src="./surfer.jpg" 
   alt="Description of the image for screen readers">
</as-dithered-image>

That’s just… a nice API! It’s easy to use and easy to control. This idea could have been developed and delivered any number of other ways, but this way feels pretty good. Web Components allow you to build (and distribute, really) a bit of design and functionality that anybody can use anywhere on the web.

Well, I say anywhere, but if you’re using a JavaScript framework, it does require that JavaScript framework plays nicely with them. A good place to check is the website Custom Elements Everywhere that has tests for it. React, famously, isn’t great with them. And, well, server-side rendering of them is a bit tricky. And the accessibility story is a bit messy. And styling them isn’t my favorite. So the whole story isn’t so clear.

Still, personally, my brain reaches for the idea of a Web Component more and more. When I made my Calendar with Container Queries demo, I thought a great way to showcase the fact that you don’t need to change the viewport width for the container queries to hit was if you could resize the area that component is in some other way. I figured there must be a Web Component for this and of course, there was.

So are Web Components destined to be used for small bits of framework-agnostic functionality? Maybe! Maybe not! I mean you can’t discount that Adobe literally built the entire application of Photoshop on the web with Web Components.

…  the entire Photoshop app is built using Lit-based Web Components. Leaning on the browser’s built-in component model and Shadow DOM encapsulation, the team found it easy to cleanly integrate a few “islands” of React code provided by other Adobe teams.

Photoshop’s journey to the web

They aren’t alone, either. EisenbergEffect’s 2023 State of Web Components starts off with loads of examples of big production sites going fairly big on Web Components, like YouTube, MSN, Salesforce, and SpaceX. I always think of GitHub too which felt like a pretty early adopter.

What makes all this Web Component stuff so tricky and nuanced is that they aren’t just one technology, they are really quite a big bucket of technologies that all come together to form what the world (well, me at least) thinks of as Web Components.

The classics are Shadow DOM, Custom Elements, and HTML Templating. But even among them, the details of how they are implemented and what advancements are coming to them is complex. EisenbergEffect’s’s article gets pretty deeply into it so is worth checking out if nothing else to understand how wide this subject is.

As a CSS guy kinda, I try to follow the styling story for them. The Shadow DOM is where that story starts, offering the unique ability to contain styles quite strongly. But how do you get the CSS in there? Do you put special HTML attributes on everything so you can reach in with ::part selectors? Do you put Custom Properties on everything so you can “reach in” from the outside to style them? Do you put a block of CSS in the HTML template? Do you @import CSS from inside? Sort of “yes” to all of them, but also sort of “🤢” to all of that if you ask me. But then there are Constructible Stylesheets and Adopted Stylesheets which seem like a web platform win allowing for more proper programmatic access to CSS. Then CSS Module Scripts allowing for proper importing of CSS in JavaScript which has long been a bundler-only aberration. And making that CSS declarative just might bring it full circle. Phew!

Back to the idea of actually using these things. Brad Frost believes the job of Web Components really isn’t at odds with JavaScript frameworks at all. (I always thought it was a fair comparison, since all JavaScript frameworks teach you to build in composable components that are isolated bits of design and functionality). But Brad splits it along another dichotomy he is famous for:

  • Web components handle front-of-the-front-end code (e.g. the look and feel of a button)
  • JS libraries/frameworks handle back-of-the-front-end code (e.g. what happens when a user clicks on that button)

If that’s pull-off-able, it sounds reasonable to me. I’d have to see some examples. I think of how even the most basic interactivity, like <button onClick={}> means putting framework-specific code into the “HTML” and I don’t totally get how to untangle that since both the native HTML template and the framework-specific HTML (e.g. JSX) are involved.

All this talk so far is also about using the Web Components technology “raw”, that is, the web platform APIs directly. I heard from people early on in this world, who were part of shaping the whole idea, that the APIs were more designed around framework authors and that your average website crafting citizen was meant to use abstractions around Web Components, not the APIs directly. That’s a wild claim to me since there is little precedent for that, but OK.

The first wave of those abstractions were libraries that just made things a little more ergonomic at the cost of a few KB of a client-side library. Lit is a famous one. It just makes the instantiation of web components a little easier. Re-rendering efficiently wasn’t an early aim (wtf), so it helped with that. Styling, as I laid out, is rough, so it helps with that a little. Personally, I was never hugely drawn to it as it seemed like it bought you a little niceness, but not enough to feel locked to some new framework (might as well have just picked a more robust JavaScript framework then).

I think we’re seeing the next wave of Web Components frameworks now, like WebC and Enhance. They both make SSR the primary feature. I thought that was a weird choice at first as, that’s nice and all, but didn’t seem to be the main reason Web Components weren’t “winning”. But I’m coming around to it. I think when SSR gets “solved” like this, other solutions come along for the ride. Like styling gets easier. But also solves bigger questions like “how do I build whole sites with this?” by including things like data-fetching advice and real routing.

Perhaps the most clutch part about Web Components is that, even if the beginnings were shaky (they were) and even if the story still isn’t perfectly clear (it isn’t), the technologies are now built into browsers and browsers are wonderfully long-term and backward-compatible. They aren’t just going to rip out Web Components support. It’s just going to get better over time.

Need help understanding the tech more? I’d pass you over to my friend Dave’s course HTML with Superpowers.

The post Chris’ Corner: Let’s Talk Web Components appeared first on CodePen Blog.