XBL XBL XBL!

© Bill Watterson and Universal Press Syndicate.

I thought I should provide some sort of introduction to XBL so that when you're sick of me saying it, at least you'll know what I'm talking about.

This is an intentionally simplified introduction, but it also reflects my perspective on how XBL can be used. There is no guarantee that this reflects the official priorities of XBL. For more information refer to the XML Binding Language (XBL) 2.0 specification and XBL 2.0 Primer.

Descriptions of XBL inevitably end up sounding like binding blah, blah bound document blah, blah bound element blah, blah binding document. There's some definitions near the end of this article.

Overview: CSS on Steroids

XBL - the XML Binding Language - provides a mechanism for associating enhanced presentation or behavior with selected elements in a web-page.

It's like CSS on steroids.

CSS allows styling information to be simply and unobtrusively associated with an element. XBL enhancements (or bindings) are associated with an element in a similar manner, but with XBL you can re-order the children of the bound-element, or insert new content with scoped styling, add new scripting methods and handle all events that propagate through the element.

Even when content is re-arranged or inserted by XBL, the DOM of the bound-document is unaffected. For example, a web-site could serve pages with no banner or site navigation in the body,

<body>
 <p>I am the unique content of this page.</p>
</body>

then XBL could be used to insert the banner, navigation, footer, etc.

<body>
 <div id="banner">
  <h1><img class="logo" src="/logo.png" style="vertical-align: middle;" /> meekostuff.net</h1>
 </div>
 <div id="navigation">
  <ul>
   <li><a href="/">Home</a></li>
   <li><a href="/about.html">About</a></li>
   <li><a href="/projects/">Projects</a></li>
   <li><a href="/blog/">Blog</a></li>
   <li><a href="/contact.html">Contact</a></li>
  </ul>
 </div>
 <div id="main">
  <p>I am the unique content of this page.</p>
 </div>
 <div id="footer">
  <p>Perhaps a site-specific footer would be useful.</p>
 </div>
</body>

Although the banner, etc is now displayed to the user, the page author doesn't have to worry that IDs and classes in the inserted markup clash with those already present because XBL keeps the inserted markup invisible to the bound-document.

Rationale: Semantics and Scalability

The complex enhancements that facilitated by XBL allow the page author to concentrate on writing succinct and semantically appropriate markup and then delegate presentation and behavior as required. This will generally result in improved maintainability, accessibility and SEO of web-pages.

Web-pages are becoming more dynamic, both in the widgets and effects that enhance the user experience, and in the insertion and removal of content. Web-applications, as the extreme example, are becoming common-place. As more features are introduced and content is inserted or removed (including the presentational content of widgets) several problems can arise:

XBL mitigates all these problems resulting in a more scalable solution for enhancing web-pages.

Demo

XBL bindings can enhance or override the default presentation and behavior of a bound-element with one or more of the following:

Templates
Rearrange the child elements of the bound-element, allowing you to add content or change the structure of the tree rooted at the element.
Styles
Declare styles for content added in the template.
Handlers
Declare event listeners for events that propagate through the bound-element.
Implementations
Declare methods and properties that can be called from handlers. They are also conditionally available on the bound-element.

The following example provides simple illustrations of these main aspects of XBL bindings. It is an XBL document containing a single binding definition which implements a numeric-input field similar to that proposed in HTML5 (but with much less functionality).

<?xml version="1.0" encoding="UTF-8"?>
<xbl xmlns="http://www.w3.org/ns/xbl">

 <binding element="input[type=number]">
  <template>
   <div id="bindingBox" xmlns="http://www.w3.org/1999/xhtml">
    <div id="textBox">
     <input type="text" id="text" />
    </div>
    <div id="buttonBox">
     <div id="stepUp"></div>
     <div id="stepDown"></div>
    </div>
   </div>
  </template>
  <implementation>
({
  stepUp: function() {
    var input = this.shadowTree.getElementById("text"); input.value++;
  },
  stepDown: function() {
    var input = this.shadowTree.getElementById("text"); input.value--;
  }
})
  </implementation>
  <handlers>
	<handler event="click">
var stepUp = this.shadowTree.getElementById("stepUp");
var stepDown = this.shadowTree.getElementById("stepDown");
if (event.target == stepUp) this.stepUp();
if (event.target == stepDown) this.stepDown();
	</handler>
  </handlers>
  <resources>
    <style>
     #bindingBox {
      display: block;
      margin: 0; padding: 0;
     }
     #textBox, #buttonBox {
      float: left;
      margin: 0; padding: 0;
     }
     #text {
      height: 14px;
      margin: 0;
     }
     #stepUp, #stepDown {
      display: block;
      width: 15px; height: 8px;
      margin: 0; padding: 0;
      border: 1px solid ButtonShadow;
      border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
      overflow: hidden;
     }
     #stepUp {
      background: ButtonFace url(arrow-up.gif) center -2px no-repeat;
     }
     #stepDown {
      background: ButtonFace url(arrow-dn.gif) center -2px no-repeat;
     }
    </style>
  </resources>
 </binding>
	
