Essential HTML tweaks for accessible themes

Talk by Martin Stehle

The short talk shows developers, theme authors and plugin authors how to write the Hypertext Markup Language (HTML) code of themes and plugins for meeting the Web Content Accessibility Guidelines (WCAG) 2.1.

There are important success criteria in the WCAG which affect the way how you write the HTML code for your users. Do you know which ones? And do you know which functions are provided by the WordPress core to fullfill those criteria? This talk shows them all.

The talk provides you the tricks about

  • how to approach the challenge of writing accessible HTML code in an easy and effective way,
  • how to set informations and relationships of the content,
  • how to establish a meaningful sequence of the content,
  • how to write alternatives for non-text contents.

In detail you can learn about the WCAG-compliant generation of e.g.

  • continuous texts,
  • forms on WordPress options pages,
  • tables.

Watch Martin’s Presentation


Martin: For whom did I write this presentation? Of course, the frontend developers, the theme authors and also plugin authors. And of course for everybody who’s interested in my message. Because this is a really technical presentation we will talk about languages. Some need to code is uh, is eh.

Ok. What do I cover in this presentation. Of course, I will talk about the conformance levels A and AA. Because you have to fulfill them. I’ll talk about techniques categories, categorized, sorry, as sufficient and of HTML and relevant WordPress functions. I will not talk about, oh, I have to rearrange my second screen.

I will not talk about um, other topics, because I have not that time to get the contents in a basic presentation about that topic. I will not cover ARIA, not CSS or JavaScript, not Frames – no no, I have not that time.

But for all the other topics you are right here. OK. Let’s say some words about me again. About my, professional – yes, I am a computer scientist interested in media for about, 20 years. But I am also an expert for accessibility in the court.

I have impairments, I am body impaired, I am a wheelchair user. And of course, accessibility in every topic of my life was in my interest, is in my interest. And so, I got in touch with web accessibility in 1998, when I’ve did my first steps in HTML programming with great potential to create accessible content for everybody. But you have to know how to do it, and you also can do it really wrong.

So, I got in touch with the first WCAG and sort, we said, at one point, we were in 1999 I think, I was a contributor for the next version of them. And, today, I am a consultant and developer for accessibility. Now. What will you get? A soft warm up, then a big Journey, dive deeply into some coding.

And I will show you some of the benefits, how you can create them. OK. We’ll start with the soft warmup. Well, the very first element of an HTML code is, of course, the HTML element.

You know that. And, that’s also the topic of my first rule of thumb. Define the page language. That is also in Success Criterion 3.1.1 of conformation level A, that you have to fulfill that if you want to call your theme accessible.

It’s a very helpful information for applications, not for the human, but for applications so they don’t have to guess what is that human language. No. If you give them it with a tag or an element with an attribute with a value by lang, then you have the application for you, and they can speak in the correct language.

Well. How to create one that do not have the correct language of the web page? The human language? And how to do it right?

You tell the human language here in the HTML element with the lang attribute. lang is short for language. And you can see here an example how to specify that the human language of that page is in Portuguese – Brazilian Portuguese.

But, you know, WordPress is a CMS for the whole world, we have many languages of course, so don’t fix that language because you do not know what language the WordPress administrator will use.

So, how to do it more dynamically? How’s that, WordPress, by the very useful function called the language_attributes(). Put that into the HTML element and WordPress will do the rest for you. You can set it and forget it, OK? Also this language changes within the content, content of the web page. For example, we have an abbreviation in a foreign language, or you do quote a foreign person in the foreign language.

It’s very useful, for a screen reader, for example, to tell that page here comes another language, so change the speaker. Well, you can also use the lang attribute in any other element of HTML, for example, a span in an inline element. Or in another block element, like blockquote, and you can specify the language change there. You can’t just also specify the language, you can also specify the reading direction – for example, in English you use left to right reading, and if you want to quote a text in Arabic, there is a change in reading direction and you can do that with the dir attribute. dir is short for direction, and you can tell properly and for other machines here comes a change of reading direction.

If you want to go deeper into that, then read the specifications in ISO 1766 and read that and you know how to write proper language standards, language specifications, like this example for British English, Japanese, and Farsi, which is spoken in Iran.

