HTML5 formalizes the ability to store data directly in the page element. The data is simple to add, and just as simple to access.
Custom data attributes give us the ability to add more richness and depth to our markup than we’ve ever been able to before. Custom data attributes, often called the data-*
attributes, are an easy way to add contextual data to HTML5 markup. Just come up with an attribute name, prefix it with “data-”, and add it to any HTML markup tag:
In the preceding example, we have information we want to present to the user that we include as text inside the tag. We also have contextual information that our app will want to use to provide additional functionality to the user. Before HTML5, this additional data would have been stored in one of two ways. Either we would have hacked up another attribute (such as the class
attribute or the id
) with a string that encoded all this information, or we would have kept a separate data source in JavaScript that had a reference to this tag linked to it. Neither of these options is very fun, and both require quite a few lines of JavaScript to become useful.
Being able to place this data in the element itself not only is convenient for access purposes, but also provides rich context. According to the HTML5 spec from the W3C, a custom data attribute is defined as the following:
A custom data attribute is an attribute in no namespace whose name starts with the string “data-”, has at least one character after the hyphen, is XML-compatible, and contains no characters in the range U+0041 to U+005A (LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z).[3]
In summary, it’s an attribute that starts with “data-” and is in all lowercase letters. Now, let’s be clear about the purpose of this data. We’ll start with how we don’t want to use it (let’s get all that negative stuff out of the way!).
First, the data attribute shouldn’t be used to replace an existing HTML attribute such as class name id
. For example, if you want to add a unique identifier to an element of which there will only be one on the page, just use the id
, because that is exactly what it is designed for. Having a data-id
on all your elements will probably get you a healthy number of complaints from your friends and coworkers. Second, don’t use the data element to make your code more “machine-readable.” This is what microformatting is for, which we will discuss in depth in a few hacks. Your custom data attribute is intended to provide information that is relevant for your application, not for an external page reader (whether it is human or machine).
Now, on to the fun part! How should you use custom data attributes? Simply put, you should use them for “anything you need,” with emphasis on the words anything and you. Anytime you need access to data about a DOM element or to data related to the information that element represents, store it in the custom data attribute.
In the following example we have a table that was built out dynamically in JavaScript from a database. The database has a local key that identifies each row of data, but that key only means something to our application; it doesn’t have any value to the user. Before custom data attributes, we had to do something like this:
Then we had to use CSS to hide the first row (with a class name of key
):
Another really bad solution involved using one of the existing attributes to store this data. In the following example the data is stored in the id
attribute:
There are so many problems with this solution that it’s hard to know where to start. First, it’s a horrible idea to store data in the id
attribute. The id
attribute is meant to be a unique identifier for HTML elements. Since it’s associated with our database key, the key will change when the data changes, making it impossible to use that id
to reference the element, as it’s subject to change. Storing the key as a class name is equally bad, for similar reasons.
Now let’s turn it around and put that essential data into a custom data attribute:
Here we have simple markup that contains a reference to our database key, without unnecessary markup or prostitution of the id
or class
attribute. We didn’t even have to write any CSS to make this work.
Accessing the Data
Another important piece of the puzzle concerns accessing the data. The W3C HTML5 spec has a clear method for collecting data in JavaScript. A dataset
object is available on the HTML5 element that allows you to access your custom values by name:
Notice that we don’t need the “data-” in front of our value; we just call our value name directly. This access method is great and meets the spec, but like many of our HTML5 features, it only works in HTML5 browsers. Interestingly enough, putting a custom data attribute of sort
onto an element has worked in browsers for some time (it may not have validated, but it worked), all the way back to IE 6. However, note that the JavaScript access method is introduced with the HTML5 spec, but don’t fret—we have a hack for that:
Before, HTML5 browsers simply recognized the value as an attribute of the element, so a simple getAttribute
method of the element would retrieve the data. Note that in this method, the “data-” part of the value is required to retrieve the data.
There is one more way to access this data, but it comes with a warning. Most current browsers support a CSS3 pseudoproperty (see Chapter 3 for more about pseudoclasses) on which you can base a style declaration. It looks something like this:
or this:
Now your CSS can style the element based on the presence of the custom data attribute, or by the value of the custom data. Here’s your warning: don’t use custom data in place of CSS classes. Class names are still the definitive way to declare reusable style rules. Remember, custom data is not intended to represent something to the user, but rather to provide context data for your application, which means that, in general, you don’t want to use the previously demonstrated pseudoclasses.
0 Comments: