Category Archives: Standards

Standards, protocols, recommendations and guidelines.

The Cascade: Part 2 (Finally!)

Exactly one year ago from this day, I published part 1 in a series of articles about CSS cascading and inheritance. However, due to various factors (mostly laziness), the sequel never got published… Until now! Today, I’m going to take a break from the XBL series of articles (which will resume in a day or so) and finally publish the long awaited conclusion to this series. If you haven’t read part 1 (or even if did a long time ago), I suggest you do so now before continuing.

Following on from the first article in which we looked at how to find all the style declarations that applied to each element, we’re going to show how these are sorted by order of precedence, to determine which ones are applied to the element.

Sorting

Steps 2, 3 and 4 of the algorithm deal with sorting the declarations into the order of precedence. From the exercise in the part 1, we were left with 4 rule sets which applied to the p element in the sample document. For the purpose of this exercise, I’m just going to add a few more declarations and annotate them with their origin.

p { margin: 1em 0; } /* User Agent */
* { background: blue none !important; color: white !important; } /* User */
P { text-indent: 1em; text-align: left; } /* User */
p { text-align: justify; } /* User */
#content p { margin: .8em 0; line-height: 1.2; text-indent: 0 !important; } /* Author */
p { line-height: 1.4; } /* Author */

Step 2

Step 2 of the cascade says to sort the rules according to importance and origin. The following is the order of precedence specified in CSS 2.1.

  1. user agent declarations
  2. user normal declarations
  3. author normal declarations
  4. author important declarations
  5. user important declarations

If we discard the selectors for now (they’ll be need again in step 3 below), we’re left with a list of declarations. A declaration is a property and its associated value. We can then proceed to sort them into the order specified.

  1. User Agent Declarations
    1. margin: 1em 0;
  2. User Normal Declarations
    1. text-indent: 1em;
    2. text-align: left;
    3. text-align: justify;
  3. Author Normal Declarations
    1. margin: .8em 0;
    2. line-height: 1.2;
    3. line-height: 1.4;
  4. Author Important Declarations
    1. text-indent: 0 !important;
  5. User Important Declarations
    1. background: blue none !important;
    2. color: white !important;

Step 3

Step 3 of the cascade then says to sort the rules with the same importance and origin by the specificity of the selector. The details of calculating the specificity is out of scope for this article, but it has been covered by others. See Andy Clarke’s Specificity Wars and Molly Holzschlag’s CSS2 and CSS2.1 Specificity Clarified.

This step is important for cases where two declarations for the same property have the same importance and origin. In this example, this occurs for both user normal declarations (two text-align declarations) and author normal declarations (two line-height declarations).

For the user normal declarations, these are the rule sets involved:

p { text-indent: 1em; text-align: left; } /* User */
p { text-align: justify; } /* User */

As you can see, both have the same selector (p), which has a specificy of 0,0,1. So, sorting by specificity in this case makes no difference. However, for the author normal declarations, these are the rule sets involved:

p { line-height: 1.4; } /* Author */
#content p { margin: .8em 0; line-height: 1.2; text-indent: 0 !important; } /* Author */

These 2 rule sets each use different selectors which have different specificity. The selector #content p has a specificity of 101. The selector p has a specificity of 0,0,1. Since 1,0,1 is a higher specificity than 0,0,1, the former takes precedence. So the order of author normal declarations is changed to the following:

  1. margin: .8em 0;
  2. line-height: 1.4;
  3. line-height: 1.2;

Step 4

The forth and final step of the sorting process involves sorting declarations which have the same importance, origin and specificity by the order they are specified in the CSS. This is where the order of the user normal declarations from step 3 is resolved. In this example, given that I listed the declarations in the order in which they appeared, no change needs to be made to the above list.

In cases where there is more than one declaration for a property, the latter declaration overwrites the former, which is effectively discarded. This leaves the following list of declarations to be applied to element.

  1. text-align: justify;
  2. margin: .8em 0;
  3. line-height: 1.4;
  4. text-indent: 0;
  5. background: blue none;
  6. color: white;

This concludes the series about the cascade, but the related issue of inheritence still needs to be addressed and I intend to do so at some point in the future. However, I don’t expect that it will take another year before I do… But who knows? 🙂

XBL Part 2: Event Handlers

This is part 2 in my 5 part series on XML Binding Language. If you haven’t already read part 1, I suggest you do so now before you continue reading. XBL provides a mechanism for attaching event listeners to elements, and declaring the conditions under which the handlers should be invoked. In this article, I’m going to compare traditional event handling techniques with those that will be provided using by XBL.

Traditional Event Handling

The following example illustrates some typical unobtrusive scripting techniques to attach event listeners, including both the window.onload property and the addEventListener() function.

window.onload = function() {
    var nav = document.getElementById("nav");
    var li = nav.getElementsByTagName("li");
    for (var i = 0; i < li.length; i++) {
        li[i].addEventListener("mouseover", doSomething, false);
    }
}

Another common method, though generally considered bad practice these days, is to use the HTML onevent attributes, like the following.

<li onmouseover="doSomething();">...</li>

There are advantages and disadvantages to both methods, but the former is generally considered better because it separates the behaviour layer from the markup. However, the latter is a simple declarative syntax that can be quite convenient in some cases.

Handling Events with XBL

In XBL, instead of requiring authors to use a script to search for the elements, the event listeners are attached to those that the binding is attached to. XBL provides a simple declerative syntax which also continues to separate the behaviour layer from the semantic markup layer. Event listeners are declared using both the handlers element and its child handler elements.

