How to add and test skip links


Many users navigate websites using the keyboard only or with screen readers. These users need a way to skip directly to the main content of the page.

If your theme has a navigation menu, a header / banner area with content, or secondary sidebars before users reach the main content, your theme is required to include a skip link.

Even if you have never used a skip link in your theme before, you may have seen this behavior in WordPress core or on other websites.

For example, if you navigate to the top of this page, and press the Tab key, you will see a skip link:

A button element with the text "Skip to toolbar" in high contrast.

Clicking the link or using the Enter key will bring you to the target area.

This is the first focusable element on this page, and this is what you need to recreate.

And as a reviewer, you have already tested everything you need to see if a theme passes this requirement.

Lets look at one more example. Below is an animation of the skip link used in Twenty Nineteen. First, I place the cursor in the adress field and press Tab. When the skip link is focused, I press Enter, and focus is moved to the element with the content ID:

An animation of the skip link used in the Twenty Nineteen theme. When the skip link is used, the focus moves to the container that holds the main content.

A minimally conforming skip link must:

  • Be the first focusable element perceived by a user via screen reader or keyboard navigation.
  • Be visible when keyboard focus moves to the link.
  • Move focus to the main content area of the page when activated.

Note that using a small font-size for the link, or a color contrast that is too low, may render the skip link useless to the users that it is intended to help (Note that despite it’s style, this is not a button).

Code examples:

Place the link at the top of your page, for example below wp_body_open in header.php:

<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<div id="page" class="site">
<a class="skip-link screen-reader-text" href="#content">
<?php _e( 'Skip to content', 'twentynineteen' ); ?></a>

Remember to adjust the link target to make it work for your theme.

CSS:

/* Accessibility */
/* 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 !important;
  width: 1px;
  word-wrap: normal !important;
  /* Many screen reader and browser combinations announce broken words as they would appear visually. */
}

.screen-reader-text:focus {
  background-color: #f1f1f1;
  border-radius: 3px;
  box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6);
  clip: auto !important;
  clip-path: none;
  color: #21759b;
  display: block;
  font-size: 14px;
  font-size: 0.875rem;
  font-weight: bold;
  height: auto;
  right: 5px;
  line-height: normal;
  padding: 15px 23px 14px;
  text-decoration: none;
  top: 5px;
  width: auto;
  z-index: 100000;
  /* Above WP toolbar. */
}

/* Do not show the outline on the skip link target. */
#content[tabindex="-1"]:focus {
  outline: 0;
}

JavaScript

There are known bugs with skip links, so if you want to add workarounds, this is how the problem is solved in the default theme:

/**
 * Fix skip link focus in IE11.
 *
 * This does not enqueue the script because it is tiny and because it is only for IE11,
 * thus it does not warrant having an entire dedicated blocking script being loaded.
 *
 * @link https://git.io/vWdr2
 */
function twentynineteen_skip_link_focus_fix() {
	// The following is minified via `terser --compress --mangle -- js/skip-link-focus-fix.js`.
	?>
	<script>
	/(trident|msie)/i.test(navigator.userAgent)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",function(){var t,e=location.hash.substring(1);/^[A-z0-9_-]+$/.test(e)&&(t=document.getElementById(e))&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())},!1);
	</script>
	<?php
}
add_action( 'wp_print_footer_scripts', 'twentynineteen_skip_link_focus_fix' );

Read more about skip links:

Please read the following documentation from the accessibility team: WordPress Accessibility – Development best practices -Skip Links https://make.wordpress.org/accessibility/handbook/markup/skip-links/

https://make.wordpress.org/themes/handbook/review/accessibility/required/#skip-links

Techniques for WCAG 2.0 -G1: Adding a link at the top of each page that goes directly to the main content area