How Does HTML Microdata Help With Accessibility?
I've been studying HTML from an accessibility blog written by a blind developer. I was curious how they structured their markup and wanted to see if there were any extra bits that made it even more accessible.
The markup from this particular blog seemed to go above and beyond what I'd call basic semantic structure; article
, header
, logically ordered headings, etc. It also featured some attributes I've recognized from before (item-something
?) but I never took the time to learn about: Microdata.
What is Microdata?
Microdata, as described from schema.org and/or the Microdata spec, are attributes to help browsers build out a machine-readable data structure for browsers to consume. It can be thought of as key:value
pairs much like a JSON object.
After reading the spec and reviewing some examples, there seems to be three main attributes to be aware of:
- Anything with the
itemscope
boolean attribute is the item, or "thing" of data you're defining. It's more or less a container or "starting point" of data. - An item needs the
itemtype
attribute with a specific URL value to further describe the vocabulary or "category" of the thing. In other words, what is acceptable as child items of data. - One last attribute to include in the definition of an item is
itemprop
. This is the property name of the data node we're currently defining.
Here's the kicker:
Microdata helps to locate and arrange content for browser Reader Mode.
What is Reader Mode?
Reader Mode is a browser feature that makes it easier for someone to focus on content by:
- hiding non-essential page elements like navigation, sidebars, footers, and ads
- changing the page's text size, contrast and layout for better readability
- removing distracting animations
This helps with creating a more accessible experience for people with cognitive impairments or learning disabilities, such as Dyslexia, as it strips away everything that's unnecessary on the page.
Adding Microdata to a blog post template
Let's write some HTML for a blog post template and add in the Microdata attributes which help in creating a better Reader Mode experience.
1. Article container
For the article
container element, let's add couple attributes as described above.
<article itemscope itemtype="http://schema.org/BlogPosting">
<!-- … -->
</article>
Adding the itemscope
and itemtype
attributes will create the initial data structure for the browser to consume. Settings its type as "BlogPosting" will allow for a specific set of children data to be added.
2. Header and meta content
Next we'll add the header
element along with the blog post meta data. This will include information such as the title, byline, date published, and author. Since this is a full blog post landing page, we'll use an h1
for its title text.
<article itemscope itemtype="http://schema.org/BlogPosting">
<header>
<h1 itemprop="headline">My Blog Post Title</h1>
<p itemprop="description">A little extra on what this post is about</p>
<ul>
<li>
Written by
<span itemprop="author" itemscope itemtype="http://schema.org/Person">
<span itemprop="name">Scott</span>
</span>
</li>
<li>
<time datetime="2020-01-09" itemprop="dateCreated pubdate datePublished">
January 9th, 2020
</time>
</li>
</ul>
</header>
<!-- … -->
</article>
There's a lot of content here, so let's break it down.
- The
h1
element received theitemprop="headline"
attribute, declaring this as the post title. - The byline content container has the
itemprop="description"
attribute, which declares this content as the post description. -
Author data requires its own data type of "Person". Since we need to declare a new
itemtype
attribute, we also includeitemscope
to begin a new node for the data structure. This data needs to be set in its own HTML element, wrapping the related content. Sincespan
is an inline element and features no semantic meaning, this is a safe element to use.The author's name is then wrapped with another
span
with itsitemprop
attribute set toname
. -
Lastly, the date of the blog post uses the semantic
date
element which features theitemprop="dateCreated pubdate datePublished"
attribute to set the date of the post.
3. Content body
The last pieces to add are the (optional) post image and content body.
<article itemscope itemtype="http://schema.org/BlogPosting">
<header>
<!-- … -->
</header>
<img src="article-image.jpg" alt="" itemprop="image" />
<div itemprop="articleBody">
<p>
Lorem ipsum dolor sit ame, consectetur adipiscing elit. Donec a quam rhoncus, tincidunt ipsum non, ultricies augue…
</p>
<!-- … -->
</div>
</article>
With the itemprop="articleBody"
attribute applied to the wrapper div
element, our data structure knows this is the primary text content of the post.
The itemprop="image"
applied to the img
element sets this as the main post image.
Altogether now!
Here's the final HTML snippet with all the Microdata attributes added:
<article itemscope itemtype="http://schema.org/BlogPosting">
<header>
<h1 itemprop="headline">My Blog Post Title</h1>
<p itemprop="description">A little extra on what this post is about</p>
<ul>
<li>
Written by
<span itemprop="author" itemscope itemtype="http://schema.org/Person">
<span itemprop="name">Scott</span>
</span>
</li>
<li>
<time datetime="2020-01-09" itemprop="dateCreated pubdate datePublished">
January 9th, 2020
</time>
</li>
</ul>
</header>
<img src="article-image.jpg" alt="" itemprop="image" />
<div itemprop="articleBody">
<p>
Lorem ipsum dolor sit ame, consectetur adipiscing elit. Donec a quam rhoncus, tincidunt ipsum non, ultricies augue…
</p>
<!-- … -->
</div>
</article>
Try it out in my Microdata example CodePen.
Test Microdata implementation
If you're adding Microdata attributes to your templates, check out Google's Structured Data Testing Tool. You can add a URL or source code directly and the tool will report errors and warnings to your structure.
In testing the above HTML snippet, this tool reported some missing data which was required for the BlogPosting type. Here's what I added to satisfy these errors:
<div itemscope itemprop="publisher" itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Company Name">
<span itemprop="logo" itemscope itemtype="http://schema.org/ImageObject">
<meta itemprop="url" content="logo.jpg">
</span>
</div>
Since this content is only for data structure we can use the HTML meta
element. This remains as valid HTML as long as only the itemprop
and content
attributes are included.
You could accomplish the same thing by setting CSS display: none
on a wrapper span
element, but this has negative side effects when it comes to SEO and other data structure related issues.
Reader Mode comparison
Here's why I feel these extra attributes are worth adding. Review these before and after images from Safari Reader Mode:
Before
After
Here are the main differences with Microdata applied:
- Byline is moved up directly below the title with slightly larger text.
- Author and date are formatted on the same line, separated by a bullet character.
- The author is displayed! (Not sure why it would be hidden before. 🤔)
- The image is center aligned.
Conclusion
By including Microdata attributes the Reader Mode layout now provides extra visual affordance. These visuals help in communicating structure and purpose of the content.
When applied to the template, Reader Mode will provide a consistent visual style, helping people consume content with accuracy and ease.
And really, this is what we as designers and developers of the web should be striving for; focusing on ease of use and creating a comfortable experience for all readers of our content.