Now, my second step here in the warmup is the page Title. I do not mean the title of the content, I mean the title of the whole web page. This is the criterion in the WCAG to help you identify the web page, and give you good orientation within the website. And not only within the website, the page title is also used by search engines to put the page title on the search engine’s results page.

So it’s not only useful for disabled people, it’s useful for everybody. What can you do wrong here? Well, I saw a page with no title in it at all; I saw a page with an empty title in it, I saw a webpage with default text which it repeated on every page in the title element.

Sometimes I saw the file name, or at least there is no unique title for each page in a website. How to do it properly. Well, I do see a list of techniques you can find them in the documentation of the WCAG 2.1 techniques. Use the title element, ensure the title element describes the current page, ensure unique title text. But, you don’t know what the title will be, because every editor, every contributor, can write the title.

So, you have to do it dynamically. And WordPress again provides a useful function for that. You only need to add the theme support of the ‘title-tag’ in your theme’s setup in functions.php And in header.php, you just call the function wp_head(), and what that will do that for you.

Why is that possible? Because wp_head() calls the function which prints out the title element and this function calls another function which renders the document title. I recommend you to take a look in the WordPress core code to that function is quite short and it covers every page, of every site, for example, a single post, a search the site page, or an error page, [unintelligible].

And you can either, you can change the page title, with filter hooks, as you can see here, the pre_get_document_title filter one. I take, I would recommend you take a look at that function, it’s very useful.

But you also can’t forget that you just use add_theme_support( 'title_tag' ) and wp_head().

OK. That was just a warm-up. For you, I hope you are into it and ready. But now, to try to begin, we will get deeper into that. First, think about that, maybe, before you started accessibility, maybe, you learned about coding that a web page is purely a visual mouse-controlled interface. If you have heard all the other presentation, you already know that is not true, because when you say it is “only” a purely visual interface that is not true, because there are other forms of presenting web page content.

In reality, a web page is a sequence of content and interactive elements, controlled by different technologies for different ways of presentation. Yeah? No. Too learn requirement for that, a specific mindset is really helpful. Three things they have to know. The first is “Text is king.” Because every browser, every device, can do with text. Not every browser can do with images or with videos or with audio, or with an applet or with a Flash file.

Every device can compute text. Can do something with text, so text is king. If you have any content, be sure that it is also available in a text word form. The rest is entourage. The second played in your mind set is “Always give structure” with HTML.

Don’t think about only the visual attention of your content. Separate content and the design of it. Mark up the content with HTML elements. And I will show you examples.

And the last, third and last played in your mindset is “Keyboard first”. If a webpage is not accessible with a keyboard, it is not accessible at all. OK? Mouse and loudspeaker and so are a distance. Keyboard is the first which has to work. Again – Text is king. Always give structure with HTML elements, and keyboard is first. OK?

Now you are ready for the big journey. Let’s take a look at these big topics: Structure, meaningful sequence of the content, and alternatives for non-text contents.

When it comes to structure, we have to take closer looks to three types of content: continuous texts, like you read a paragraph, headings, headlines, lists, and so on – forms, and there are tables. If you read continuous text – I’m sorry, if you produce continuous texts in your theme, in the editor, or in your guidance page, ensure that the structure of the web page content and the associations between distinct pieces of content are available in HTML.

If that sounds a bit abstract, but no going, I’ll show you some examples. Visual formatting is not sufficient: again, separate content and design. Design, yes, it’s OK, but first is content: Text is king. If you want to give structure, specify the structure automatically, and then you can design it with CSS.

What can you do wrong? Well, just a typical HTML code with no structure: There’s a div element, div is short for division, of course it has an attribute called class with value header, it must be the headline, we have tags, we have line breaks, and maybe some type of list? Yet how we can read that?

But now, assistive technology can not read that, can not make sense about that. And if you go farther, you will see more examples. You will see now a table. In the left column, there are some type of elements, and in the middle column you see how you can do it wrong, and in the right column you see how you do it correct.

If you want to specify a headline, yes, of course, is larger and bold font the text, and more and mostly separated by a blank line from the paragraph, yes. But, that does nothing an application can detect, so instead use heading element of HTML from H1 to H6, then you can design it with CSS.

But then go through list items, and form field, and for special words, words like abbreviations, emphasis, and so on.