In the previous article, we looked at how bindings are associated with elements using a selector, just like in CSS. For example, this binding will be attached to all li elements within an element with id="nav".

<xbl xmlns="http://www.w3.org/ns/xbl">
  <binding element="#nav li">
    <handlers>
      <handler event="mouseover">
        doSomething();
      </handler>
    </handlers>
  </binding>
</xbl>

If present, only one handlers element is allowed within a binding, but it can contain as many child handler elements as required, to capture as many different events as you like. This binding declares a single event handler that listens for the mouseover event. When the mouseover event is fired on a bound element (i.e. an element to which this binding is attached), the handler is invoked in effectively the same way it would have been using the other methods shown above.

Event Filters

There are often times when you only want to handle an event under certain conditions. For example, when you want to capture a click event and do something only when the user clicks the left mouse button; or capture a keyboard event and perform different functions depending on which key was pressed. In traditional scripting techniques, you have to check the values of certain properties using if or switch statements in your function, like the following.

function doSomething(e) {
    var code;
    e = e || window.event;
    code = e.keyCode || e.which;
    switch(code) {
        ...
    }
}

Much of that involves handling of browser incompatibilities, but even if all browsers supported the DOM Events standard, it’s still quite complicated. XBL addresses this by providing a simple declarative syntax for describing these conditions using attributes on the handler element.

In the following example, separate handlers are provided for for handling the keypress events depending on which character was entered. The first handles the character a, the second handles b. If any other character was entered, neither of these two handlers will be invoked.

<handlers>
  <handler event="keypress" text="a">
    doSomethingA();
  </handler>
  <handler event="keypress" text="b">
    doSomethingB();
  </handler>
</handlers>

Similarly, in the following example, the handler will only be invoked when the user left clicks while holding the Shift key down.

<handlers>
  <handler event="click" button="0" modifiers="shift">
    doSomething();
  </handler>
</handlers>

Other Common Event Filters

There are several other filters that can be used. The following list is a subset of the available attributes for this purpose. I suspect these will be the most commonly used filters because they cover the majority of mouse and keyboard event usage on the web today.

button
A space separated list of mouse buttons pressed by the user. e.g. button="0 2" matches either the left or right mouse buttons.
click-count
The number of times the user clicked. e.g. click-count="2" matches double clicks.
text
The text entered by the user. This is different from the key code because it matches the letter that was entered, regardless of the keys that were pressed. This is particularly important for languages that require several key presses to enter certain letters.
modifiers
Modifer keys, including alt, control, shift, meta, etc.
key
Matches against the keyIdentifier value defined in DOM 3 Events
key-location
For matching the location of the key that was pressed on the keyboard, including standard, left, right and numpad.

In the next article in this series, I’ll be taking a look at XBL Templates, which will provide significant presentaional enhancements, particularly in regards to layout.

XBL Part 1: Bindings

XML Binding Language (XBL) is a mechanism for extending the presentation and behaviour of a document. The XBL 2.0 specification recently reached Last Call and it has some very cool features to look forward to using in a few years. It’s somewhat based upon the original XBL 1.0 specification created and implemented by Mozilla, though it has been significantly redesigned and is not backwards compatible with it.

While reading this, keep in mind that XBL is still a working draft and any feature I discuss may change significanly between now and when it becomes a recommendation. Presently, there are no implementations of XBL 2.0, so you can’t use it yet.

Bindings

A binding is a way to attach presentation and behaviour to an element. The concept is similar to the way we already style elements using CSS and attach event listeners to them with JavaScript, but the idea is to add an extra layer of abstraction in between to simplify the process. Bindings are a not a way to replace existing authoring tools like CSS and JavaScript, but rather an enhancement to them.

There are four main aspects of a binding: implementations, templates, handlers and resources. In this whopping 5 part series, I intend to give you a brief overview of each of these components to explain their purpose and functionality.

Implementations
Describe a set of methods, properties and fields on an element.
Handlers
These offer an improved way to declare event listeners.
Templates
A way to enhance the presentation (particularly layout) beyond what is possible with existing CSS techniques.
Resources
Additional stylesheets, images, video, audio or any other content associated with the binding.

Sample Bindings

Bindings can be attached to elements in several ways: a selector in the element attribute of the binding element, the ‘binding‘ property in CSS or using a script.

The element Attribute

The element attribute specifies a selector. The same type of selector you use with CSS, so it’s very easy to understand. This binding will be attached to all elements that match the selector: #nav li.

<xbl xmlns="http://www.w3.org/ns/xbl">
  <binding element="#nav li">
    <implementation>...</implementation>
    <template>...</template>
    <handlers>...</handlers>
    <resources>...</resources>
  </binding>
</xbl>

The ‘binding‘ Property

The ‘binding‘ property can be used in in your CSS to attach a binding, in exactly the same way you apply any other other style to an element.

bindings.xml:

<xbl xmlns="http://www.w3.org/ns/xbl">
  <binding id="foo">
    <implementation>...</implementation>
    <template>...</template>
    <handlers>...</handlers>
    <resources>...</resources>
  </binding>
</xbl>

The stylesheet:

#nav li { binding: url(bindings.xml#foo); }

Using a Script

Elements will implement the ElementXBL interface, which defines three methods: addBinding(), removeBinding() and hasBinding(). The addBinding() method can be used to attach a binding to an individual element using a script, like this:

var e = ...; // Get the element somehow
e.addBinding("bindings.xml#foo");