</xbl>

And here is a demo of how that would work in a browser if this XBL document were associated with a web-page whose only content was <input type="number" />. You should be able to use the up/down arrow buttons to increment/decrement the value of the input.

Let's step through the example code:

<?xml version="1.0" encoding="UTF-8"?>
<xbl xmlns="http://www.w3.org/ns/xbl">

The XBL document is an XML document with a xbl element in the XBL namespace as the root.

 <binding element="input[type=number]">

Binding definitions (only one in this example) are contained by the binding element. The element attribute contains a CSS Selector specifying which elements in the target document will be bound to this binding - in this case on input elements where the type property is "number".

  <template>
   <div id="bindingBox" xmlns="http://www.w3.org/1999/xhtml">
    <div id="textBox">
     <input type="text" id="text" />
    </div>
    <div id="buttonBox">
     <div id="stepUp"></div>
     <div id="stepDown"></div>
    </div>
   </div>
  </template>

Templates can be used to add content to the bound-element and even change the layout. For empty bound-elements - like inputs - the template element is like an iframe that overlays and hides the bound-element. The person viewing the page sees the contents of the template, but scripts on the page still interact only with the bound-element.

  <implementation>
({
  stepUp: function() {
    var input = this.shadowTree.getElementById("text"); input.value++;
  },
  stepDown: function() {
    var input = this.shadowTree.getElementById("text"); input.value--;
  }
})
  </implementation>

Implementations add new methods (or properties) to bound-elements. Inside these methods the binding is referenced with this, the bound-element with this.boundElement and the content of the template element (which appears inside the bound-element) with this.shadowTree.

The shadow-tree has a getElementById() method, which, in terms of our iframe-analogy would make the shadow-tree the document-node of the iframe.

  <handlers>
	<handler event="click">
var stepUp = this.shadowTree.getElementById("stepUp");
var stepDown = this.shadowTree.getElementById("stepDown");
if (event.target == stepUp) this.stepUp();
if (event.target == stepDown) this.stepDown();
	</handler>
  </handlers>

Handlers in the XBL-document map to event-listeners on the bound-element. They are called in the context of the binding-implementation.

  <resources>
    <style>
    ...
    </style>
  </resources>  

Style information for XBL-bindings must be nested within a resources element. The styles are applied to the elements in the shadow-tree and don't effect elements in the bound-document.

Use-cases

XBL is especially suitable for features that add presentational content to the page as part of their implementation, such as:

Some of these enhancements could still function with scripting disabled.

Alternatively, because XBL is automatically applied to targeted elements (even during document load) it can be used purely as a built-in event-delegation system. This simplifies the implementation of widgets with event driven functionality:

Definitions

XBL

When I refer to XBL, I'm usually talking about the W3C's XML Binding Language (XBL) 2.0 specification. This is also commonly known as XBL2.

I have a project that provides a subset of XBL, XBLUI - XBL User Interface enhancements. I won't make any distinction between XBL - the specification, and XBL - this implementation, except to point out where I extend the spec.

There are other technologies and standards (see History) that offer features similar to XBL, including Mozilla's earlier (and non-compatible) eXtensible Binding Language - also known as XBL1, and Microsoft's even earlier DHTML Behaviors. Sometimes I will group these into a vague XBL category. In those cases I won't point out the differences between them unless it is to be explicit about how something is done in XBL2.

Bindings

In XBL, enhancements to elements in a web-page are called element bindings, or just bindings. Other technologies use the term behaviors instead of bindings.

Bound Element

When a binding definition is associated with an element, a binding-object is created from the definition, and the element becomes the bound-element of the binding object.

XBL Document

A XBL document is an XML document that contains binding definitions.

Binding Document

When a XBL document is associated with a web-page then it becomes the binding-document for the page.

Bound Document

When a XBL document is associated with a web-page then the page becomes the bound-document for the XBL document.

History

IE5 was the first browser with the ability to declaratively associate behaviors to elements. It provided DHTML Behaviors which are defined in HTC files and associated with elements using CSS or scripting methods. DHTML Behaviors support many of the goals of XBL, although perhaps not in a robust, performant and cross-browser manner. For whatever reason, they have not seen much uptake.

Mozilla then implemented the Extensible Binding Language (also referred to as XBL1 or Mozilla XBL) which, along with XUL, Javascript and CSS, is used to implement the Firefox user interface. Like DHTML Behaviors, Mozilla XBL has not had much uptake outside of its parent organization.

The XBL2 specification attempts to build on the successes and resolve some of the failures of these earlier element binding solutions. Mozilla and Webkit projects have expressed the intention to provide native implementations in the near future, and other browser vendors have apparently expressed an interest.

Notes

Event Delegation

Event handling behavior can be associated with elements in two ways:

The second approach is referred to as event-delegation and has the following advantages:

The first approach is better if you have to dress up the element anyway.

There are many event-delegation systems implemented in Javascript libraries, including: