Wednesday, April 23rd, 2008

Embed your data- in HTML 5

Category: Dojo, HTML, Standards, Unobtrusive JS

<p>Simon Willison pointed out the part of the HTML 5 spec that discusses a way to add attributes to HTML elements for your own needs via data-.

For example, a spaceship for a game:

  1. <div class="spaceship" data-id="92432"
  2.     data-weapons="laser 2" data-shields="50%"
  3.     data-x="30" data-y="10" data-z="90">
  4.  <button class="fire"
  5.         onclick="spaceships[this.parentNode.dataset.id].fire()">
  6.   Fire
  7.  </button>
  8. </div>

Every HTML element may have any number of attributes starting with the string “data-” specified, with any value.

These are intended to store custom data private to the page or application, for which there are no more appropriate attributes or elements.

The dataset DOM attribute provides convenient accessors for all the data-* attributes on an element. On getting, the dataset DOM attribute must return a DOMStringMap object, associated with the following three algorithms, which expose these attributes on their element:

Simon points out that “this will be incredibly useful for unobtrusive JavaScript where there’s no sensible place to store configuration data as HTML content. It will also mean Dojo has an approved method for adding custom attributes to declaratively instantiate Dojo widgets.”

Related Content:

14 Comments »

Comments feed TrackBack URI

Incredibly useful indeed! I rely heavily on some annoying workaround techniques to attach behavioural metadata to elements. Nice to know that in HTML5 we’ll have the tools we need to do it with real HTML attributes.

If you’re stuck looking for a way to embed config data into an element, try turning your data into JSON, url-encode it, and put it into the class attribute. Then on page load, scan for elements containing a JSON-esque class, parse the JSON into an object, and assign that to a child object of the element. Thereafter, your unobtrusive scripts can access the data via $(‘element’).dataobj . I’ve built a robust bootstrapped library using this technique, which works on all major browsers as far back as IE6.

Ian Ring

Comment by httpwebwitch — April 23, 2008

You could add attributes to elements in XHTML all along and you didn’t need the precursor “data-” for my attribute names, though I could see how a precursor would be useful and a best practice.

Comment by delorie — April 23, 2008

Well, you _could_ add custom attributes all along, but my understanding was that these had to be name-spaced attributes (ie x:newAttribute=”something”), and accessing name-spaced attributes via JS is a bit more of a pain, as I recall. Its why I’ve tried to move away from custom attributes. The data concept is nice, but feels wrong to me, like when designers have 10 “classes” on an element as JS hooks and data.

Comment by Jon Hartmann — April 23, 2008

Just create a custom namespace and bind to those attributes. Not sold on this one.

Comment by docyes — April 23, 2008

I see more and more the dream of having a strict XML web slipping away. It would have been so beautiful if everything was XHTML and easy to parse. Adding custom attributes this way without using namespaces will make this future switch harder.

Comment by Spocke — April 23, 2008

@Spocke
The tag soup web is here to stay. It’s too difficult to get everyone to “play nice” and produce valid XML. I don’t see a validating web happening, pretty much ever.

HTML5 is a sorely needed upgrade to the tag soup web, so I’m glad they’re being practical about the sort of extensions that go into it.

Comment by Joeri — April 24, 2008

@Joeri: Yes, it seems to be that way. I guess it was all the less geeky web people not understanding the concept and need for XML as a HTML storage format. It’s a shame it feels like a big step backwards but I guess the majority never took that step anyway so thats the failure of XHTML.

Comment by Spocke — April 24, 2008

Totally agree with docyes – namespacing is the way to go and what’s more, its not *that* complex. Its just a pain with non-standards-compliant browsers (i.e. IE) which don’t support the getElementsByTagNameNS method.

Comment by khaitu — April 24, 2008

Wow. Why bother to write an HTML 5 spec at all? Apparently the only thing a spec does is make people complain about what it prevents them from doing.
.
I wonder what was wrong with:
.

getDocumentById(“spaceship-92432″).weapons = “laser-2″;
// etc

Comment by trav1m — April 24, 2008

I wonder what was wrong with:
.
div id=”spaceship-92432″ class=”spaceship”

/div
script
getDocumentById(“spaceship-92432″).weapons = “laser-2″;
// etc
/script

Comment by trav1m — April 24, 2008

The great thing about this approach is that it is a convention.
1) It will be supported on all current browsers
2) By making it a standard future browsers can be expected to support it
3) It describes something that is already done, and works well.

In principle I think xhtml is the way to go but in reality you have to deal with backwards compatibility. An observation core to the design of http & html is that of inconsistency. The more you rely on strong semantics the less consistency you can accept and the more often you will fail to show a page.
It seems to me that this fits nicely with REST principles.

Comment by hvendelbo — April 24, 2008

@httpwebwitch && John Hartmann:

Agreed that URL-encoded JSON is the way to go for binding complex data to HTML elements. But why overload the class or id attributes with this data? I think the constant overloading of these attributes for unobtrusive JavaScript is reason for the data- attributes in the HTML 5 spec.

I don’t understand why namespacing is an issue. You could always add arbitrary expando attributes to HTML and the browser would ignore what it didn’t understand, even as your script had access to it. This was the approach we took at Orbitz when I worked there. Check out the “agent” attribute on any number of tags at http://www.ebookers.com. If you’re worried about your HTML validating, you can always create a custom DTD that includes your expando elements.

Comment by bdillard — April 24, 2008

I know this post is old, but I wanted to mention a Rails plugin I just finished that addresses this issue. I implemented it using the somewhat recent data storage methods of jQuery, Prototype and Mootools.

http://github.com/CodeOfficer/js-data-helper/tree/master

Comment by codeofficer — May 10, 2009

Data attributes allow parameters to be written in HTML and parsed into JavaScript, as used by the the Distal engine.
http://code.google.com/p/distal

Comment by Dmitri — March 5, 2012

Leave a comment

You must be logged in to post a comment.