The last line of the table tells you why. Because if you use another device, another than a visual output, you lost all structure information if you don’t give any structure information. If you provide any structure information, then they will be preserved even in a non-visual output. OK?

So, now for the next how-to we have an example for headings.

We have a screenshot on the left, of an option page in the backend. The red dots are headings, headlines. And we can see them. If you mark them up, properly, as headings, another device, for example a screen reader, can detect them as headlines. And the blind user can jump from headline to headline, a quite benefit for him. And you can see here a visual presentation of a list of headlines, and I think them critical, right?

How to: HTML. Well, how to continuous texts. Well, in determining which we have appropriate, education is when you know where to look it up. So, I recommend you look it up in the specification for HTML: how to use the elements, how to use which element for what, and do that properly. And I can say again and mind my pronunciation, use them, use these HTML elements, and use them and not other inventions because with a standard and maybe other inventions like division or span is not what is known by other devices.

And now we come to forms. Forms can really challenge for users, with vision impairment, with mobility impairment, with cognitive or other disabilities, and with others who are using assistive technologies. Oh, forms can be really really a burden, but you can write accessible forms.

What can you do wrong with forms? Well, in HTML, is an element called label, and the label element provides an association of the form control, maybe a checkbox, and its description. You can see how to do it wrong: do not provide any label element or provide a label element but not the association between the form control and its label, its description.

With these two examples, of label elements not using properly, there is no association of the text and the form control the machine cannot distinct, cannot specify the association. And in fact there is, when there are words the user have to fill out, so called, required fields, you can see here an asterisk of form that there are form fields and one form is required to fill out and is marked with an asterisk, an explanation of the asterisk is found down where, at the bottom of the form, where that is not effective.

And sometimes you see required fields marked by color only, of course you can see that, but can you hear that? Marking by color is OK, but that is not sufficient. So how to do it right. Use the label element and use other let element more structural element like fieldset and legend, like optgroup in a selection, like submit buttons, especially if you have selections, and indicate required form controls using labels or legends.

That means, on the second example, first example is how to label properly if you use the label element, you use it’s attribute called for, and in the form control, you use the attribute called id and you use both attributes the same way you, and now the machine or the software can create association between the description and the form control.

So do can the screen reader and other assistive technology. Right? Let’s move on to second example. How to indicate the required fields properly. Well, don’t put an explanation at the end of the form, but indicate an identical description at every form element which is required to fill out. Or you can use it in a legend if you have a group of form elements.

So, and, then you can indicate it with a color, in the second step of course. First is text is king, for form structure.

Well, it is important when it comes to backend pages, pages for the backend, it is really helpful to provide a consistent presentation of forms.

And for that, it’s not, uh, for that WordPress does provide some functions inside that here see in slide, chapter three, settings_fields(), do_settings_sections(), submit_button(), look it up please to see the documentation, and you can prepare the form with these two functions add_settings_field() and register_setting(). You do not have to write the form element, WordPress will do that for you inside, with these three lines, and you will have, and users will have a consistent form.

Now tables…oh…that’s pretty important – if we come to widget on the widget page, You can create, you might prefer, instances of the widget, how to be sure that the ID is unique on that page. And for that, WordPress provides the two functions get_field_id() and get_field_name(). Use them, as you see in your code, instead of hard-coded where you use these functions, if your widget is a subclass of the WordPress widget WP_Widget you have access to these two functions.

Okay, now I come to tables.

Tables are good to present table informations. What can you do wrong? You are not using table, or the table element – you are using the div element, or you are using tables for visual only, called layout tables. And you do not create any distinction between columns, headers, and data cells for example. So how to tables. Provide the correct markup, provide a summary attribute, a caption element, and using ids and header. I saw an example how to write it, in your code, this is the summary attribute in a table element, and here in a complex table you can see an example how to use the attribute headers and ID so, for example, a screen reader can read out if the tables are the value 20, which column header the table cell belongs.

Okay. Now, we will come to meaningful sequence. A very helpful technique. The meaningful order of content means that you have, the header, you have main content, you have sidebar, you have footers, you can change them but changing them will not change the meaning of the content, Okay?

