The Web Components spec should add support for multiple, named, DOM-valued properties

At last week’s Google I/O 2012 conference, Chrome engineers Alex Komoroske and Dimitri Glazkov gave a talk called, The Web Platform’s Cutting Edge, a good overview of Web Components and custom elements in particular. The demo code shown in that presentation does point to an issue with the current Web Components spec that could seriously constrain the ease with which components can be written and shared. I’ll lay out the case here in hopes this problem can be fixed at an early stage.

But first: A word of appreciation

Authoring a spec for a new standard like Web Components is generally a thankless task, as is the tireless work of promulgating the standard through presentations like the one at Google I/O. So, before saying anything else: a big Thank You to Alex and Dimitri for their work on HTML Templates, Custom Elements, and Shadow DOM. Everything which follows is meant to support your work, not put it down.

Background of the problem

As I’ve blogged about before, I’m a passionate fan of web UI components and believe they will transform UI development. The ability to define new elements for HTML is something designers and developers have long wanted but, until now, could only dream about. In the demo, Alex and Dimitri use Chrome’s early implementation of the proposed spec to create custom elements. They elegantly combine these elements to produce a custom UI component for a user poll:

Web Component Poll

This poll user interface is a large component comprised of sub-components for accordions (or, later in the demo, tabs) and the big iconic choice buttons in the poll for “Semantics”, “Offline & Storage”, etc. All these components are defined with declarative markup.

I enthusiastically agree with the presenters that declarative HTML, including the ability to define custom elements, results in UI code that can be easier to read than a comparable imperative solution in JavaScript. And to its credit, most of the demo code shown in the presentation is self-explanatory.

However, one aspect of the code really jumped out at me as a serious limitation of the current spec: a component host can only pass a single DOM content subtree to the component. As I’ll try to show, I believe that could seriously limit the degree to which a component can expose a meaningful API.

Consider the markup behind those big “choice” buttons. Each choice component includes an icon, a short text summary used as a label, and longer descriptive text that appears in a tooltip on hover. You can think of that per-choice data as, in effect, three public properties of the choice component:

<element name=”x-choice” extends=”div” constructor=”ChoiceControl”>
    <template>
        <div id=”choice”>
            <div id=”icon” class=”mask”></div>
            <content select=”h3:first-of-type”></content>
            <aside>
                <content select=”*”></content>
            </aside>
        </div>
    </template>
    …
</element>

The code above makes use of the proposed <content> element to select specific portions of the DOM tree (using CSS selectors) and incorporate them into the component’s shadow DOM. With that in place, the code for the overall poll component (i.e., the choice host) can instantiate choice buttons with the following markup:

<x-choice value=”semantics”>
    <h3>Semantics</h3>
    <p>Giving meaning to structure, semantics are front and…</p>
</x-choice>
<x-choice value=”offline-storage”>
    <h3>Offline & Storage</h3>
    <p>Web apps can start faster and work even if there is no…</p>
</x-choice>
…

So the first code fragment effectively defines a choice component with three public properties (although these aren’t actually class properties). The second code fragment shows the creation of two instances of that choice component, filling in two of the three choice properties. It’s not shown where the icon property is filled in, but it’s presumably done through styling.

All looks fine so far, but there are some serious issues lurking here.

Problems

