Marking up contact information semantically using HTML5 & microformats
Posted: May 3rd, 2010 | Author: Rachael L. Moore | Filed under: Microformats | Tags: Accessibility, Best Practices, Front End Web Development, HTML5, Microformats, Search Engine Optimization (SEO), Semantic Markup | No Comments »itemprop attribute to add semantic meaning and “microdata” to HTML5 documents, inspiring me to update and post a little ongoing project of mine.The good thing about the microdata (itemscope, itemtype, itemprop, etc.) part of the HTML5 spec is that it is part of the HTML5 spec; it’s built into HTML5. That really is a good thing. On the other hand, it’s potentially yet another competitor in the semantic lineup and it’s a newcomer in a spec that’s not entirely finalized.
Its integration with HTML5 (and, who knows, its design) may make it a better way to add semantic meaning to our HTML documents than microformats, but I personally won’t commit to that one way or another until I’ve attempted to use it in a variety of real-world situations. I won’t make any comparisons to RDFa (which it’s not entirely incompatible with according to this source who knows far more than me about it) or comments about namespaces…for my own safety. Yes, I have an opinion, and, no, it’s not entirely favorable toward HTML5. But forget that. This post isn’t about the theoretical rigor of this HTML5 feature — just about how to use it alongside other semantic options, like the hCard microformat, to add semantic meaning that is machine readable.
Note that my understanding of HTML5 microdata (henceforth referred to as “item” stuff) suggests that it is not meant only or necessarily to be a “microformat killer” or to replace RDFa, but one of its possible applications certainly is duplicating some of the “functionality”* of stuff like hCard or FOAF.
Some good news is that Google is already starting to support “item” parsing (and I’m sure others will follow), but it’s important to remember that both the microformats.org formats and RDFa have been around for several years and therefore have already established themselves in many implementations across the web.
I say this to point out that the surge of articles which will surely be written about about HTML5′s “items” don’t mean that it’s time to throw out microformats/RDFa (for a variety of reason I’m sure others will point out). One purely pragmatic reason is breadth and depth of support — it’s too early to chuck out microformats that already have support in favor of HTML5 “items.” Unfortunately, that means writing redundant code.
Below is an example of a “profile” I’ve been working on as a basic structure for contact information/profiles. It already used HTML5 tags and microformats and was awaiting some RDFa. When a coworker sent me the Dive into HTML5 article I spent some time at lunch adding HTML5 microdata and tested it in Google’s Rich Snippets Testing Tool.
I won’t go into exhaustive detail about every line. The sites I linked above give good introductions to the details. I’ll just draw your attention to a few things I think are worth noting.
Semantic person in HTML5
I started with the new HTML5 figure tag. It designates a section of a document that contains multimedia with a caption. figure seems like a good fit to me because…
- Most profiles tend to show a picture of a person which is captioned with the name of the person. The two are related in a way that figure alone communicates.
- Often profiles are embedded in ways that make the profile an independent part of the page that is supplementary to the page content.
So, figure jumped out at me for the reason it seems to fit semantically and for the reason it “feels” modular.
<figure class="vcard" id="vcard-lastfirst-idnum123"
itemscope="itemscope" itemtype="http://www.data-vocabulary.org/Person/"
title="Firstname Lastname">
- To “activate” hCard I’ve added
class="vcard", - And to add HTML5′s “item” functionality/microdata I’ve added
itemscopeanditemtype. - I’ve used the definitions in Google’s Data Vocabulary which is integrated into their Rich Snippets and can be written as a microformat, an HTML5 item, or RDFa.
- I’ve added an id to remind myself to give the card a unique ID so that it can be easily referenced using the microformat include.
- I’ve used a
titleattribute because I’ve noted it sometimes appears in accessibility plugins. I don’t want to be redundant, but some software has seemed to ignore headers (not in reading it, but in labeling navigation) even with WA-ARIA (which I haven’t included in this sample anyway), sotitleis in.
Organization within Person
When you’re giving a person’s organization and title, that organization is another entity itself that you may want to give additional information about. All of the places I’ve tested so far support nested vcards, and Google’s Rich Snippet Tester appeared to do well with nested items.
...
<span class="org" itemprop="affiliation" title="Organization"
itemscope="itemscope" itemtype="http://www.data-vocabulary.org/Organization/">
<div class="vcard">
<span class="organization-name fn" itemprop="name">Organization Name</span>
<div class="adr" itemprop="address"
itemscope="itemscope" itemtype="http://data-vocabulary.org/Address/">
<!-- Address --><span class="street-address" itemprop="street-address">6601 N Monroe</span>
<!-- City --><span class="locality" itemprop="locality">Tallahassee</span>,
<!-- State --><abbr class="region" itemprop="region" title="Florida">FL</abbr>
<!-- Zip --><abbr class="postal-code" itemprop="postal-code" title="32303-9329">32303</abbr>
<!-- Country --><abbr class="country-name" itemprop="country-name" title="United States">USA</abbr>
<!-- Lat/Lon (Metadata) -->
<span class="geo" itemprop="geo"
itemscope="itemscope" itemtype="http://data-vocabulary.org/Geo/">
<abbr class="latitude" itemprop="latitude" title="60.6060606060">60.6060606060</abbr>
<abbr class="longitude" itemprop="longitude" title="-60.6060606060">-60.6060606060</abbr>
</span>
</div> <!--/ .adr -->
</div> <!--/ .vcard -->
<span class="organization-unit">Unit</span>
<span class="title" itemprop="title">Job Title</span>
</span> <!--/ .org -->
...
That’s a geo location nested within an address nested within an organization nested within a person. You start with the person and mention the organization as a name, then include the separate vcard for the organization. The organization has its own address and that address has its own geo code.
Telephone & E-mail
Google’s data vocabulary doesn’t specify telephone numbers for a person, only for organizations. It also lacks any reference to e-mail addresses anywhere. Since my test case is primarily for a person and the hCard microformat doesn’t have that problem I’ve used the pattern that works for hCard and incorrectly bolted Google’s data vocabulary on with HTML5′s microdata/item properties. It’s wrong for Google’s data vocabulary. I did it, but I’m thinking it’s probably best to leave it out and let the hCard microformat handle that part**.
Contact Info/Profile with HTML5, microdata, and microformats
<!--- Photo with Caption --->
<figure class="vcard" id="vcard-lastfirst-idnum123"
itemscope="itemscope" itemtype="http://www.data-vocabulary.org/Person/"
title="Firstname Lastname">
<!-- Photo -->
<img src="#" width="180" height="240" alt="" class="photo" itemprop="photo" />
<!-- alt redundant; image labeled by context, leave empty (webaim) -->
<!-- Caption -->
<figcaption>
<!-- Profile -->
<section class="profile">
<!-- Name -->
<header class="n" title="Name">
<span class="fn" itemprop="name">
<span class="given-name">Firstname</span>
<span class="additional-name">Middlename</span>
<span class="family-name">Lastname</span>
</span> <!--/ .fn -->
<span class="nickname" itemprop="nickname">Nickname</span>
</header> <!--/ .n -->
<!-- Organization -->
<span class="org" itemprop="affiliation" title="Organization"
itemscope="itemscope" itemtype="http://www.data-vocabulary.org/Organization/">
<div class="vcard">
<span class="organization-name fn" itemprop="name">Organization Name</span>
<div class="adr" itemprop="address"
itemscope="itemscope" itemtype="http://data-vocabulary.org/Address/">
<!-- Address --><span class="street-address" itemprop="street-address">6601 N Monroe</span>
<!-- City --><span class="locality" itemprop="locality">Tallahassee</span>,
<!-- State --><abbr class="region" itemprop="region" title="Florida">FL</abbr>
<!-- Zip --><abbr class="postal-code" itemprop="postal-code" title="32303-9329">32303</abbr>
<!-- Country --><abbr class="country-name" itemprop="country-name" title="United States">USA</abbr>
<!-- Lat/Lon (Metadata) -->
<span class="geo" itemprop="geo"
itemscope="itemscope" itemtype="http://data-vocabulary.org/Geo/">
<abbr class="latitude" itemprop="latitude" title="60.6060606060">60.6060606060</abbr>
<abbr class="longitude" itemprop="longitude" title="-60.6060606060">-60.6060606060</abbr>
</span>
</div> <!--/ .adr -->
</div> <!--/ .vcard -->
<span class="organization-unit">Unit</span>
<span class="title" itemprop="title">Job Title</span>
</span> <!--/ .org -->
<!-- Location -->
<address class="adr" itemprop="address" title="Location"
itemscope="itemscope" itemtype="http://data-vocabulary.org/Address/">
<!-- Address --><span class="street-address" itemprop="street-address">1532 Chadwick way</span>
<!-- City --><span class="locality" itemprop="locality">Tallahassee</span>,
<!-- State --><abbr class="region" itemprop="region" title="Florida">FL</abbr>
<!-- Zip --><abbr class="postal-code" itemprop="postal-code" title="32303-9329">32312</abbr>
<!-- Country --><abbr class="country-name" itemprop="country-name" title="United States">USA</abbr>
<!-- Lat/Lon (Metadata) -->
<span class="geo" itemprop="geo"
itemscope="itemscope" itemtype="http://data-vocabulary.org/Geo/">
<abbr class="latitude" itemprop="latitude" title="30.3030303030">30.3030303030</abbr>
<abbr class="longitude" itemprop="longitude" title="-30.3030303030">-30.30303030</abbr>
</span>
</address> <!--/ .adr -->
<!-- Contact -->
<a href="mailto:email" class="email">test@example.org</a>
<div class="tel"
itemscope="itemscope" itemtype="http://www.data-vocabulary.org/Organization/">
<abbr class="type" title="home pref">Home:</abbr> <abbr class="value" itemprop="tel" title="+1##########">(###) ###-####</abbr>
<abbr class="type" title="work">Office:</abbr> <abbr class="value" itemprop="tel" title="+1##########">(###) ###-####</abbr>
<abbr class="type" title="mobile">Cell:</abbr> <abbr class="value" itemprop="tel" title="+1##########">(###) ###-####</abbr>
<abbr class="type" title="fax">Fax:</abbr> <abbr class="value" itemprop="tel" title="+1##########">(###) ###-####</abbr>
</div>
</section> <!--/ .profile -->
<!-- Links -->
<section class="note">
<ul>
<li><a href="http://www.example.org/" class="url" itemprop="url" rel="me self external">example.org</a></li>
<li><a href="http://www.example.org/" class="url" itemprop="url" rel="me self external">example.org</a></li>
<li><a href="http://www.example.org/" class="url" itemprop="url" rel="me self external">example.org</a></li>
<li><a href="http://www.example.org/" class="url" itemprop="url" rel="me self external">example.org</a></li>
<li><a href="http://www.example.org/" class="url" itemprop="url" rel="me self external">example.org</a></li>
<li><a href="http://www.example.org/" class="url" itemprop="url" rel="me self external">example.org</a></li>
<li><a href="http://www.example.org/" class="url" itemprop="url" rel="me self external">example.org</a></li>
</ul>
</section>
</figcaption> <!--/ .figcaption -->
</figure> <!--/ .figure.vcard -->
Download the current version of Microformats in Profiles & Contact Information here. You can also see the use of HTML5 microdata + Google’s Review Data Vocabulary + hReview in there along with a few other things. It’s still under development so I recommend you use the link to ensure you are looking at the most recent code.

Leave a Reply