If that is the case, then you have a meaningful sequence. There might be other, may be, other meaningful orders, of course, only one is sufficient for your web page or your theme template. Yeah? And that is important because if you provide a meaningful sequence your web page is accessible not only in visual causes, it’s also accessible in assistive devices.

What can you do wrong? Well, you do not provide any content structure via HTML or you want to try it with CSS to at least provide meaningful sequence visually, but again there’s a lack of structure, that’s a big failure.

How to do it. Use the HTML elements for structure, and test your content. Either turn off the CSS in your browser, or else use a text-only browser like Lynx, or a service like Textise, to have a look, to have an image of your text.

Ok? And now, the next big step in our journey, the third and last big step, is about non-text content.

We all love non-text content, like videos, like audios, like animations. But, text is king, right? So, what are we doing? We provide text alternatives for those types of content. For example, for audios and videos, there’s a text transcript and I will show you an example in German of the Federal president. You can see here a video, in sign language, but then, the president starts to talk, and what he says is also available here, as text. Here as a PDF, and in an easy language.

So, if you have a text alternative, well that’s acceptable, right? OK. Back to our presentation. If you have video, use captions. And with the track element, you can combine video with captions files, like so. If you have applets, use the alt attribute.If you have objects, use the body of the element to provide alternative of the text.

And now, the big topic is of course, images. Well, my speakers before me told a lot about images and alternative text. I just repeat it here. Use alt attributes, use alt also in images in sitemaps, no, not sitemaps, in image maps. And if there images are decorative, don’t use any alt text. I want to provide a helpful resource on the server of the

It’s the so-called alt decision tree, a very funny and helpful graphic to tell you how you write an alternative text. I know, of course, you can do it in a quick way, that was described in a presentation ago. There a thought called a telephone test, explain during a phone call to other person an image in not more than 10 words, maybe 11 words, or in a short sentence. How would you do it? There, you get the idea of that image.

Very quick and easy rule of thumb how to write correct and useful alternative text for images.

Wah! That’s a big journey. Let’s take the last topic of my presentation and you think, well, I’m running out of time. Right? So, I will do it fast. Fasten your seatbelt, please.

Well, keyboard support is really crucial, of course for accessibility, keyboard first. So test your web page with the keyboard and without the mouse. If you can access all form elements with the keyboard only, then you have an accessible web page.

If you can reach every link with the keyboard only, you have an accessible web page. What can you do wrong? You do not use HTML properly, for example, here’s a span with the onclick attribute. That is not a link for a machine, that’s something what you invented, no. Or the onchange event on a selection field.

There is not, there’s the at least two orientations failure. How to do it properly. Well, avoid use of JavaScript for interactivity and use HTML. Bypass blocks, that equate to topic. Blocks, I do not mean the Gutenberg blocks. I mean blocks as sections of the content, of the web page. Repeated on multiple pages, like navigation link block or the main content block, or sidebars, and so on. So, provide links to that blocks.

These links do not need to be visible, the so-called skip links. If you use, let me show you an example, Here you can see a page of my localhost, and I am using now the tab key. Once, and you can see here, the skip link. Very helpful for users with visual impairment, or use screen reader, and is read, is speaking out loud for screen reader users, of course.

I use the class skip-link and screen-reader-text, and I recommend you to take a look in the file style.css of the Twenty-Twenty theme and to re-use these statements in CSS for your themes.

Soon, we will come to an end, I promise.

Just links. As we have seen, in the presentations ago, provide useful links, because links can be read out out of context. Out of the web page context, for example, in a link list, of a screen reader, or another assistive technology. So be sure that a link text is understandable out of context.

What can you do wrong? Well, using the read more links especially on archive pages of a blog.

Then you hear, read more read more read more read more, and you do not know, OK, what’s the topic of that link? Or you use different link for the same target, that’s OK, but not optimal because the link of consistency and may cause disorientation.

And now you open your windows in new tabs without notice, for me, I think, that is not forbidden but you can do it better. How to. Well, provide a link text, which describes the purpose of a link. And uses the same link text for the same target, and of course, use different link text for different targets or different web pages.

You can extend the link text with the title attribute, but be aware that is not reliable because users can turn off speaking of the title attribute. Instead, extend the link text with visually hidden unique text. And here you can see an example of that I have found that in the theme Twenty Nineteen is a function the_content() and you can pass the link text for that, for the read more link and with that construction, you can offer a link that you print out only Continue Reading, but in the assistive technology, there is a longer description, a unique link. Again, then you see, if you put the title of the_title() into the link description, and you, so you can provide unique links hearing, but visually consistently.

