/* <![CDATA[ */ var monsterinsights_frontend = {"js_events_tracking":"true","download_extensions":"doc,pdf,ppt,zip,xls,docx,pptx,xlsx","inbound_paths":"[]","home_url":"https:\/\/marcofolio.net","hash_tracking":"false","ua":"UA-2742311-1","v4_id":""};/* ]]> */

HTML5 data-* attributes are great and you know it

Like I said in my previous article, all information about HTML5 is way too big to put into one blog article. We first looked at what HTML5 microdata can do for us, and today we’ll dive into another feature W3C added to their HTML specification. It’s called custom data attributes (by developers mostly referenced as data-* attributes), and I’ll explain what it is and what problems it fixes for us.

The data-* attributes are extremely useful, especially for JavaScript developers. W3C describes the use of these kind of attributes as: Embedding custom non visible data to your HTML. But why would you need it? Let’s take a dive into this new HTML specification. Although this article has a strong focus on jQuery, I assume you understand it counts for any other library and (of course) JavaScript itself.

Uses of technologies

Chris Coyier created this useful overview for the correct use of the several webdesign technologies:

Web Technologies

Now let’s focus on two techniques Chris points out here: HTML and JavaScript. Keep their appropriate use in mind, since it’s very important to know the difference.

JavaScript plugins

JavaScript plugins are great. jQuery has loads of official jQuery plugins which extend the capabilities of the framework just that little bit further (I wrote some plugins for jQuery too). Since you want the plugin to be used by loads of people, you make it easy to use and as flexible as possible.

Although jQuery allows options to be used to change the behaviour of the plugin, sometimes you need to put data inside the HTML for it to make it work. For example, take a look at this piece of code:

HTML


<img class="pic-0" />
<img class="pic-1" />
<img class="pic-2" />


for(var i = 0; i < $("img").length; i++) {
   $(".pic-" + i).doStuff(); // Do something   
}

JavaScript

I know this isn’t the best example I came up with, but that isn’t the goal of this article. The plugin loops through all the elements starting with the pic- class and does something with them (for example: Arrange them according to their index). But why it this o-so-very-wrong?

The main problem here, is the mis-use of the class attribute; That should mainly be used as a reference for CSS. And the use of prefixes (in this case: pic-) is just extremely dirty. But let’s take a look at another example for creating tooltips:

HTML


<p>
   This is the actual text
   <span>This is the tooltip</span>
</p>


$("p span").hide();
$("p").hover(function() {
   $("span", this).show();
});

JavaScript

So here we "hide" the information stored in the tooltip inside a span-element (hiding could be done with CSS too). When we hover the paragraph, the tooltip will show it’s contents. But what’s wrong with this solution?

Once again, we mis-use something here. This time, it’s the span-element that is out of place. We manually need to hide it and it doesn’t "feel" right at that place. But how should we tackle these kind of problems, the right way?

The jQuery solution

For these kind of problems, jQuery already has a pretty nifty solution. Since we don’t want our HTML-elements or attributes to be mis-used, we can dynamically add data to the DOM using the .data() API. This allows jQuery developers to add the data they want to the HTML elements, without abusing the HTML itself. Let’s take a look at how the two previous examples could be re-written using the .data() API.

HTML


<img />
<img />
<img />


var i = 0;
$("img").each(function(){
   $(this).data("iterator", i); // Store data
   i++;
});

$("img").hover(function(){
   alert($(this).data("iterator")); // Retrieve data
});

JavaScript

Did you see that? We don’t have any dirty class attribute mis-use anymore, since we can simply iterate over the HTML element and add the index dynamically (I know the index() method would be better in this case, but just for the sake of the example, I kept it simple). Looks like a very good solution for our problem we had before!

But now for the tricky part: How would you re-write the tooltip example to use the data() API? You don’t want to store the tooltip text inside the JavaScript file. If you do this, it would mean that you would update the JS file each time you want to add a new tooltip. Also, you would store your content inside JavaScript instead of the place where it belongs: The HTML. So, how should we fix this problem?

Bring in the data-*

The custom data attributes give us a very clean solution for this problem. We can now store any data and add it to the HTML as an attribute, as long as it starts with data-. Let’s take a look at how we could have re-written the two previous examples, but now using the custom data attributes.


<img data-index="0" />
<img data-index="1" />
<img data-index="2" />

<p data-tooltip="This is the tooltip">
   This is the actual text
</p>

HTML

I know the first example looks very silly, but I’ll come to that later. The second one, on the other hand, is pretty cool! We now have the appropriate place to store that kind of information. Another upside, is that it’s hidden by default and we can easily retrieve it using JavaScript to display the tooltip. When using jQuery, you could simply retrieve the value using the .attr() method, like this:

JavaScript


   var index = $("img").attr("data-index");
   var tooltip = $("p").attr("data-tooltip");

Take note the .customdata() plugin is a lot more flexible for custom data attributes.

But now back to the images. Although the data-index isn’t that useful, we can make a lot more use of the custom data attributes. Another advantage is that we are not limited to one data attribute! We can add as many as you want, as long as they all have a unique name. Check out the following HTML:


<img alt="My alt text"
   data-longdescr="My long description"
   data-geo="Location I took the picture"
   data-cam="The type of camera I used"
   data-time="The time I took the picture" />

HTML

Did you see that? I’m suddenly capable of adding loads and loads of more data to one single image. Imagine how you would write this when you couldn’t use the custom data attributes? Logically, it probably wouldn’t make as much sense as above. Now you can use these attributes to display them using JavaScript. This is the kind of power you get when using custom data attributes.

Conclusion

In my opinion, the data-* attributes is one of the coolest and (for the developers) most useful features there is. We’re now able to store data inside the HTML without any dirty hacks, or storing it in the JavaScript. Although it has some limitations (for example: You can only place text inside the attributes, and not more HTML elements), I think it’s a pretty nice solution for the problems described above.

What do you think? Have you ever encountered a problem like described above? If so, do you like the data-* attributes solution proposed in HTML5? Feel free to share!

Further reading

Leave a reply:

Your email address will not be published.

Site Footer