Web Components and progressive enhancement

I’m a big advocate when it comes to progressive enhancement. I believe we should be building the web with resilience in mind and think about all the different ways a browser could possibly render our sites. With or without JavaScript and when something breaks or when something is simply just not supported in the browser our user chooses to view our site in.

Lately, I’ve been looking into Web Components as part of my work on the Origami team. We’re looking into how Web Components will be used in our design system and how they will effect the way we create components. I’ve also been writing a couple of talks on the subject looking at the different ways of building components we have right now on the web. During this research I turned to the Design Systems Slack team, to ask whether there were any questions around Web Components that people thinking about design systems would like to know about. I had some really interesting responses from Kaelig and Jeremy on the subject of progressive enhancement and I thought it would be quite useful to share our discussion here as well.

Kaelig: I have a question! How do you deal with progressive enhancement? e.g. for buttons

This is a tricky area to deal with, if the is= attribute was being supported across all browsers it would be less of an issue, but Webkit keep pushing back on it. In fairness though I think this is an area where we’re going to have to employ different areas of the Web Components specs to get the best advantage. I wouldn’t make a custom element for a button, when we already have <button>. I’d maybe employ ShadowDOM to help with encapsulated styles but apart from that I don’t see a great deal of benefit making a custom button element when we already have one. I think it’s a bit of a shame a lot of the Google/Polymer examples use buttons, as it’s really only tacking on some minor functionality that can be handled without the Web Components specs in most cases.

Jeremy: Kaelig’s question gets to the heart of web components for me. […] The second issue is something I ask of any technology: “How well does it fail?” (an important corollary to “How well does it work?”). It’s the answer to that question that makes me comfortable persuing new CSS features, Service Workers, and the like, but very uncomfortable about monolithic technologies (like some client-side JavaScript frameworks) that require me to go “all in” on the technology. Until web components work well and fail well, I’m probably going to remain apprehensive about them. Support for “is=” would definitely help, but I also think that we could do with seeing examples of custom elements that borrow the design approach from HTML of elements like canvas, audio, video, and picture, where failing well has been given some thought. Does that make sense?

This concern definitely makes sense and a lot of what I’ve been thinking about too lately. There’s a lot you can pick and choose from in terms of the Web Components specs so it’s not essential that people go all-in on everything straight away.

In terms of how well they will fail, well it depends mostly on what we class as ok in terms of failing. I’ve been thinking of a gallery component lately, where you’d have a custom element, say <o-gallery> for want of a better example, and simply populate it with images you want to display, with custom elements and shadow DOM you can add all the rest, controls/layout etc. Markup would be something like:

<o-gallery>
  <img src="">
  <img src="">
  <img src="">
</o-gallery>

If none of the extra stuff loads, what do we get? Well you get 3 images on the page. You still get the content, but just none of the fancy interactivity.

Kaelig: buttons are a tricky one, I took this example on purpose. As an experiment I recently converted our Lightning Design System button component & variants to <slds-button> web component and the result it produced was ridiculous (no PE!). Salesforce doesn’t do progressive enhancement anyway but still, that made me really annoyed at the spec.

So let’s say you want to produce a WC library where your users don’t have to write any class names in their markup (styling done in the shadow DOM), you automatically fail at Progressive Enhancement. This is a shame because I think it would make sense to ship a WC framework rather than a CSS framework!

This is why it continues to trouble me that the first example we run to in web components are buttons. Buttons/links are pretty much always going to fail with PE because in that situation we will probably need is= which looks like it’s not going to happen. At least in webkit anyway. These built-in elements that have a lot of semantics and interactivity delivered through the browser are going to be really hard to replicate in WCs safely and in a progressively enhanced way. Even if we code all of those things back into the elements, the user still has to wait for all our code to download and parse before they get the fully working version. Whereas with a native button or anchor, the browser already has all that built-in.

However, I completely disagree with Kaelig that there’s an automatic fail in progressive enhancement with WCs. There’s a fail if you don’t write code with progressive enhancement in mind, which has always been the case. It just means you have to write your components thinking about what they fall back to. Essentially all custom elements fallback to a <div> so you need to be able to handle that use case appropriately. This is the same case when it comes to <input type="date">, you know that browsers will fail back to a text input, so you have to code around that, same thinking goes into using WCs, there’s just a bit more to it.

Kaelig: Let’s see where the spec leads us. In principle I’m very attached to web components but I’ve mostly been frustrated by the real world inadequacy of their current possibilities they offer. It seems to take a lot of effort to simply do a button in WC (that doesn’t even degrade well), when that’s actually the most common use case for modern web apps. I wonder what people like Alex Russell might have to say about this.

I think Kaelig sums up a lot of the frustration with the Web Components spec to date and I think it also might have a lot to do with the general lag of the specs being implemented in browsers. It’s taken over 5 years before we’ve been able to properly see things agreed by vendors and finally start to get integrated in a lot of places. In the time since they were proposed, a lot of frameworks and libraries have been released to look at working with a components based design system in JavaScript instead and now people are starting to get comfortable with those technology choices.

I think Web Components will change the way we build websites. However, it’s going to take a while before people really start to get behind them. There are more real-world examples of custom elements and web components at the Custom Elements website, a lot more than just fancy buttons, which is a start. But there are still some unanswered questions around how a design system will come to fully utilise the web component specs and whether it will be the best route for developers and users both. I’m going to keep on writing about things as they come up and as we start to implement them in Origami, so hopefully that will be a worthwhile insight into a real-world design system with web components.