Showing posts with label microformat. Show all posts
Showing posts with label microformat. Show all posts

Monday, February 8, 2016

A Question of Semantics

Aztec pyramidOver the past (nearly) 20 years, one of the webhead topics for which I have been an advocate is the creation of semantic code. In the beginning, it was "semantic markup" because markup was really all we had. A little while later we added stylesheets and several of us also began thinking in terms of semantic styles. Now we're seeing other features, such as animation, carry meaning and are beginning to think of them in "semantic" terms as well1. Each of these has been layered upon the other - a figurative Aztec pyramid. semantic and what does it mean to write semantically and why worry about whether or not our markup, or CSS, or any other level of code is semantic?

First, let's address what we mean by writing "semantic code".

Let's begin by saying that not all code is semantic. We spend significant time considering the content of a web site, a page, or an application and how it carries meaning, but the code that wraps the content can either carrying meaning or not. When I wrap content in a DIV or P tag, I know something more about the content than content that is simply terminated with a line break (BR tag). If I use HTML5 and wrap content in an ASIDE tag or ARTICLE tag, I know even more about the content than if I had wrapped them in a DIV or P tag.

As another example, if I wrap a number in a SUP tag the only thing I know about that number is how it should be displayed; however, if I wrap a number in a SPAN tag with a semantic class attribute - footnote, for example - I now know something more about that number. Similarly, when I add WAI-ARIA2 attributes, such as aria-describedby even aria-hidden I am describing the content even more fully3 just as surely if I use an EM or STRONG tag instead of an I or B tag.

To put it simply, semantic code includes not only content, but meta-communication about that content.

So, why worry about whether or not our markup, or CSS, or any other code is semantic? The simple answer is that the meta-communication in code is as important, and in similar ways, as tone and body language are in verbal communication. The importance of meta-communicating code is easily seen when assistive technologies, such as screen readers like JAWS or VoiceOver, are used. Simply consider the difference between a I (italics) tag and an EM (emphasis) tag or a B (bold) tag and a STRONG (strong emphasis) tag. One category is visually oriented, but the other is both visually and verbally oriented, leading to a not only richer, but more precise, experience...one with less cognitive load...and the lower the cognitive load, the better the user experience (which anyone who is "customer-focused" wants).

At this point you might be thinking "I see the importance of semantic markup and using ARIA semantics, but why bother with the rest". Consider this - what do you think your experience would be like if face-to-face communication were missing an element of meta-communication. Would you gather as much meaning? Would it be as complete? As a society, we generally don't think so, which is why we have all sorts of assistive technology intended to help us compensate for missing elements - each element is significant. This significance should be carried over into the coding world. I would posit that we ought to go so far as to say that when any element of the code does not qualify as semantic that the code as a whole is not semantic.

At this point we have only discussed general benefits of semantic code in relation to humans. I haven't even touched on the benefits of semantic code in relation to machines. By using semantic CSS, for example, browser plugins are able to interface more fully with other applications - like calendars - especially when the CSS is a microformat. This opens the door to creation of a number of symbiotic relationships between your code and existing applications, especially in mobile channels where we have merely scratched the surface.

