How to Use HTML5 Data Attributes

Back in the old XHTML/HTML4 days, developers had few options when storing arbitrary data associated with the DOM. You could invent your own attributes but that was risky; your code would be invalid, browsers could ignore the data, and it would cause problems if the name ever became a standard HTML attribute.

Therefore, most developers relied on the class or rel attributes since these were the only ones which permitted reasonably flexible strings. For example, presume we were creating a widget for displaying messages such as Twitter timelines. Ideally, the JavaScript should be configurable without changing its code — so we define the user’s ID in the class attribute, e.g.

<div id="msglist" class="user_bob"></div>

Our JavaScript code would look for an element with the ID msglist. A little string parsing would find a class starting with user_, assume “bob” is the ID and display all messages from that user.

Say we then wanted to define a maximum number of messages and ignore those older than six months (180 days):

<div id="msglist" class="user_bob list-size_5 maxage_180"></div>

Our class attribute has become increasingly cumbersome; it’s easy to make errors and JavaScript parsing is more complex.

HTML5 data Attributes

Fortunately, HTML5 introduces custom data attributes. You can use any lowercase name prefixed with data-, e.g.

<div id="msglist" data-user="bob" data-list-size="5" data-maxage="180"></div>

Custom data attributes:

  • are strings — you can store anything which can be string encoded, such as JSON. Type conversion must be handled in JavaScript.
  • should only be used when no suitable HTML5 element or attribute exists.
  • are private to the page. Unlike microformats, they should be ignored by external systems such as search engine indexing bots.

JavaScript Parsing #1: getAttribute and setAttribute

Every browser will let you fetch and modify data- attributes using the getAttribute and setAttribute methods, e.g.

var msglist = document.getElementById("msglist");

var show = msglist.getAttribute("data-list-size");
msglist.setAttribute("data-list-size", +show+3);

It works, but should only be used as a fallback for older browsers.

JavaScript Parsing #2: jQuery data() method

Since version 1.4.3, jQuery’s data() method has parsed HTML5 data attributes. You don’t need to specify the data- prefix so the equivalent code can be written:

var msglist = $("#msglist");

var show = msglist.data("list-size");
msglist.data("list-size", show+3);

However, be wary that jQuery cleverly attempts to convert the data to a suitable type (booleans, numbers, objects, arrays or null) and avoids touching the DOM. Unlike setAttribute, the data() method will not physically change the data-list-size attribute — if you inspect its value outside of jQuery, it would still be ‘5’.

JavaScript Parsing #3: the dataset API

Finally, we have the HTML5 dataset API which returns a DOMStringMap object. You should note that data-attribute names are mapped by dropping the data- prefix, removing hyphens and converting to camelCase, e.g.

attribute name dataset API name
data-user user
data-maxage maxage
data-list-size listSize

Our new code:

var msglist = document.getElementById("msglist");

var show = msglist.dataset.listSize;
msglist.dataset.listSize = +show+3;

The datalist API is supported by all modern browsers but not IE10 and below. A shim is available but it’s possibly more practical to use jQuery if you’re coding for the older browsers.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Etienne

    I already use the jquery .data with some script. But the data was not modified in the html, if I use both method, first a jquery .data to set the data, then a javascript getAttribute to read it, will it see my new data, or it will return blank?

    • Craig Buckler

      Hi. If you update a data value using jQuery’s data() method, it won’t change the attribute in the DOM. Therefore, a subsequent getAttribute or dataset API call will return the original value when the page was loaded.