And how to open new tabs. It’s very easy. just say in the link that it is opens in a new tab, in a new window, and you don’t like the text, you can hide it visually at least it is speak out loud for screen reader users. Of course, use a list, a group of links, and use an element nav for navigation. A nav element is really useful, and education, here, if you know where to look it up. I provide you a link because in WordPress 5.5. there’s great support for nav element using aria labels.

Now I come to, I think, the last one. The last topic of the presentation. The focus order.

Focus is when you tab through the content and you can reach the links, the form fields, every one, Provide a meaningful focus order, and let me provide a meaningful sequence, so you get a meaningful focus order. What can you do wrong? Use a tabindex attribute, oh, yes, there’s a tabindex attribute that you can control the order of the focus while tabbing, or doing tabbing, but you do not know if what happen if the possible with other element without the tabindex attribute, and the other there is maybe you use the :hover pseudoclass for mouse overs, but do not provide the :focus class, too. So, how do you do it properly?

Use both the :focus and the :hover class, pseudoclasses, and avoid the tabindex attribute. That’s my preferred use no tabindex, just provide a meaningful sequence in the HTML code, then the focus order is meaningful too. OK, this is my really last. We can squeeze something in not about fooling, about resizing. The window, for example, or resizing the content, with the browser functions.

Well, how can you do it wrong in HTML.

You provide the meta element, but if you put name and I have seen that you do not allow any scaling or resizing. How to do it properly. A wise technique tells you don’t put it in or if you have to, allow scaling and resizing, so you can see here in this example.

Well, congratulations! Now we have come to an end. We have learned the mindset of an accessible developer. Text, structure, and keyboard first. And we have learned how to structure the template provide a meaningful sequence without CSS first, provide text alternatives, provide skip links, and provide tab-able and resize-able content.

We have some tools which helps you in the world, some data like Nu HTML Checker, or An accessibility checker online called WAVE, I love that tool, and a text only converter, Textise. You can find this presentation on Slideshare now, on that link, and now, the line is open for questions.

Megan: Thanks so much, Martin. Unfortunately, we don’t have time for questions.

But there are some on the site, and we’ll make sure those get answered.

We’re actually going to be able to move into our closing remarks, but…

Additional Resources

WP Accessibility Day has not assessed speaker-provided presentation resources for accessibility.

View presentation slides

Questions on “Essential HTML tweaks for accessible themes

  1. Q: Since the title element can only contain text, would you recommend avoiding language changes in page titles, or using different text for the title element and the main page heading?

    1. Yes, I recommend to avoid language changes in the title element to stay comprehensible for all users (and also accessible). Instead use the language of the website, even in the title of the page content, and use the foreign text in the rest of the content.

  2. Q: WordPress doesn’t provide any native tools for making forms; but they’re clearly needed by most sites. Do you have a recommended form plugin for WordPress?

    1. My opinion is: a length of 60 – 70 characters is sufficient. Think about a list of posts with fatured images, and all these images have an alt text. Short texts help to scan that list quickly. I’d use “very lengthy” alt texts as image captions.

    1. A very bad example is any element with the “onclick” event. Use the A element instead.
      Bad examples of Javascript interactivity are often found in forms when Javascript events like “onchange” and “onsubmit” trigger changes which an assistive technology is not aware of and so the user, too., E.g. loading a new page after an option in a selection field was selected.
      A good example is: first develop without Javascript. If that work, you can add Javascript interactivity as long as assistive technologies (and so the users) aree awre of the changes created by Javascript. That approach is also known as “Progressive enhancement”.

  3. A very bad example is any element with the “onclick” event. Use the A element instead.
    Bad examples of Javascript interactivity are often found in forms when Javascript events like “onchange” and “onsubmit” trigger changes which an assistive technology is not aware of and so the user, too., E.g. loading a new page after an option in a selection field was selected.
    A good example is: first develop without Javascript. If that work, you can add Javascript interactivity as long as assistive technologies (and so the users) aree awre of the changes created by Javascript. That approach is also known as “Progressive enhancement”.