The root issue here is that, as currently speced, Web Components can only accept a single DOM-valued content property via markup. This leads to a profusion of problems:

  1. Asking developers to tease apart component content will mean work for devs, and produce inconsistent results.

    Why, exactly, is the choice component using the <h3> tag to specify the text label for the button? Because this component has two textual properties, and the current Web Components spec only lets the developer pass one DOM content subtree to a component. So the component’s author developer has to somehow let the component’s users pack more than one property into the content, and then the dev has to crack that content to extract those properties. The question of how to crack that single content subtree into multiple properties is left entirely up to the developer.

    The tool given to the developer for this purpose is CSS selectors, which at first glance seems powerful. Unfortunately, it’s also a recipe for inconsistency. Every developer will have the freedom—and chore—to approach this problem their own way, guaranteeing the emergence of a handful of different strategies, plus a number of truly bizarre solutions.

    It’s as if you were programming in a system where functions could only accept a single array. As it turns out, we already have a good, common example of a such a system: command line applications. Every command-line application has some main() function that’s handed a single array of command line options, and the application has to decide what to do with them. Although conventions eventually arose with respect to the order and meaning of arguments, there’s still a wide variety of approaches. Some apps rely on argument position, some rely on single-letter flags (“-a”), some rely on full-word named parameters (“–verbose”), some have idiosyncratic microgrammars (e.g., chmod permissions), and many applications support a rich combination of all these approaches.

    Parsing arguments is tedious, boring work. In the early days, a developer throwing an app together might do the absolute minimum work necessary. The result was often inconsistent or incomplete argument support. The dev might eventually be forced to hack on their app until they finally had a roughly functional command line parser. These days, developers can rely on language features, or libraries like Python’s argparse, to “crack” the argument array into a meaningful structure which can be more easily inspected. In particular, it’s invaluable to a developer to be able to directly inspect specific arguments by name.

    The use of CSS selectors does remove some of this tedium, but it still leaves devs without a consistent way to refer to component properties by name, thereby leaving the door wide open for inconsistency. A dev might decide to use DOM structure, HTML tags, element classes, or a combination of all of these to demarcate properties. This will make it much harder for devs to share components, to swap out one component for another, and so on. It would be better if we could learn from the command-line argument example now and head off this inconsistency.

  2. HTML semantics are nearly meaningless when used to identify parameters.

    In the Google I/O demo, the developer of the choice component elected to use HTML tags within the single content subtree to identify properties. In this case, they decided that the first <h3> element in the content would identify the summary text, and everything else would be used as the longer text description.

    But why use <h3> for this purpose? The W3C spec says a heading tag like <h3> should be used to, “briefly describe the topic of the section it introduces”. These choices aren’t introducing sections, so that can’t be the the case here. Neither is this <h3> being used to reflect the rank of an element in a hierarchical document structure.

    In all likelihood, the <h3> is used here, as it often is in practice, to mean something like, “somewhat prominent, but not too prominent”. Visually this usually translates to, “bold text, a little bigger than the body text”. At least, that seems to be how <h3> is being used in this component.

    There’s nothing really wrong with that, but it’s clearly arbitrary. Other developers might easily make a different decision. Later, in the very same demo, the code for the poll component accepts the text label for a different Voting button through the use of a <label> element. So in one place in this app, a button’s label is specified with an <h3>, but elsewhere in the same app, a button’s label is specified with a <label>. I don’t think this reflects any particular negligence on the part of the demo’s developers. I think it’s a latent issue in any scheme that relies on HTML elements for something than the original purpose. Perhaps the code’ s developers did have some reason in mind for using <label> in one place and <h3> in another, but the point is that the reason is not obvious to another party looking at the code.

    The same arbitrary nature of tag choice here applies to use of the <aside> tag to identify the choice description. Try this: show the poll screen shot above to 3 web developers, and ask them which HTML tag they would use to specify the tooltip that should appear when the user mouses over a choice button. I’d be surprised if even one of them picked the <aside> tag. Is the tooltip content here really, as the W3C description says for the <aside> element, “tangentially related to the content around the aside element, and which could be considered separate from that content”? Well, not really. But, maybe; that’s a debatable point. The fact it’s debatable is what’s at issue here.

    In contrast, here’s a tautological statement which wouldn’t generate debate: the choice description in the tooltip is the choice description in the tooltip. The local semantics here aren’t in question. So it’s a shame the property can’t be described in contextual terms like “description”, or “tooltip”.

    The fact that the component is using HTML elements to identify arguments appears sensible, but in practice will be nearly meaningless. Every single time a dev needs to create a new component property, they’ll pick from the 100-odd HTML elements. Their selection may depend on their experience, their mood, the phase of the moon, and which handful of HTML elements they haven’t already used for other properties on the same component. It’s highly likely a different developer (or the same developer on a different day) would make a different selection of HTML elements for the same properties.

    Imagine an object-oriented programming language that forced you to give class properties one of 100 sanctioned property names: “index”, “count”, “name”, etc. Evereyone’s classes would look consistent, but it would be an utterly false consistency. That’s effectively what we’ll get if component authors are forced to choose HTML tags to identify component properties.

  3. Use of CSS selectors hinders a developer’s ability to add new properties.

    Suppose the author of this component needs to add a new property to this choice component. Maybe they want to add a “More about this choice” link to each choice; this link should navigate to another page with more details on that poll choice. Following the example of the <h3> for the choice summary, they decide to define this link property by extracting the first <a> tag in the content to be the link to the “More about this choice” page.

    Perhaps, following their use of the “h3:first-of-type” selector above, they decide to pick out this <a> tag with the similar CSS selector “a:first-of-type”. If they do so, this component author will inadvertently screw up any component user who happened to include an <a> tag somewhere in the description. Suppose a user of this component has already created some code for a choice like this:

    <x-choice value=”semantics”>
        <h3>Semantics</h3>
        <p>
            Semantics in <a href=”…”>HTML5</a> applications…
        </p>
    </x-choice>

    The “a:first-of-type” selector for the “More about this choice” link will accidentally pick up the existing link, thereby breaking this use of the component. The component author could issue a “Breaking Change” notice, warning everyone to include an <a> tag before the choice description. But even that wouldn’t help someone who, for whatever reason, needed to embed an <a> inside of the <h3>.

    The use of selectors here could be made more robust by using the child selector “>”, as in “> h3:first-of-type”. But this gets verbose, and again, isn’t likely to be a universal convention, and inconsistent use of the child selector will only add to the confusion. The fundamental problem is that using CSS selectors for this purpose is inherently fragile.

  4. Arbitrary parameter structure is brittle.

    The fragility of using CSS selectors remains even if one tries to avoid the use of arbitrary HTML elements. Suppose you decide to use element position to identify components. You’ll still up a component which is hard to update.

    Here, a relevant case study is the existing of positional function parameters in most programming languages. To take just one example, consider JavaScript functions. Suppose you’ve defined a function with three parameters: “function foo(a, b, c) {…}”. If you now want to add a new parameter “d”, you have to add it to the end of the argument list to avoid breaking existing users of your function. This can easily produce a function whose parameter order feels unnatural. And to use the new “d” parameter, a function caller must supply the intermediate arguments a, b, and c, even if those are irrelevant to the function call at hand.

    To avoid these problems, programming languages tend to eventually evolve named function parameters. Functions with named parameters are inherently more future-proof and, importantly, allow callers to only specify the parameters they care about.

    The lesson of positional function parameters applies to trying to parse component properties out of the DOM content subtree. Having learned this lesson in countless programming languages, it would be nice to just jump straight to a reasonable solution which allowed for named component properties. While CSS selectors represent a powerful parsing tool, much of that power is completely unnecessary in this context — and some people will inevitably put that extra power to poor use.

  5. Subclasses will compete for parameters with their base classes.

    The above situations quickly deteriorate further when one envisions extending an existing component via subclassing. Subclassing is a crucial means of efficiency in component development, in which the behavior of one component can be specialized for new purposes. As just one case, over 33% of the controls in the QuickUI Catalog are subclasses of other Catalog controls. For example, both DateComboBox and ListComboBox extend ComboBox, which itself extends PopupSource. This separation of concerns is vital to keep the code clean, organized, and maintainable.

    Such subclasses would likely become unworkable as Web Components, because each level of the class hierarchy will be competing with its ancestors and descendants as they all tried to extract properties from the single DOM content subtree permitted by the Web Components spec. If the choice class extracts an <h3> element from the content, then that element is effectively invisible to the <content> selectors of its subclasses. (Or, if you let subclasses have first shot at the content, then the elements they pull out are effectively invisible to their base classes.)

    This significantly complicates point #3 above (using CSS selectors to pull out properties from the DOM content subtree makes it hard to add new properties). Consider a subclass of the choice component above called, say, special-choice. Perhaps the author of special-choice has decided to use the HTML <h4> element to identify a particular property. Now the author of the base choice component decides to add a new property, and elects to use <h4> for this purpose themselves. This has the effect of breaking the special-choice subclass. Obviously, such naming conflicts can arise in regular OOP classes, but here the likelihood of conflict is much greater because of the highly constrained vocabulary of HTML elements.

    Using DOM structure to select properties (point #4, above) is even more brittle when one considers subclasses. If a component class decides to use DOM element position to select content for a given property, and someone creates a subclass that likewise uses element position, the original base class’ API is effectively frozen. Suppose the base class defines a <content> element with selector “:nth-child(3)” , and the subclass goes ahead and uses a <content> with selector “:nth-child(4)”. How is the base class supposed to add support for a new property now? They can’t use position 4, because a subclass is already using that.

    The situation could be worked around by requiring not just specific tags, but also specific class names, but this has problems of its own (see below).

    As currently drafted, the Web Components spec seems highly likely to close off the possibility of rich component hierarchies. Most component developers will probably elect to just copy-and-paste useful code from other developers, rather than subclassing them, to preserve the ability to modify their components in the future.

  6. Class names could help identify properties, but will probably just complicate everything.

    One way to skirt the problems above is to use HTML element classes to identify properties by class name, and reference these classes in the CSS selectors. If you gave up on specific HTML tags, and just used a <div> and a named element class for all properties, the second code fragment above could look like this:

    <x-choice value=”semantics”>
       <div class=”summary”>Semantics</div>
       <div class=”description”>Giving meaning to structure…</div>
    </x-choice>
    <x-choice value=”offline-storage”>
        <div class=”summary”>Offline & Storage</div>
        <div class=”description”>Web apps can start faster…</div>
    </x-choice>
    …

    This could potentially work if everyone agreed to always using an element class name to identify a property, and consistently applied those classes to a single element type (likely <div>) which everyone agreed upon would stand for “parameter”.

    Unfortunately, the more likely result is that throwing element class names into the mix will just complicate everything further. Some devs will write their components that way, but others will insist the use of HTML elements as shown above. Some will require the use of both specific HTML elements and specific class names. E.g., the choice component’s summary property will be forced to be identified with <h3.summary> to avoid possible conflicts with other <h3> elements in the content. This would be verbose and, worse, as a component user you’d have to remember and specify two things, when one should be sufficient.

  7. Invisible component APIs foreclose the possibility of inspection and reflection.

    The choice component in this example effectively presents its hosts with an external API that allows the host to fill in two text properties. Unfortunately, that API is implicit in the design of the <content> elements and their selectors. That makes it hard to programmatically understand what a component is doing.

    At design time, there’s no easy way to statically analyze the code to inspect what those <content> elements are actually being used for. You could potentially parse the HTML to find the <content> elements, then parse their CSS selectors, but that still wouldn’t give you any hints as to what those <content> elements were being used for. At least a formal property name gives you a real idea as to its purpose.

    And at runtime, there would be no easy way to ask a choice component instance questions about which properties it supports: “How many properties do you have?”, or “Do you have a ‘description’ property?” Such run-time inspection of a component’s API (also known as reflection) can be a powerful tool.

    In this very presentation, Google’s developers point toward the benefits of programmatic inspection when they observe that giving web developers the ability to create new custom elements (via the <element> tag) will open new possibilities in researching possible improvements to HTML itself. For example, researchers could statically inspect Web Components actually used by production web sites to determine, for example, the names of the most common custom elements. That in turn could help guide the formal adoption of new HTML elements in future versions of the language itself.

    That’s just one example of what’s possible when APIs are explicit. Such explicitness should be extended beyond component names to cover component property names as well.

A proposal to fix this: Support multiple, named, DOM-valued component properties

All the issues above could be eliminated or dramatically improved if the Web Components spec were amended to let developers create components that accept multiple, named, DOM-valued properties. (Presumably, this support would actually be added to HTML Templates, used by both <element> and <decorator> elements.)

Here are some possible syntax suggestions:

  • Proposal A: Use a consistent tag for component properties.

    A convention of using <div> elements to hold properties (see point #6 above) is a bit odd, because the <div> tag is used simply as a placeholder. The convention could be improved by formalizing a new element specifically for this purpose. Perhaps the existing <param> tag, currently limited to use within <object> elements, could be given new life by being repurposed for use within components. Its definition would need to be extended to support a closing </param> tag form that could encapsulate a DOM subtree:

    <x-choice value=”semantics”>
        <param name=”summary”>Semantics</param>
        <param name=”description”>Giving meaning to …</param>
    </x-choice>
    <x-choice value=”offline-storage”>
        <param name=”summary”>Offline & Storage</param>
        <param name=”description”>Web apps can start …</param>
    </x-choice>
    …

    If <param> can’t be redefined this way, then a new tag like <property> could be created.

    If HTML semantics zealots insist on mapping component content to HTML elements, it’d be possible to let define a component author identify a backing HTML semantic tag that should be used to treat the property’s content for search and other purposes. E.g., syntax within the <element> definition would indicate that the “summary” property should be backed by an <h3> element. This is exactly the way that the <element> tag’s “extends” attribute is already spec’ed to work. The author indicates that an <x-choice> element is backed by a <div>.

    In the exact same way, the author could indicate that a <param> (or <property>) of name=”summary” should be backed by an <h3>. As noted above, the particular choice of backing HTML element might be inconsistent or meaningless, but at least use of a backing element confines the problem to a much smaller audience. That is, the component users shouldn’t need to know that summary property behaves like an <h3>, just like they don’t have to know that an <x-choice> behaves like a <div>. Rather, that would be something only the component author would need to concern themselves with.

  • Proposal B: Expand data- attributes to support data- elements

    HTML developers can already attach arbitrary string data to HTML elements as data- attributes (that is, element attributes prefixed with “data-”). Web Components could build on this precedent to allow data- elements that specify DOM subtrees nested within the component’s content. For example:

    <x-choice value=”semantics”>
        <data-summary>Semantics</data-summary>
        <data-description>Giving meaning to …</data-description>
    </x-choice>
    <x-choice value=”offline-storage”>
        <data-summary>Offline & Storage</data-summary>
        <data-description>Web apps can start …</data-description>
    </x-choice>
    …

    In the case where the property values are pure text, a <data-foo> element could be interchangeable with the corresponding data-foo attribute within the component tag. So one could also write:

    <x-choice value=”semantics” data-summary=”Semantics”>
        <data-description>Giving meaning to …</data-description>
    </x-choice>
    <x-choice value=”offline-storage” data-summary=”Offline & Storage”>
        <data-description>Web apps can start …</data-description>
    </x-choice>
    …

    The data- element form would only need to be used when specifying a real DOM subtree with subelements; otherwise, the data- attribute form could be used.

  • Proposal C (preferred): Let developers define custom property elements

    The above approach could be tightened further by dropping HTML’s historic obsession with restricting the set of tags. By dropping by the “x-“ in the custom element tag, and the “data-“ in the custom property tag, we end up with something much cleaner:

    <choice value=”semantics”>
        <summary>Semantics</summary>
        <description>Giving meaning to structure, …</description>
    </choice>
    <choice value=”offline-storage”>
        <summary>Offline & Storage</summary>
        <description>Web apps can start faster …</description>
    </choice>
    …

    As with the data- element approach above, this custom property element approach could also support the use of a data- attribute on the element tag itself when specifying a simple string property value.

    The cleanliness of the code above comes at the cost of an ambiguity: if you can define your own element tags and property tags, how does the parser know which is which? In the code above, is <summary> a property of <choice>, or is it a custom element in its own right? One resolution would be a precedence rule, e.g., if <summary> is a child of a parent that has a summary property, then treat it as a property, otherwise instantiate it as a custom element. Another resolution would be to follow what Microsoft did with XAML’s property element syntax: allow (or require) the property to be written as <choice-summary>.

    As noted above, if HTML powers that be insist on mapping component content to a fixed set of HTML elements, that could  be handled by letting a component author indicate the HTML element which should be used to back each property. Again, that would relegate the problem to something that only the component author would have to worry about. The writer of the code above that hosts the choice component wouldn’t have to obsess over the question of why <aside> was picked instead of <label>; that detail would only be visible by reading the code for the choice component. The host author only has to deal with <summary>, which has local meaning.

    In any event, the above code sample is clean, and should serve as a goal. Such code would be a joy to write — and read. It moves HTML definitively towards the creation of domain-specific languages, which is where it should go.

    It’s somewhat absurd that we can only define markup terms according to global consensus. That’s like waiting for a programming language committee to approve the names of your classes. The web will move forward at a much faster pace if we can let individual problem domains (online stores, news sites, social networks, games, etc.) define their own tags, with semantics they care about and can agree upon. As the aforementioned uses of <aside> and <label> illustrate, forcing developers to use HTML elements may give the appearance of consistent semantics, but that consistency is merely a facade. In contrast, letting polling organizations define the meaning of a <summary> property for a <choice> component could produce meaningful consistency within that industry.

There’s still time to fix this

In their presentation, Alex and Dimitri indicated that their goal is not to spec out a complete replacement for web UI frameworks. Rather, the goal of their work is to lay a solid foundation on top of which great web UI frameworks can be built by others. In this light, it is hoped that the Web Components spec can be amended to support multiple, named, DOM-valued properties — because that’s exactly the foundation a great web UI framework is going to need.

The QuickUI framework, at least, is more expressive with regard to component content than is possible within the current Web Components spec. That is to say, the existing Catalog of QuickUI controls (and the many others controls written in the service of specific QuickUI-based applications) could not be ported to the current Web Components spec. Or, perhaps, those controls could be ported — but then, for the reasons given above, the collection would then become so brittle that its evolution would come to a halt. That would be a shame.

To be sure, the Google team, and the others working on Web Components, are smart folks, and it’s likely they’ve already given at least some thought to the problems raised in this post. But more input, particularly when informed by real application experience by potential users of a standard, is always valuable in weighing decisions about what should go into the standard. And it’s in that spirit that this post is written.

If you yourself have worked with component frameworks, and have experiences that bear on this issue, please share them with the folks at Google. A good forum for feedback might be the Web Components page on Google+. (Be sure to thank everyone for their work!)

Advertisement

5 thoughts on “The Web Components spec should add support for multiple, named, DOM-valued properties

  1. Thanks for this wonderful post. You’ve raised a really crucial issue here. Here’s my $0.02:

    Web Components are opening the door to a new phase of web application development. Right now we’re standing on the threshold. The light on the other side is dazzling. So we’re going to be disoriented for a while, but that is OK, because once we adjust to the light everything will be much clearer.

    Point #1: I agree. For a while, results will be inconsistent. Wildly inconsistent. We’re still getting our bearings.

    Point #2: You’re right that HTML semantics are somewhat meaningless; his example that h3 is “somewhat prominent” is spot on. I think the common practice will be: Nested custom elements. Just like has its , has its and has its , we’re going to see sets of elements describing the structure of custom elements. It will feel totally natural. The only compelling reason to use HTML elements is if you’re designing for a specific fallback content effect in legacy browsers and you can’t achieve it with CSS (so I think using h3 will be unusual, but I could imagine people using input so they can participate in form submission.)

    Point #3: This is right and wrong. You’re spot on that the selectors you use in are part of your API and you will want to evolve and version that very carefully. However, with reference to my comments on point #2, when components use sets of elements tailored to their specific semantics, you’re going to accidentally collide a lot less.

    Point #4: I agree that relying just on position is a bad idea, but I don’t see people doing that. I think the most common use of position will be to specify that something has only one of something. A tab has only one label, so your custom tab element will select the first tab label just to break ties.

    Point #5: I’m really interested in subtyping components and it is something I haven’t thought about much. I want to study the Quick UI components to understand this issue better. Combine versioning with subtyping and you’ve got multiplicative complexity. There’s a dark corner of my heart, scarred by OO programming, that knows that most successful subtyping comes from someone controlling all of the things in the hierarchy and versioning them in lockstep. Then there’s a tiny amount of successful subtyping adding trivial adornment or convenience. Then there is an ocean of tears.

    Point #6: I don’t see how this is substantially different to Proposal A. I think specific elements (see my comments on Point #2) are a better choice.

    Point #7: This one is really interesting. Recently I have been thinking just about how web components will be documented – the HTML standard is an example, but I’m sure we can do better because web component documentation will be aimed exclusively at app authors. Script, markup and styling APIs will be important. You could imagine taking good documentation (like example markup with placeholders) and mechanising it (like DTDs or other schemas – hopefully in a lightweight way) and using that to support tools. But I don’t think the Web Components standards should bite off this problem, because there needs to be a lot more experimentation to work out what’s useful. (The same goes for lots of other component related stuff like licensing. Let the people who need it experiment on the platform, and then incorporate it in standards if that adds value.)

    Proposal B is interesting for a couple of reasons: First, because the data- element name prefix implies scoping, where my proposed solution of more custom elements doesn’t. (What does a tab mean when it is used outside of a tab strip?) Second, it lets you present attribute values as content, which is nice and succinct. The data- prefixes work against the succinctness, though. It also overloads data- and seems contrary to the original purpose of data-; if you were using data attributes, you might be unhappy to find a whole bunch of them in an element’s dataset that weren’t really data.

    Proposal C is the closest to what I’m thinking will happen, but I think it is fine if these elements use the existing custom element machinery. That machinery will probably be very useful for breaking up the implementation of your component anyway. Scoping is appealing, however what should the semantics be when one of these elements is removed from the outermost custom element and inserted into the DOM? It probably should not change object identity, so does that just throw an exception? Insert it anyway? (Then we may as well not worry about scoping.)

    If nested custom elements are the solution, the problem of using simple (preferably unprefixed) element names in a reliable way becomes more important. It is a difficult problem. But if we can crack it there are many benefits: It is easier to use different versions of the same library in the same page at once; naming collisions between different libraries become manageable; and naming collisions between libraries and the future evolution of HTML might even become manageable. The convention-al alternative – x-qui-combobox > x-qui-combobox-popup – is simple (good) but verbose (boo).

  2. Ah, WordPress ate my inline tags. I meant “Just like summary has its details, video has its track and table has its tr …” and so on.

  3. Hi Jan! Thank you so much for this tremendous research! The thinking is refreshing and helpful to those of us who have been wandering in the spec woods for the last year (that’s me!)

    In the past month, I’ve seen enough examples that clearly show that existing, declarative-only API for distributing insertion points is not enough. I have a few ideas and will have a proposal to address this soon. Once it’s written down, let’s try to take another run at this problem and see if it looks any better.

    Dominic’s response covers most of reactions that I had. Here are my nits.

    There’s slight error in understanding the current Shadow DOM spec, which hinders some of the arguments. Per spec, the selectors in “select” attribute are fragments: http://www.w3.org/TR/shadow-dom/#dfn-selector-fragment, which means that they explicitly only select the children of the host. You can’t accidentally pick off a descendant element.

    I’ll admit I had a bit of fun picking out element names for markup API in the demo, “aside” and “label” probably being some of the more obnoxious examples. In all likelihood, the “named arguments” approach you mentioned will probably take a stronger hold — and is already possible with both using class names and custom tags (as Dominic mentioned)

    By the way, dropping the “x-” prefix is a non-starter, since this gives us no way to discern local semantics from public semantics in the document.

    The “100 sanctioned property names” analogy simply doesn’t fit: this is HTML, not some proprietary format that we’re inventing. And if we were, we definitely shouldn’t be using the Web platform as a starting point. Being able to integrate with public semantics and compose documents that mix both public and local semantics is a big deal.

    Just as much as I want to be able to have a custom tag for x-choice, I want to be able to use hyperlinks, emphasis and even tables inside of its tooltip — and also keep the general meaning of what I am saying declaratively reasonably discernible even if the meaning of local semantics is not available.

  4. Perhaps I’m missing something. . . why can’t the “x-” prefix be dropped? Would it not be possible to discern local semantic of a newly defined element by the definition in the template? Is the concern that a developer might override the functionality of an existing tag?

    Defining all custom tags as extensions of existing elements seems to solve this problem already: if there is any error on part of the local template, the component can simply default to the behavior of it’s super.

  5. Pingback: Quetzal: an experimental translation of the QuickUI component model to HTML custom elements | QuickUI

Comments are closed.