Classic theme accessibility semantics
Skill Lonsdale201/wp-agent-skills/theme-development/classic-theme-accessibility-semantics
A community-maintained collection of agent skills for WordPress plugin and theme development.
npx -y skills add Lonsdale201/wp-agent-skills --skill classic-theme-accessibility-semanticsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 21 stars21 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Build or audit accessibility and semantic HTML in classic PHP WordPress themes on WP 7.0. Covers `language_attributes()`, `wp_head()`, `body_class()`, `wp_body_open()`, landmarks, skip links, focus management, `screen-reader-text`, heading order, nav/button semantics, `aria-controls` and `aria-expanded`, forms and labels, image alt handling, icon accessibility, reduced motion CSS, search forms, and common mistakes such as hover-only menus, hidden focus outlines, fake buttons, missing main landmarks, or unlabeled controls.
SKILL.md
9.0 KB, as published. Nobody here has run it
Classic Theme Accessibility and Semantics
Use this when creating or reviewing the HTML semantics, keyboard behavior, landmarks, skip links, focus styles, forms, images, icons, and ARIA behavior of a classic PHP WordPress theme.
Accessibility is not a visual polish pass. It affects template structure, PHP output, CSS, and JavaScript behavior.
When to Use This Skill
- Writing
header.php,footer.php,index.php,single.php,page.php, or navigation templates. - Adding a mobile menu, modal, search toggle, carousel, tabs, accordion, or interactive widget.
- Reviewing theme markup for WordPress.org-style accessibility expectations.
- Fixing keyboard navigation, missing focus states, unlabeled controls, bad heading order, or broken landmarks.
Document Skeleton
A classic theme header should preserve core hooks and language/body helpers.
<!doctype html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
Rules:
- Use
language_attributes()on<html>. - Use
bloginfo( 'charset' )for the charset. - Use
wp_head()before closing</head>. - Use
body_class()on<body>. - Call
wp_body_open()immediately after the opening body tag. - Add
add_theme_support( 'title-tag' )in theme setup; do not hardcode<title>.
Landmarks
Use semantic landmarks so users can navigate the page structure.
<header id="masthead" class="site-header">
<nav id="site-navigation" class="main-navigation" aria-label="<?php esc_attr_e( 'Primary menu', 'textdomain' ); ?>">
...
</nav>
</header>
<main id="main" class="site-main">
...
</main>
<footer id="colophon" class="site-footer">
...
</footer>
Rules:
- Each page should have a clear main landmark.
- Major navigation landmarks need accessible names when there is more than one
nav. - Do not put the entire page in generic
<div>elements when semantic elements fit. - Do not create multiple unlabeled
mainelements.
Skip Links
Add a skip link that becomes visible on focus and targets real content.
<a class="skip-link screen-reader-text" href="#main">
<?php esc_html_e( 'Skip to content', 'textdomain' ); ?>
</a>
The target must exist. If focus needs to move reliably in JavaScript-assisted layouts, make the target focusable:
<main id="main" class="site-main" tabindex="-1">
Rules:
- The skip link must be the first meaningful focusable element after
wp_body_open(). - It must become visible on keyboard focus.
- The
hrefmust point to an ID that exists on every template.
Screen Reader Text CSS
Include a standard visually-hidden utility and restore it on focus.
.screen-reader-text {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(1px, 1px, 1px, 1px);
word-wrap: normal;
border: 0;
}
.screen-reader-text:focus {
top: 5px;
left: 5px;
z-index: 100000;
display: block;
width: auto;
height: auto;
padding: 15px 23px 14px;
clip: auto;
background: #fff;
color: #000;
font-size: 1rem;
font-weight: 700;
text-decoration: none;
}
Rules:
- Do not use
display: nonefor content that screen readers need. - Make skip links visible on focus, not only available to assistive tech.
- Keep focus styles visible above sticky headers.
Headings
Headings describe document structure.
Rules:
- Use one clear
h1for the primary page title. - Archive/search pages usually use the archive/search title as
h1. - Posts in archive cards should usually use
h2. - Do not choose heading levels based only on font size.
- Do not skip levels to achieve visual styling; style with CSS.
Links, Buttons, and Toggles
Use elements by behavior:
- Links navigate to URLs.
- Buttons perform actions on the current page.
- Form controls collect input.
Mobile menu toggle:
<button
class="menu-toggle"
type="button"
aria-controls="primary-menu"
aria-expanded="false"
>
<?php esc_html_e( 'Menu', 'textdomain' ); ?>
</button>
Rules:
- Do not use
<a href="#">as a button. - Keep visible labels or accessible names for icon-only buttons.
- Update
aria-expandedwhen a controlled region opens/closes. aria-controlsmust reference an existing ID.- Avoid adding ARIA when native HTML already communicates the behavior correctly.
Focus and Keyboard
Rules:
- Never remove
outlinewithout a visible replacement. - Use
:focus-visiblewhere appropriate, with a fallback if supporting older browsers. - Hover-only menus are not enough. Keyboard users must be able to open and traverse navigation.
- Modals and off-canvas panels need focus management and Escape behavior. If the theme cannot implement that correctly, avoid shipping the interaction.
- Do not trap focus in ordinary dropdown navigation.
Forms and Search
Rules:
- Every input needs a real
<label>or an equivalent accessible name. - Placeholder text is not a label.
- Error messages should identify the field and be programmatically connected when possible.
- Use
get_search_form()unless the theme has a specific accessible custom search form. - Nonces and validation are security concerns, but accessible errors are still required for user correction.
Images and Icons
Rules:
- Informative images need useful alt text.
- Decorative images should use empty alt text.
- Do not stuff keywords into alt text.
- For featured images, rely on WordPress image functions where possible and ensure attachment alt text is maintained.
- SVG icons used only as decoration should have
aria-hidden="true"andfocusable="false". - Icon-only buttons/links need an accessible name via visible text,
.screen-reader-text, oraria-label.
Motion and Visual Requirements
Respect reduced motion preferences.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
scroll-behavior: auto !important;
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
Rules:
- Ensure text contrast is sufficient in normal, hover, and focus states.
- Do not rely on color alone to communicate state.
- Keep line heights and spacing readable.
- Avoid auto-playing motion-heavy UI. If used, provide pause/stop controls.
WordPress Template Helpers
Preserve helpers that contribute useful classes and core integration:
body_class()on<body>.post_class()on post wrappers.wp_body_open()after<body>.wp_head()andwp_footer().language_attributes()on<html>.the_custom_logo()when using core custom logo support.get_search_form()for baseline search form behavior.
Review Checklist
- Header uses
language_attributes(),wp_head(),body_class(), andwp_body_open(). - Page has one clear main landmark.
- Skip link exists, is focus-visible, and points to a real ID.
- Navigation landmarks have accessible names.
- Mobile toggles are buttons and update
aria-expanded. - Keyboard focus is visible everywhere.
- Headings follow document structure.
- Forms have labels and understandable errors.
- Images and SVG icons have appropriate alt/ARIA behavior.
- Reduced motion is respected for animations/transitions.
- Theme does not rely on hover-only interactions.
Common Mistakes
- Hiding skip links with
display: none. - Removing outlines globally.
- Using a fake link for menu/search toggles.
- Adding
role="button"to an anchor instead of using a button. - Creating several unlabeled navigation landmarks.
- Outputting icon-only buttons with no accessible name.
- Making dropdown menus impossible to use with a keyboard.
- Forgetting
wp_body_open()inheader.php.
References
- Official documentation: https://developer.wordpress.org/themes/functionality/accessibility/
- Official documentation: https://developer.wordpress.org/themes/classic-themes/basics/template-tags/
- Verified source paths:
wp-includes/general-template.phpwp-includes/post-template.phpwp-includes/nav-menu-template.phpwp-includes/class-walker-nav-menu.phpwp-content/themes/storefront/inc/structure/header.phpwp-content/themes/generatepress/header.php