Markup Style guide

Follow the regular WordPress HTML style guide, with the additions and modifications listed here.

Generating a semantic DOM is important. Then HTML elements have true meaning and devices like browsers and assistive technology know how to interact with them natively. Even when writing a dynamically generated DOM (such as with React), be mindful of what you’re actually outputting.

We aim to meet the WCAG accessibility guidelines at level AA.

Generated HTML can be checked against W3C standards using the W3C Markup Validation Service. And by using the aXe accessibility testing tool available as browser extension or the npm module aXe-core.

This markup guide is additional to 10up Best Practices on Markup

HTML5 Structural Elements

Additional to the 10up best practices: the HTML5 document outline is not supported by browsers. This requires developers to use h1-h6 to convey document structure, not section structure.

This means: one unique H1, that describes the content of the page, and the rest of the headings are used meaningful and sequential, without skipping a heading level. A heading should represent the content below.


  • use semantic HTML5 elements. Don’t compose the HTML using mainly (meaningless) divs and spans.
  • use an <a> for change of location
  • use a <button> to invoke an action
// Bad:
<div style="big-heading">News</div>

// Good:
// Bad:
<a href="#" id="js-some-action">Open</a>

// Good:
<button id="js-some-action">Open</button>

screen-reader-text class

This class is used to hide content from screen but not from screen readers and search engines.

/* Text meant only for screen readers. */
.screen-reader-text {
    border: 0;
    clip: rect( 1px, 1px, 1px, 1px );
    clip-path: inset( 50% );
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
    word-wrap: normal;

Use of colour

The ratio of the colour contrast between text (or text on images) and the background colour must be:

  • 1 : 4.5 or higher for text smaller than 24 pixels
  • 1 : 3.1 or higher for text equal or larger than 24 pixels

For bold text:

  • 1 : 4.5 or higher for text smaller than 19 pixels
  • 1 : 3.1 or higher for text equal or larger than 19 pixels

There are many tools to check colour contrast, for example:

Title attribute


Give iframes a unique title attribute describing the content of the iframe.

<iframe title="Your title" src="your-url"></iframe>

Don’t use a title attribute on links. The support is so different per device that it can’t be trusted to be consistent.

// Bad:
<a href="your-url" title="Your title"></a>
// Good:
<a href="your-url">Your title</a>

If you don’t want to show the link text, use the .screen-reader-text class to hide it from vision:

<a href="your-url"><span class="screen-reader-text">Your title</span></a>


WAI-ARIA stands for “Web Accessibility Initiative – Accessible Rich Internet Applications”. It is a set of attributes to help enhance the semantics of a web site or web application to help assistive technologies, such as screen readers for the blind, make sense of certain things that are not native to HTML.

First rule of ARIA: don’t use ARIA.

A pure semantic HTML5 solution without ARIA is always preferred. This way all devices interacting with the web page or app understand the meaning of this element.

// Bad:
<div role="button" tabindex="0">text</div>

// Redundant:
<button role="button">text</button>

// Good:

ARIA can be useful for announcing dynamic or toggled content.

ARIA Landmark Roles

Now browsers support HTML5 better, some ARIA roles became redundant:

// Old:
<article role="article">
<aside role="complementary">
<footer role="contentinfo">
<header role="banner">
<main role="main">
<nav role="navigation">
<section role="region">

// New:
<footer> (if not within an article or section element)
<header> (if not within an article or section element)