Beyond what we typically think of as code, however, we must also make sure other features - like animation - are semantic (seriously, if you haven't read Motion with Meaning: Semantic Animation in Interface Design yet, go do it) or, at the very least, don't break our semantic model, just as we ought make certain those features in the user interface do not increase cognitive load. One of the methods people who design user interfaces have used for decades that helps maintain a semantic approach and also tends to reduce cognitive load is skeuomorphism4. One of the most common historic examples of this method is making a data input form mimic the paper version; however, there are numerous other examples - folder and file images for directories on a computer or an image of a envelope for mail or email are just two examples.

In a previous post I wrote about a different (credit/debit) card input form I had developed5. Although that post discussed, in more general terms, creating a form that validates a credit/debit card including determining the brand, it links to an input form that uses a minimalist style - and there are reasons to use a minimalist, semantic approach at times - and contains the JavaScript to perform the validation. One of the deficiencies in that prototype, however, is the lack of semantic animation (in the minimizing of the account number input). That deficiency is addressed in another prototype where I take a skeuomorphic approach and create a card input form that looks and behaves much like its real-world counterpart. Feel free to take a look at both prototypes and see which is a more complete, user-friendly experience. I'm confident you'll find the more complete the semantic approach, the better the experience. (Of course, a combination of the two - the technical validation of version 1 and the skeuomorphic design of version 2 - is probably closer to ideal.)

All the issues I've brought to the fore so far are focused on the customer (user) experience, as they should be. However, there are other sides to the use of a semantic approach - SEO advantages and your (hopefully) friendly interface engineer, for example. Although the SEO benefits of the use of semantic markup and styles are becoming less dramatic than they were in the past, they are still present, and that will likely not change. A document a machine can read and understand will always fare better than one that is less understandable. As for interface engineers - semantic code makes understanding what is likely to be a complex solution a little easier. Reducing the cognitive load for an interface engineer generally means more productivity and less frustration. More productivity and less frustration will generally result in better code, so getting into the practice of writing semantic code can become a self-reinforcing loop and make the world a better place. Best of all, it means more happy coding.

Reference Notes (please note that links open in a new window).
  1. Al Hazwani, Amin and Bernard, Tobias. Motion with Meaning: Semantic Animation in Interface Design. A List Apart. 19 January 2016. http://alistapart.com/article/motion-with-meaning-semantic-animation-in-interface-design (accessed 31 January 2016)
  2. The WAI-ARIA specification divides the accessibility semantics into roles, states, and properties. You can see that specification at https://www.w3.org/TR/wai-aria/usage.
  3. The WAI-ARIA semantics are very powerful, and getting their usage just right can be difficult, so if you're new to the whole "Accessible Rich Internet Applications" space, start with the W3C's ARIA Primer.
  4. Skeuomorphism is the practice of making virtual items - such as data input forms - resemble their real-world counterpart. (https://www.techopedia.com/definition/28955/skeuomorphism)
  5. King, Robert, 'A Better Credit Card', Getting Paid to Think [weblog]. 28 December 2012, http://gettingpaidtothink.blogspot.com/2013/02/a-better-credit-card.html.

Monday, November 10, 2014

A machine-readable resume

Anyone who's known me (professionally) for long knows that I've been a fan of microformats. Note 1 One of my early projects at PayPal was to write component code that used the hCard microformat Note 2 to mark up addresses. This little Easter egg Note 3would allow merchants with repeat customers to add contact information to their systems easily using any the vcard reader plug-ins.

You might be asking why I'm such a fan of microformats - and that's an easy question to answer. Our goal – as designers and developers – must be to make information more readable, Note 4 and more searchable, than it ever has been. A large part of the reason I'm a fan of microformats is the same reason I'm a huge fan of semantic HTML – it's more readable and understandable, not only by people, but by machines as well.

The next question may be "why is that important for resumes". Machines generally lack bias, and bias is a huge issue, especially in evaluation of resumes – you can read more about such bias on my post "What's in a name?" – which is why when friends went to work at LinkedIn, I put the words in their ear that they should use the hResume microformat. Note 5

A few short years ago, the hResume (and its related hCard format) were the only significant efforts in to create an HTML resume that would be a candidate for the Semantic Web. Time moves quickly on the Internet, however, and I should note that the hCard and hResume formats have been 'deprecated' in favor of the new formats – h-card and h-resume – and since Google, Bing, and Yahoo! joined together to create microdata schemas Note 6 you've (almost) had another way to mark up a resume. Granted, the microdata way takes more work because there isn't a format specifically for resumes, you have to cobble it together, but it's fairly easily done, and I'm going to tell you how while also describing how to mark up the data in both hResume and h-resume formats. This approach will give you a resume that's readable by nearly every bot crawling the web.

Getting Started

Note: before you go any further, it is important that you consider how much personal information you post on the web. You certainly need a name and some way for people to contact you, but more than that could put you at risk, and only you can evaluate the degree of risk. You ought also make a plan for re-evaluating that risk periodically.
First, let's think about a resume for a moment. Every resume is basically a combination of personal data and event data. You could think of it in other ways, but that doesn't really make sense. Every job you've ever had is an event organized by your employer, and every educational session you've attended is an event organized by the institution you attended. Once we've figured this out, it's relatively easy to put together a resume.

Now let's start with your code…we'll start with the contact information, which is typically where a resume begins. In order to be as complete as possible, I'm going to use all three formats – the two microformats: hResume and h-resume, and the microdata format, which we'll basically be creating. One small note here - there will be sections that I have marked up using tags that you may wish to replace with other tags; for example, a job description could easily be an ordered or unordered list rather than a paragraph, so feel free to use the tag that best describes the data you're presenting.

If you're using the h-resume format, you'll need to wrap all your information in a container with the class h-resume (same if you're using the hResume format), so feel free to use either a DIV tag or a SECTION tag as long as you use hResume and h-resume in the class attribute.

<section class="hResume h-resume">
  [your resume here]
</section>

You will not need this markup if your intention is to only use microdata, because there is no microdata schema for a resume or CV - this only applies to the hResume and h-resume formats. If schemas.org decides to create a resume schema, you could easily add the itemscope and itemtype attributes to this section.

Contact Information

The first section we're going to add to the resume is the contact information. It's typically the first section on any resume, so it's as good a place to start as any. For the microformats the sections will need to be identified and it's a good practice to identify the sections with some sort of header, so we're going to use the pattern where we have a header followed by identified content blocks. Since contact information is fairly simple as a h-card or Person object, I'll just go straight to the code where you'll notice I'm using a mixture of class attributes used by h-card (including contact, p-contact vcard and h-card) Note 7 and itemprop attributes (including name, addressLocality, and addressCountry). Note 8

One other note - I'm using a class name called "clipped" that hides content by using an absolute position and the CSS "clip" property (e.g. .clipped { clip:rect(0 0 0 0); clip:rect(0, 0, 0, 0); position:absolute; }). This approach makes content accessible in a way that setting the "display" property to "none" does not.

<section class="hResume h-resume">
  <section>
    <header>Contact</header>
    <div class="contact p-contact vcard h-card" itemscope="" itemtype="http://schema.org/Person">
    <p class="fn p-name" id="contact-p-name" itemprop="name">[your name]</p>
    <p class="adr p-adr" itemprop="address" itemscope="" itemtype="http://schema.org/PostalAddress">
      <span class="locality p-locality" itemprop="addressLocality">[locality]</span>
      <abbr class="region p-region" itemprop="addressRegion">[region]</abbr>
      <span class="postal-code p-postal-code" itemprop="postalCode">[postal code]</span>
      <abbr class="country-name p-country-name" itemprop="addressCountry">[country code]</abbr>
    </p>
    <p class="email">
      <span class="type clipped">[email type, e.g, "Work" or "Personal"]</span>
      <a class="value u-email" href="mailto:[email address]" itemprop="email">[email]</a>
    </p>
    </div>
  </section>
</section>

If you're wondering why I've included the country name, keep in mind that bots have a difficult time determining context. They could use a language code to guess about where you are, if you have it...but what about people who publish their resumes in a language or for a place other than where they're currently located - they'll want some way to identify where they're located that is not associated with the document language code. Also, note that I've added an ID attribute to the "name" element (identified by the "fn" or "p-name" class and the "name" itemprop) – that will be used later in the code as part of the h-resume format.

Summary or Objective

The next section you may want to include is the "summary" or objective. Why might you want to include a summary? It's basically the tl;dr section for your post. If you're using the hResume or h-resume format, use the class names "summary" and "p-summary", respectively. Something like the following should suffice.

<section>
  <header>Summary</header>
  <p class="summary p-summary">[your summary here]</p>
</section>

Note that this section is not available in the microdata version. An alternative to leaving it out completely is to add it within the Person schema after the email paragraph as a "description" (e.g., <p class="clipped" itemprop="description">[your summary here]</p>); however, doing so may result in information being duplicated by bots reading your resume.

Experience

Now we get to the complex portion - work experience - and I'll try to make it as simple as possible. First, the data needs to be wrapped in the "experience" class for the hResume and h-resume formats and since experience is really an ordered list of events, we're going to be semantic and use the OL tag and since they're events, we're going to add the vcalendar class. This means our experience items are wrapped inside code like this...

  <section>
    <header>Experience</header>
    <div class="experience p-experience">
    <ol class="vcalendar">
      [your experience here]
    </ol>
    </div>
  </section>

This means our work experience - each job - can be wrapped in an event, giving us code like this...

<li class="vevent vcard h-event h-card" itemscope itemtype="http://schema.org/Event">
  <a href="#contact-p-name" class="include"></a>
  <div itemprop="organizer" itemscope="" itemtype="http://schema.org/Organization">
    <p class="org p-org" itemprop="name">[your employer]</p>
    <p class="location p-location" itemprop="address" itemscope="" itemtype="http://schema.org/PostalAddress">
      <span class="adr p-adr">
        <span class="locality p-locality" itemprop="addressLocality">[employer locality]</span>
        <abbr class="region p-region" itemprop="addressRegion" title="[region]">[employer region]</abbr>
      </span>
    </p>
  </div>
  <p class="summary p-summary title p-job-title" itemprop="name">[job title]</p>
  <abbr class="dtstart dt-start" content="[start year]-[start month]" itemprop="startDate" title="[starting date]">[starting date]</abbr> - <abbr class="dtend dt-end" content="[end year]-[end month]" itemprop="endDate" title="[ending date]">[ending date]</abbr>
  <div class="description p-description">
    <p itemprop="description">[job description]</p>
  </div>
</li>

There are a few additional things you'll want to know about this section. First, the readers will strip HTML tags out of properties, so don't worry about any markup you have inside the specified properties; however, they do not alter white space - e.g., line breaks, tabs, and spaces - so keep it to a minimum. Second, there are a couple things to note about the dates - the first is that the content and title values are ISO 8601 format and the second is that the starting date is always required for an event but an ending date is not, which means I can easily use a date range like <abbr class="dtstart dt-start" content="2009-03" itemprop="startDate" title="2015-07-01">July 2014</abbr> - <span class="date-name">Present</span> for a current position. Third, you'll notice the very first element within the event is an anchor tag that uses the ID attribute we created in the contact information as its href with the class attibute "include" – this is how we're using "p-name" data we identified earlier.

If I had a second job with the same employer, common practice is to not list the employer information a second time, but we want to make sure our information is as accurate and complete as possible, so we include it and just use the "clipped" class to hide it, like so.

<li class="vevent vcard h-event h-card" itemscope itemtype="http://schema.org/Event">
  <a href="#contact-p-name" class="include"></a>
  <div class="clipped" itemprop="organizer" itemscope="" itemtype="http://schema.org/Organization">
    <p class="org p-org" itemprop="name">[your employer]</p>
    <p class="location p-location" itemprop="address" itemscope="" itemtype="http://schema.org/PostalAddress">
      <span class="adr p-adr">
        <span class="locality p-locality" itemprop="addressLocality">[employer locality]</span>
        <abbr class="region p-region" itemprop="addressRegion" title="[region]">[employer region]</abbr>
      </span>
    </p>
  </div>
  <p class="summary p-summary title p-job-title" itemprop="name">[job title]</p>
  <abbr class="dtstart dt-start" content="[start year]-[start month]" itemprop="startDate" title="[starting date]">[starting date]</abbr> - <abbr class="dtend dt-end" content="[end year]-[end month]" itemprop="endDate" title="[ending date]">[ending date]</abbr>
  <div class="description p-description">
    <p itemprop="description">[job description]</p>
  </div>
</li>

Education

The next section is typically education. Again, we're going to use the event model to describe this portion of your career. Like the experience section, it needs to be wrapped in section description and is an ordered list, so...

<section>
  <header>Education</header>
  <div class="education p-education">
    <ol class="vcalendar">
      [your education events here]
    </ol>
  </div>
</section>

The name or description should contain a short description of the event. If you're listing a single course, it would be the course name, but if you're listing all the courses leading up to matriculation, list the degree or certificate you earned, like so.
<li class="vevent h-event" itemscope="" itemtype="http://schema.org/Event">
  <div class="summary p-summary vcard h-card" itemprop="organizer" itemscope="" itemtype="http://schema.org/Organization">
    <a class="url fn p-name org p-org" href="http://www.millikin.edu/" itemprop="name">[institution]</a>
    <p class="adr p-adr" itemprop="address" itemscope="" itemtype="http://schema.org/PostalAddress">
      <span class="locality p-locality" itemprop="addressLocality">[locality]</span>
      <abbr class="region p-region" itemprop="addressRegion" title="[region]">[region]</abbr>
    </p>
  </div>
  <abbr class="dtstart dt-start" content="[start year]-[start month]" itemprop="startDate" title="[starting date]">[starting date]</abbr> - <abbr class="dtend dt-end" content="[end year]-[end month]" itemprop="endDate" title="[ending date]">[ending date]</abbr>
  <p class="description p-description" itemprop="name">[degree, program of study, or course name]</p>
</li>

As with the section containing work experience, the bots will strip HTML tags out of properties and leave white space, the dates use ISO 8601 format in the content attribute, and the starting date is required but an ending date is not. Unlike the work experience, we are not including an anchor tag that uses the ID attribute we created in the contact information as its href with the class attibute "include" as the first element – the h-card entry is that of the institution instead.

Skills

The final section I'll cover in detail is the section listing your skills. This section does not use microdata because there isn't currently a schema for skills, with the exception of as a property of the JobPosting schema. There are other sections typically included in a CV, and one of those sections Note 9 is included in the hResume and h-resume formats, but those are not discussed in any detail here.

Because information about skills is typically something for which people generally request additional information, I recommend that you use a table as markup. Use the class name "skills" for the table, this will identify the section, and use the class names "skill" (for hResume) and "p-skill" for h-resume to identify individual skills. I recommend that you add columns to your table to identify when you last used the skill or what your competency level is - the latter is especially use for language skills. This approach would give us something like the following.

<section>
  <header>Skills</header>
  <table class="skills">
    <thead>
      <tr><th>Skill</th><th>Last Used</th></tr>
    </thead>
    <tbody>
      <tr><td class="skill p-skill">AJAX/XmlHttpRequest</td><td>2014</td></tr>
      <tr><td class="skill p-skill">bootstrap</td><td>2014</td></tr>
      <tr><td class="skill p-skill">CSS/CSS3</td><td>2014</td></tr>
      <tr><td class="skill p-skill">cssless</td><td>2014</td></tr>
      <tr><td class="skill p-skill">D3js</td><td>2014</td></tr>
      <tr><td class="skill p-skill">dustjs</td><td>2014</td></tr>
      <tr><td class="skill p-skill">git</td><td>2014</td></tr>
      <tr><td class="skill p-skill">HTML/HTML5</td><td>2014</td></tr>
      <tr><td class="skill p-skill">Java</td><td>2014</td></tr>
      <tr><td class="skill p-skill">JavaScript</td><td>2014</td></tr>
      <tr><td class="skill p-skill">jQuery</td><td>2014</td></tr>
      <tr><td class="skill p-skill">JSON</td><td>2014</td></tr>
      <tr><td class="skill p-skill">nodejs</td><td>2014</td></tr>
      <tr><td class="skill p-skill">Perl</td><td>2014</td></tr>
      <tr><td class="skill p-skill">Splunk</td><td>2014</td></tr>
      <tr><td class="skill p-skill">SVN</td><td>2014</td></tr>
      <tr><td class="skill p-skill">XML-Schema</td><td>2014</td></tr>
      <tr><td class="skill p-skill">XML</td><td>2014</td></tr>
      <tr><td class="skill p-skill">XPath</td><td>2014</td></tr>
      <tr><td class="skill p-skill">YUI</td><td>2014</td></tr>
    </tbody>
  </table>
</section>

Other Sections

Because other sections typically found in a resume – e.g., "publications", "presentations", or "honors and awards" – are events, you may wish to mark them up as microdata or h-event to include them; however, they are not recognized by either resume format at this time.

Progressive Enhancement – Printing and Sorting Data

One final suggestion - by creating not only a browser stylesheet but a print stylesheet as well, you can easily make one resource fit two purposes, and that is easily done using the "@media print" query. Use of the "print" stylesheet enables you to control page breaks and typography for print versions of your resume, as well as giving you the ability to hide elements in the page that might detract from your resume.

You can also extend the functionality embedded in the browser version of your resume using JavaScript to make your resume dynamic. For example, you may wish to use the cjl-scrollabletable.js library to make your skills (or affiliations) table take up less real-estate and also allow the user to sort the data by the different columns.

If you'd like to see how all this works together, feel free to look at a full resume marked up at http://www.cathmhaol.com/resume.htm as an example.

Notes and references

Links in the notes and references list open in a new window
  1. A simple way to express meaning on the web in HTML without further complex XML alternatives.
  2. A simple, open format for publishing information about people and organizations using a 1:1 representation of the VCARD (RFC 2426) properties and values in HTML.
  3. An intentional hidden feature or message in a work such as a computer program, video game, movie, book, or crossword.
  4. This concept is the Semantic Web that Tim Berners-Lee has pushed for a number of years, even basing a TED talk around it.
  5. The hResume microformat, and its successor – h-resume – is a microformat for publishing resumes and CVs.
  6. Microdata schemas are methods used to markup HTML pages in ways recognized by major search providers, and that can also be used for structured data interoperability
  7. The specific elements used with the h-resume format, and some simple examples, can be found at http://microformats.org/wiki/h-resume. The h-card format, used to mark up contact information, can be found at http://microformats.org/wiki/h-card.
  8. The specific elements used in marking up contact information using microdata can be found at http://schema.org/Person and http://schema.org/PostalAddress.
  9. A section listing "affiliations" is recognized by both the hResume and h-resume formats; however, since there is not a microdata resume format, affiliations are contained by the Person schema. As with the "summary" section, you may wish to list affiliations with the Person information; however that may result in duplicate information.