Anne van Kesteren

Content reordering with XBL

Here we see a simple binding being used to reorder content in an HTML page, so that the element with class="nav" is positioned before the element with class="main". CSS associated with the binding is then used to position the two elements.

<xbl xmlns="data:,520e273a-62ad-4528-bb1e-9652bda76d62">
 <binding id="nav-then-main">
  <template>
   <div id="wrapper">
    <div id="col2"><content includes=".nav"/></div>
    <div id="col1"><content includes=".main"/></div>
   </div>
  </template>
  <resources>
   <style>
    #wrapper { display: table-row; }
    #col1, #col2 { display: table-cell; }
   </style>
  </resources>
 </binding>
</xbl>

The HTML page associated with such a binding might look like:

<!DOCTYPE HTML>
<html>
 <head>
  <title>Demo</title>
  <link rel="stylesheet" href="example.css">
 </head>
 <body>
  <div class="main">
   <h1>Demo</h1>
   ...
  </div>
  <div class="nav">
   <p><a href="http://example.com/">Home</a></p>
   ...
  </div>
 </body>
</html>

The CSS stylesheet referred to from that document would include various stylistic rules, and would in particular contain a link to the XBL file, making it apply to the body element so as to reorder the two child elements:

/* Colours and Fonts */
h1 { font: 2em sans-serif; color: green; background: white; }
…

/* Reorder content */
body { -xbl-binding: url(example.xbl#nav-then-main); }

The result of applying the XBL binding above to the HTML given above using the CSS given above is equivalent to the result one would get if one simply placed the div element with class="nav" before the div element with class="main". However, the effect is achieved without needing any changes to the markup. This allows the same markup to be given different presentations dynamically. It also allows changes to be applied across entire sites by merely changing global stylesheet and binding files, much as CSS can be used to change the layout and presentation of a site even without XBL.

Around now would be the time to read (and review) the XML Binding Language (XBL) 2.0 specification. Besides content reordering it allows authors to implement new DOM interfaces, create templates (that can inherit) and other do fun things. One of the main features web designers will probably like is that it allows you to add a whole bunch of div elements without polluting the markup.

Comments

  1. For some reason the first two blocks show up nearly empty in Safari. Might it be Safari trying to interpret the code?

    Posted by Mark at

  2. Wow! That's neat! I just discovered XBL for me from your post.

    BTW, it's a pity that Opera didn't implement XBL in Opera 9 when Firefox has support for it from version 1.0

    Posted by FataL at

  3. Firefox is partially based on XBL. Firefox doesn’t have support for the standard being discussed here though and it’s good that we haven’t yet implemented it, because that would be a premature implementation. At the point Opera 9 shipped the specification was not really ready. At the point when we would have to implement this for it to work in Opera 9 there was pretty much no proposal.

    Posted by Anne van Kesteren at

  4. Thanks for explanation Anne.

    In short what the main differences between W3C's XBL 2.0 proposal and Mozilla's XBL 1.0?

    Posted by FataL at

  5. @Mark:

    Indeed, according to OmniWeb's (and Webkit's) DOM Inspector, there is an <xbl> element inside the first <pre> element.

    Posted by Ryan Cannon at

  6. This looks very interesting. Never heard of it before. Gonna have a look at it later.

    Posted by Wilco at

  7. A bit too late now, but I've often thought CSS should have had something like this:

    :create#main_part {
           // Create a new div around the article text
           surround : #article;
    }
    /* Now transform the document */
    .left_column {
           // We want this material to display before the body text
           move-to : start-of(#main_part);
    .right_column {
           // We want this material to display after the body text
           move-to : end-of(#main_part);
    }

    You could then reference the moved content by referring to it as #main_part #article, thus allowing CSS to differentiate between those browsers that understood an XBL-like transformation and those that didn't.

    Posted by Anthony at