WordPress Accessibility: Fixing Themes, Blocks and Forms
WordPress itself produces reasonably accessible markup, but most WordPress sites are a mix of a theme, a page builder or the block editor, a dozen plugins and years of content written by different people. Each of those can introduce accessibility faults, and fixing them one page at a time rarely sticks.
This guide shows how to trace each Accessibility Audit finding back to the part of WordPress that produced it, fix it once where it starts, and set up the site so editors and plugin updates do not quietly undo the work.
- Where WordPress accessibility faults start
- Tracing a finding to the theme, a plugin or content
- Themes: what accessibility-ready does and does not mean
- Code for common theme fixes
- Block editor habits that cause most content findings
- Page builders: settings to check before writing code
- The fix, step by step
- Accessibility plugins and overlays
- Keeping it fixed
- Questions and answers
Where WordPress accessibility faults start
A finding in the report is just a symptom on one page. Before changing anything, decide which part of WordPress wrote the faulty HTML, because that decides where the fix belongs and whether it will survive the next update.
| Source | Faults it tends to cause | Where the fix lives |
|---|---|---|
| Theme templates and stylesheet | No skip link, missing main landmark, focus
outlines removed, pale body text, site title coded as h1 on every page, sidebar widget titles
at the wrong level | Theme settings, a child theme, the Site Editor for block themes |
| Block editor content | Images with no alt text, headings picked for size, Cover blocks with unreadable text, Buttons that all say the same thing | The post or page itself, and reusable patterns |
| Page builders (Elementor, Divi, Beaver Builder and similar) | Clickable div
elements, icon boxes with no text, tabs and accordions that do not work with a keyboard, heading tags
set in widget options | Widget settings, global widget templates, custom CSS |
| Form plugins | Fields labelled only by placeholder, radio groups with no group name, errors shown only in red | The form builder settings and the form markup |
| Other plugins | Cookie banners that trap focus, sliders that move on their own, chat widgets, social share icons with no names | Plugin settings, a replacement plugin, or the plugin author |
Most sites find that a few template-level faults generate the bulk of the report, because the header, footer and sidebar appear on every URL. Fixing those first makes the remaining list short enough to deal with properly.
Tracing a finding to the theme, a plugin or content
WordPress adds tell-tale class names to almost everything it outputs, which makes tracing quick. Right-click the failing element, choose Inspect, and look at the classes on it and its parents:
wp-block-classes, such aswp-block-imageorwp-block-cover, mean the markup came from a core block. The fix is in the editor for that post, or in the theme's styles if it is a colour or focus problem.elementor-,et_pb_(Divi) orfl-(Beaver Builder) classes point to a page builder widget. Find the widget on the page and check its settings before writing any code.wpcf7,gform_,wpforms-ornf-belong to Contact Form 7, Gravity Forms, WPForms and Ninja Forms respectively.- A class you do not recognise near the end of the page is usually a plugin. Searching the class name with the plugin's name, or deactivating plugins one at a time on staging, will identify it.
- Nothing obvious on a header, footer or sidebar element usually means the theme.
For a block theme, open Appearance, Editor, then the template part; for a classic theme, the fault is
in files such as
header.phporsidebar.php.
Themes: what accessibility-ready does and does not mean
The WordPress.org theme directory has an accessibility-ready tag. Themes carrying it have been reviewed against the WordPress accessibility team's theme requirements, which cover things like a working skip link, visible keyboard focus, sufficient contrast in the default colours, correctly structured headings, labelled form controls and menus that work with a keyboard. The recent default themes have carried the tag, and several popular free themes do as well; check the tag on the theme's directory page rather than relying on a sales page.
The tag is a good starting point, but it describes the theme as shipped. It does not cover:
- colours you change in the Customiser or in Global Styles after installing;
- demo content, starter templates and patterns imported from the theme author;
- anything a page builder draws inside the content area;
- plugins, and the content your editors write.
Premium themes sold on marketplaces have no equivalent review, so test them yourself. If a theme hides focus outlines, has no skip link and codes the logo as a heading, it is often less work to move to a well-built theme than to patch it through a child theme for years.
Block themes and the automatic skip link
For block themes, WordPress adds a "Skip to content" link automatically, pointing at the main
element of the template. If your block theme has no skip link, the usual reason is that the template
uses a plain Group block instead of one set to the main HTML element. Select the Group that
wraps the content in the Site Editor, open Advanced in the block settings and set the HTML element to
<main>. Classic themes must provide their own skip link in header.php.
Code for common theme fixes
Make theme changes in a child theme or in the Additional CSS panel, never in the parent theme's files, or the next theme update will wipe them. These examples cover the three theme faults that come up most often.
Restore a visible focus outline
/* Appearance, Customise, Additional CSS (classic themes)
or Styles, Additional CSS in the Site Editor (block themes) */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.wp-block-button__link:focus-visible {
outline: 3px solid #1a4fd0;
outline-offset: 2px;
}
Pick an outline colour with at least 3:1 contrast against both the element and the background around it. If the site has a dark header, you may need a second rule with a light outline for links inside it.
Add a skip link to a classic theme
<!-- child theme header.php, straight after wp_body_open() -->
<a class="skip-link screen-reader-text" href="#primary">Skip to content</a>
<!-- and make sure the content wrapper has that id -->
<main id="primary" class="site-main">
WordPress core already provides a screen-reader-text class in most themes that hides
text visually and shows it again on focus. If yours does not, add a rule that brings the link into view
when it receives focus, otherwise sighted keyboard users will tab onto an invisible link.
Stop the site title being an h1 on inner pages
<?php if ( is_front_page() ) : ?>
<h1 class="site-title"><?php bloginfo( 'name' ); ?></h1>
<?php else : ?>
<p class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php bloginfo( 'name' ); ?></a></p>
<?php endif; ?>
Many older themes print the site name in an h1 on every URL, so each post starts with
the same heading and the real post title becomes a second h1. Keeping the site name as a
paragraph on inner pages lets the post or page title be the one main heading.
Block editor habits that cause most content findings
- Alt text lives in the block, not only the media library. When you insert an image, the block copies the alt text from the media library at that moment. Editing the alt text in the library later does not change posts where the image is already used, so fix old images inside each post, in the Image block's settings sidebar.
- Empty alt text is correct for decoration. If an Image block's alt text is left empty,
WordPress outputs
alt="", which tells screen readers to skip it. That is right for dividers and mood photos, and wrong for a chart, a product or an image that is also a link. - Use the Outline view for headings. In the editor, open the Document Overview (the list icon in the top toolbar) and choose Outline. It lists every heading with its level and flags levels that are skipped, which is quicker than checking each Heading block.
- Choose heading levels for structure. If a heading looks too large, change its font size in the block's Typography settings rather than dropping it to a lower level.
- Watch Cover blocks. Text laid over a photo often fails contrast in some parts of the image. Raise the Overlay opacity, pick a darker overlay colour or move the text out of the image.
- Give Buttons distinct text. Three Buttons blocks that all say "Learn more" sound identical when a screen reader lists links. Write "See our pricing" or "Read the case study" instead.
- Respect contrast warnings. When you pick text and background colours in the block settings, the editor shows a warning if the pair may be hard to read. Do not ignore it.
Page builders: settings to check before writing code
Page builders can produce accessible output, but their defaults and demo templates often do not. Most of the fixes are settings rather than code:
| Widget | Common fault | What to change |
|---|---|---|
| Heading widget | Tag left at the default, so every widget heading is h2 or
a card title is h1 | Set the HTML tag option to the level the section actually needs; style size separately |
| Icon box, image box, flip box | Whole box is a link with only an icon inside, or the link wraps nothing readable | Add a visible title inside the link, or link only the title text |
| Tabs, accordions, toggles | Titles are not buttons, so Tab and Enter do nothing | Update the builder, check the widget's accessibility options, or replace with the core Details block |
| Image carousel and slider | Autoplay with no pause control, arrows with no names | Turn autoplay off, or make sure a visible pause button exists |
| Social icons | Icon-only links with no accessible name | Fill the label or title field for each network so the link has text |
| Popup builder | Focus does not move into the popup and cannot leave it | Enable any focus or accessibility options, and avoid popups that open on page load |
Builders change their widget markup between releases, so test after major updates. If a widget cannot be made accessible through its settings, replace it with a core block or a simple HTML widget rather than fighting it with CSS.
The fix, step by step
Step 1
Test a staging copy one template at a time
Make a staging copy of the site, which many hosts offer with one click, so you can deactivate plugins and edit templates without affecting visitors. Run the Accessibility Audit on one URL of each template: home, page, post, archive, search, contact and any shop pages. Group the findings by the class names on the failing elements, so you can see which came from the theme, a builder, a form plugin or content.
Step 2
Check what the theme gives you
Press
Tab on a fresh page load and see whether a Skip to content link appears, whether a focus
outline follows you through the menu, and whether the site title is an h1 on inner pages.
Look up the theme in the WordPress.org directory for the accessibility-ready tag. If the theme fails
most of these, compare the cost of patching it through a child theme with moving to a better-built theme.
Step 3
Repair skip links, focus and colours in the theme
Work in a child theme, the Site Editor or Additional CSS so updates do not erase
the changes. Add a :focus-visible outline with at least 3:1 contrast, make sure the content
area is a main element with a working skip link, and adjust palette colours in Global Styles
or the Customiser until body text reaches 4.5:1. Fix sidebar and footer widget title levels in the template,
not post by post.
Step 4
Correct blocks and page builder widgets
Open the worst pages in the editor and use the Outline view to correct heading levels, then add alt text to informative images inside each Image block. Darken Cover block overlays where text is hard to read and rewrite repeated button text. In a page builder, set each Heading widget tag deliberately, add titles to icon boxes, fill social icon labels and turn off carousel autoplay before resorting to custom code.
Step 5
Label every form plugin field
Open each form in Contact Form 7, Gravity Forms, WPForms or your builder's form widget. Make sure every field has a visible label rather than only placeholder text, that radio buttons and checkboxes sit in a group with a name, and that required fields are marked in words as well as with an asterisk. Submit each form empty and check the error messages are shown as text next to the fields.
Step 6
Tame menus, sliders and pop-up plugins
Check that the main menu opens submenus with Enter or Space, not only on hover; in the Navigation block, the Open on click option does this. Turn off autoplay on sliders or make sure they have a pause button. Test the cookie banner, newsletter pop-up and chat widget with the keyboard: focus must reach them, Escape or a named close button must dismiss them, and they must not block the page.
Step 7
Build accessibility into publishing and updates
Add alt text, heading order and descriptive link text to your editors' publishing checklist, and save accessible layouts as synced patterns. After every theme, builder or major plugin update, run the Accessibility Audit again on the same template URLs and compare with the previous results. Publish an accessibility statement explaining what you have tested, any known gaps and how visitors can contact you for help.
Accessibility plugins and overlays
Two quite different kinds of product are sold as WordPress accessibility plugins, and it matters which one you install.
- Helper plugins that change your markup. These add things the theme is missing, such as a skip link or a language attribute, or add prompts in the admin so editors fill in alt text. They make real changes to the HTML every visitor receives. They are useful as a stopgap, but check each setting and understand what it does; a better theme often makes several of them unnecessary.
- Checker plugins that report in the admin. These scan posts as you save them and warn about missing alt text or skipped headings. They help editors catch mistakes, but like any automated test they cannot judge whether alt text is accurate.
- Overlay toolbars. These add a floating button offering larger text, contrast modes or "screen reader" features on top of the site. They do not repair unlabelled fields, keyboard traps or wrong headings in the underlying code, and they can clash with the assistive technology disabled visitors already use. Fix the site instead.
Keeping it fixed
- Test on staging after updates. Theme and page builder updates regularly change markup. Re-run the checker on your template URLs before pushing an update live.
- Limit who can change global colours. Global Styles and Customiser colour changes affect every page at once. Keep that permission with the people who understand contrast.
- Review new plugins before activating. Pop-ups, sliders, chat and cookie plugins are the most common source of new keyboard traps. Test one on staging with a keyboard before adding it to the live site.
- Train editors on four things. Alt text, heading levels, link text and not using colour alone. That covers most of the content findings a WordPress site produces.
- Keep the accessibility statement current. Update it when you fix known issues or add new features.
1. Is WordPress accessible out of the box?
The WordPress admin and the core blocks are developed with accessibility in mind, and a default install with an accessibility-ready theme is a good starting point. The problems usually arrive afterwards: a theme bought for its looks, colour changes, a page builder, pop-up and slider plugins, and content written without alt text or proper headings. So WordPress can produce an accessible site, but whether yours is depends on the theme, plugins and editing habits you add to it.
2. What does the accessibility-ready theme tag mean?
It means the theme was reviewed by the WordPress.org theme team against a set of accessibility requirements before the tag was allowed, covering things such as skip links, keyboard navigation, visible focus, contrast in the default colours, heading structure and labelled forms. It applies to the theme as released, with its default settings. Your own colour choices, imported demo content, page builder layouts and plugins are not covered, so you still need to test the finished site with the checker and a keyboard.
3. Will an accessibility plugin fix my WordPress site?
Only partly. Helper plugins can add a skip link, set the page language or prompt editors for alt text, and checker plugins can warn about problems while you edit. None of them can rewrite a page builder tab widget so it works with a keyboard, or decide what an image should be described as. Overlay toolbars that sit on top of the site do not fix the code at all. Use plugins as helpers alongside fixing the theme, widgets and content themselves.
4. Are Elementor and Divi bad for accessibility?
Not necessarily, but they need more care than the core block editor. Page builders give editors free choice over heading tags, colours and interactive widgets, and older versions and imported templates often produced clickable boxes that were not real links or buttons. Keep the builder updated, check each widget with a keyboard, set heading tags deliberately and avoid widgets that cannot be operated without a mouse. If a widget cannot be fixed through its settings, replace it with something simpler.
5. Why does my WordPress theme remove the focus outline?
Some designers remove the outline because they think it looks untidy when people click buttons with a mouse, usually with a rule such as outline none on links and buttons. That leaves keyboard users unable to see where they are. The modern answer is the focus-visible selector, which browsers apply to keyboard focus but generally not to mouse clicks. Add a clear focus-visible outline in Additional CSS or a child theme so keyboard users can follow their position.
6. How do I add alt text to images already used in old posts?
Changing the alt text in the media library only affects images inserted after the change, because each Image block stores its own copy of the alt text. For existing posts, open each post, select the image and edit the alt text in the block settings sidebar. Start with posts that get the most traffic and images that carry information, such as charts, product photos and linked images. Purely decorative images can keep empty alt text, which WordPress outputs correctly.
7. Do I need an accessibility statement on a WordPress site?
UK public sector websites must publish one under the 2018 accessibility regulations. For private businesses it is not usually a specific legal requirement, but it is good practice and shows you take the Equality Act duty to make reasonable adjustments seriously. A simple page explaining what standard you aim for, what you have tested, which parts are known not to meet it and how people can contact you for an alternative is enough. This is general guidance, not legal advice.
The Accessibility Audit tests your page against WCAG 2.2 level AA, lists each finding with the element that failed and the success criterion behind it, and links to the guide that fixes it.
Open Accessibility Fixes โ