Note from the author...
My posts frequently (like this one) have a 'theme' and tend to use a number of images for visual flourish. Personally, I like it that way, I find it more engaging and I prefer for people to read it that way. However, for users on a metered or slow connection, downloading unnecessary images is, well, unnecessary, potentially costly and kind of rude. Just to be polite to my users, I offer the ability for you to opt out of 'optional' images if the total size of viewing the page would exceed a budget I have currently defined as 200k...
i is="the walrus"
It's become a fairly regular occurence for me to encounter someone on social media expressing some kind of frustration with Custom Elements. As both an avid user of them myself and someone involved in many discussions during their creation and evolution, I really want them to be better too. As I speak to the folks who are frustrated, however, I find that there is so much there that it's difficult to discuss. So, I thought perhaps it would be worth sitting down and writing about it. That, and walruses.
The time has come...
Over the last few years, I've watched several observations and criticisms sprout up about Custom Elements. It began (I think) with someone pointing out that there's an ability that is spec'ed today: The ability to extend native elements with the
is="…" attribute. Extension, as the argument goes, is desparately needed for accessibility sake. Yet, for some reason, it remains unimplemented. This has generated a lot of discussion, frequently about who was to blame for holding the Web back and making custom elements less valuable. Given this core premise, further arguments have been made as to how this would be good for so many additional reasons: Given X, then Y. Given Y, then Z. In concert, all of these simple observations and arguments really do appear to lead inexorably toward a very simple and well-justified "overall solution" that would be really grand...If browsers would just get their shit together and implment the thing in the spec. It's pretty frustrating to a lot of people. I can appreciate that.
I'd like to take some time and unpack a lot of this though...
Let's start here: The popular understanding that if we were to extend a built-in element it would be "automatically accessible" by the simple virtue of inheritance. I think it's important to explan that this is very nearly entirely untrue. Sadly, the magical walricorn won't actually magically bring all of the good little elements who used
is="…" free accessibility on International Walrus Day (November 24th).
Here's why: Currently, all that accessibility goodness that we desire is inextricably wound up in the native DOM. Sadly, the vast majority of use cases for "improving" a native element is actually about improving the DOM itself, and this creates a substantial mismatch. In reality (not an opinion), as soon as we create a new shadow root or hide the existing element or do just about anything really useful to the user experience, all of that accessibility goodness largely just vanishes.
Note: I say almost entirely untrue because there, in fact, are some small set of problems that involve no new DOM at all. However, in terms of accessibility, many of these also have similarly trivial solutions already available today and/or there are other proposals under discussion that promise to help solve these problems better.
So, any concept that
is="…" will make all components more accessible is, sadly, just misleading. There's no magical affordance in extension that allows it to map "whatever random shit I just made up" to "the thing with all of the good accessibility characteristics". You've still got to do a lot of work.
What's more, this isn't really a controverial statement in standards land. Hats off to Google for actually trying really hard to solve a lot of problems. For a brief instant, some people were very hopeful in the idea of
is="…". Others saw too many problems and too little benefit. That moment seems to have passed though and, realistically, no one seems to actively believe that
is="…" holds a lot of answers. Since that time, counter-proposals have been fermentingand, currently, appear to have wider conceptual support (I'll mention some of that later).
While accessibility is commonly cited, I think that really it is the Progressive Enhancement (PE) that appears to be afforded by
is="…" that is probably the real lynchpin feature that really makes so many people latch on to this idea. I can entirely appreciate this: It sounds so good. Unfortunately, I think this is misleading as well.
Here's something subtle to think about: Is
is="…" really PE in the traditional sense? Well, no. It can't be since the ability to extend has never existed before. PE has traditionally never been an is-a relationship.
Consider a common example used to explain PE: Our designs include a button that say "click to print" which should call
window.print() is defined), then it enhances. Seems good.
But now consider the details: It might become a paragraph containing a functional button, or it might actually become instead a functional print button. Is that the same thing?
Neither turning one thing into something else, nor changing the composition of a thing are really the same thing as extension. Traditionally, the "ness" of that element instance never changed. In no case was the same thing both paragraph and button at the same time. That's why you can't write
p is="button" for example - it's nonsense. However, the mere fact that this attribute would allow an author to express such a desire (meaning, someone can and will type that) means introducing a whole lot of new plumbing and complexity for new cases that have to be accounted for.
However we spell it out, a paragraph and a button are two things that are just entirely different things in terms of heirarchy and that's the important thing, here's why...
While you may think that the above "paragraph that is a button" example above seems "really different from what you're asking for" and is merely my contrived example aimed to convince you of something irrelevant, it isn't. I would suggest that currently this is actually precisely what we are frequently asking for without even realizing it. Why? Well, again, that's because what we want actually usually involves new DOM. It's not, in terms available to us today, actually just a specialized version of something. Really often, what we're describing is a different, and more complex kind of relationship. is-a is very specifically about extension, and extension is about describing a taxonomy, like, in the Linnean sense.
Understanding the basic ideas of Linnean Taxonomy is obviously very important to understand if you want to get a job as say, a marine biologist or a paelentologist. But what most people don't realize is that unlike some of the other frivolus things they made you learn in school, like, for example, algebra - understanding this can also come in extremely handy in everyday adult life. For example, if you needed to help my friend Sarah Drasner win a bar bet about whether people know what it is...
Alright, please help us nerds settle a drinking bet. Do you know what the Linnaean System of Classification is? (No googling)— Sarah Drasner (@sarah_edo) September 23, 2017
Or, maybe more practically, if you are doing software modeling, as we are here. So, let's talk about that for a minute.
A really significant amount of western thought has centered around trying to divide up the world like this into kind of fragile and abritrary taxonomies. Author David Weinberger has written a lot about this tendency/history, his Everything is Miscellaneous is a really enjoyable and non-technical talk that is worth watching some time.
In 1987 Barbara Liskov presented a keynote address called "Data abstraction and hierarchy" which talks about how we model things and our desire to organize things into heirarchies that extend and inherit. Liskov goes on to illustrate how that tends to cause numerous sorts of problems. More importantly, she begins to explain how we might avoid those problems and the basic concept she describes is sometimes known as the "Liskov substitution principle" or "LSP" or even just "substitutionality". In 2008 she won the Turing Award for her work.
In a way, what she's saying is: Metaphor makes for shitty modeling. Our minds are actually perfectly fine handling all sorts of wild linkages, comparisons and semantics that are more metaphorical than literal - in fact, they're kind of built to find patterns and relationships even when they don't exit.
Programming languages, on the other hand, tend to take things pretty literally. Because of this, our minds can trip us up and make us model something poorly. Extension is good and useful, don't misunderstand what I am saying. But if we use it poorly then rather than being a really helpful abstraction, we'll find that the system will begin to fight us instead.
Once again, that's just what happens here: Currently all that "good stuff" that we want is bound up pretty tightly in DOM and therefore a lot of times when we're thinking "is-a" it's unfortunately more metaphaorical than literal. In terms currently available to us today, it just isn't - and so we wind up modeling poorly.
Being able to extend input "like HTML did" is one of the most cited use case examples that I hear for extension. However, even in the platform itself, where extension was technically possible, there is no extension at play here today. There is only input. It's worth noting that most of how
input was done is largely seen as considerably problematic by implementers today. Why? Well, the easiest way to begin to understand, I think, is by listening to this talk by Monica Dinculescu. In short though, it's really created by the model mismatch we've been discussing here. Instead of being really helpful, the model begins to fight us. We begin to see the cracks in our modeling of metaphor and that actually, it isn't-really-that.
This mismatch is increasingly widely recogonized as a real problem that needs solving. In the Extensible Web sense, there's a lot more magic currently woven into today's DOM that needs explaining. In order for us to actually accomplish many of the sorts of things people are actually trying to describe, we need to decouple the powers and be able to explain the existing platform, and new things, in those terms. There are a number of discussions underway that are aimed at helping us do precisely that, and none of them are simply inheritance or
is="…" as currently specified. I'll write about those in another piece, but this leaves us with a very real problem: Until then, where does that leave us?
Well, interestingly, in the meantime, 'is-a' isn't the only kind of relationship we have identified for modeling problems. The often cited Gang of Four Design Patterns provides the simple observation "composition over inheritance" based on Liskov's work. That is: Composing features through a has-a relationship is often a better way to go in the long run anyway.
We has-a way...
The really interesting part is that absolutely nothing new is required in order for us to both follow the self-same progressive enhancement patterns that we've been using all along and gain pretty much all ofthe same values we would with
is="…" without adding any new complexity to the platform itself... How? Through composition rather than inheritance. In concrete terms:
<!-- instead of writing this --> <input type="radio" is="x-radio"> <!-- you write this --> <x-radio> <input type="radio"> </x-radio>
Yes, it's not perfect. Yes, it's not exact pairty. There are some cases where you have to progressively enhance a parent element in order to affect a child, for example. However, if you take some time and consider this carefully, you'll find that in fact, their effects are functionally equivalent in just about every useful way: Form serialization, validation, etc. Both are declarative and have about the same fault tolerance built into their pattern. And, importantly: As a creator of a component using this pattern, you'll have to change and proxy precisely as much in either model for the sake of accessibility, depending on just what DOM what you change. Because of this "very close resemblance" if you find any of these aspects very frustrating, it's worth noting that
is="…" (as specified today) would likely create many of the same frustrations. I realize that this can seem a little unintuitive, so I'll likely talk about the sorts of objections I've heard to these observations in another post.
So, to sum up: We has-a way forward for now through composition. It's not a bad way at all. It's actually quite powerful and good. It isn't perfect. It isn't complete. But we can do a lot of useful things and that's a Really Good Thing™. The fact that we've largely stopped chasing is="…" isn't due to simple stone-walling by any vendor and it isn't a net loss. Ideas need to be able to spread and percolate with lots of minds. The original ideas also need to be able to fail if they aren't fit so that ideas can mix and mutate and ultimately better ones can arise. That's just what I see happening here. In near future pieces I'll write about what sorts of ideas are actively being chased down to help us better solve these problems instead.
Special thanks to my friends, Alex Russell and Peter Rushforth for proofing/commenting on early drafts of this piece and helping them be shorter and less confusing.