We need behaviors, not inheritance!

Tomasz Jakut
Content Uneditable
Published in
4 min readMay 10, 2017

Not so long ago I’ve claimed (in Polish) that Web Components are dead, but I wouldn’t be myself if I hadn’t started thinking why some ideas didn’t work and what exactly went wrong. The thing that caught my eye was this little, poor [is] attribute, which is still a cause of a great argument. Then it suddenly came to me that W3C might be taking a wrong approach.

Object Oriented Programming and Document Object Model

If something is called Document Object Model, even if we try really hard to bend the truth, we can’t escape stating the fact that it’s still a part of the good, old OOP (DFM — Document Functional Model; I challenge you, Functional Programming lovers!). That’s why also Web Components (WC) are — willingly or not — a part of Object Oriented approach.

Custom Elements (CE) are the ones, which suffer from it the most, because they’re created just as classes that must extend HTMLElement, a native DOM constructor. Otherwise the browser will throw an error while attempting to create such element:

It’s clear that everything connected with WC will be also connected with OOP. It’s no different in the case of [is] attribute, that allows to “extend native elements” or simply, inherit from them.

“Why should I inherit from a button?!!!”

This question shows the nonsense of such approach. When we develop an application, do we even think that one button should inherit from another? Such weird approach is absent even in Block Element Modifier methodology, which introduces a concept of modifying instead of inheriting:

In CE however the big button is a class inheriting from a built-in button class:

Let’s be honest: it doesn’t look nice. Such mechanism reminds me of some silly examples of OOP in nearly all books about Java or PHP (class Dog extends Animal…). While React recommends composition, the official standard is stuck with some primitive techniques.

Issues with inheritance

Let’s imagine that we have a button that toggles a menu which is created as a CE:

Its purpose is straightforward: to toggle menu and update appropriate ARIA attributes. The question is: do we really think about this button as a button which is intended to toggle menu or rather as a button, which performs an action of toggling menu? Does an action connected with a button change its nature (even if it looks exactly the same)? CE specification claims so: button and button[is=nav-toggler] are two totally different elements.

However if we change [is=nav-toggler] to [data-toggle=nav], then we’ve got Bootstrap button for opening… anything. Well, we can even use it with a link, which allows as to create a nice fallback (if JavaScript won’t work, the link will just bring us to the desired element). In the case of CE we don’t have this possibility: nav-toggler could only be a button.

Another example: div[is=my-draggable] will be a draggable div, but dialog[is=my-draggable] won’t work — we’ll have to wrap it with a div

This leads to creating artificial beings. To make specific elements draggable, we’ll be creating separate classes for every specific element, which will be doing exactly the same: div[is=div-draggable], p[is=p-draggable], blockquote[is=blockquote-draggable] etc. It violates the “Don’t Repeat Yourself” principle and at the same time, it shows how nonsensical naming rules for CEs are (something which is totally fine when creating custom elements — e.g. dgui-slider — doesn’t make sense when using a value of [is] as an attribute to extend some native element). It’s just an unnecessary coupling of specific behavior with a specific element.

Although the proposition of making HTML element comprise of many smaller interfaces appeared later in the discussion, I fear that it would be even worse than extending whole elements using the [is] attribute. If we want to have a button, which toggles menu, we just add an event listener to the button and that’s it. No one will create a new nav-toggler element, which implements 30 interfaces, to create a button which toggles a single menu. And if someone’s really going to do it, he’ll probably forget about HTMLActivateClickOnSpace interface and the full accessibility of this custom button is gone forever.

We need behaviors!

Just imagine that we’d be able to do this:

There is an ongoing discussion about allowing creation of custom attributes in WHATWG, with voices that it would make sense only if such attributes would have lifecycle reactions (just like CEs). I’m all for it! Thanks to a separation of behaviors from specific elements and moving them to attributes, we’d be allowed to use the same code to modify the behavior of any HTML element. We won’t think anymore about artificial relationships between elements on a page (is that button just a button or a specialized button?), but about behaviors — we’ll focus on what the element does and not what the element is. Simple, efficient, elegant.

So how about creating a polyfill and pushing it to W3C?

--

--