Open Accessibility exposes a shared targeting layer plus filters for widget presentation. The goal is simple: let the plugin work across more WordPress themes without writing theme-specific hacks into the plugin itself.
The targeting layer arrived in 1.3.02. The presentation and skip-target filters described under Widget Presentation Filters were added in 1.4.0.
How Targeting Works
The frontend receives a normalized target configuration from PHP. JavaScript resolves those selectors into current DOM elements, excludes known unsafe areas, then applies feature controls to the resolved targets.
The main target groups are:
roots: content regions where controls are allowed to operate.readable_text: paragraphs, lists, blockquotes, captions, table cells, labels, and similar text.headings: heading elements.links: links inside allowed roots.media: media elements for image and visual controls.interactive: links, buttons, inputs, selects, textareas, summaries, and tabindex-enabled controls.layout_containers: opt-in containers eligible for layout relief.excluded: theme areas that should not be changed by target mutations.
PHP Filters
Use these filters when a theme needs global behavior.
Add A Content Root
add_filter( 'open_accessibility_target_roots', function( $roots ) {
$roots[] = '.my-theme-article-body';
return $roots;
} );
Exclude A Theme Region
add_filter( 'open_accessibility_target_excluded_selectors', function( $selectors ) {
$selectors[] = '.my-theme-sidebar';
$selectors[] = '.promo-card';
return $selectors;
} );
Add Layout Relief Targets
Use layout relief for containers that may clip larger text because of fixed height, overflow, or line clamping.
add_filter( 'open_accessibility_layout_relief_selectors', function( $selectors ) {
$selectors[] = '.my-theme-fixed-story-card';
return $selectors;
} );
Refine A Target Group
add_filter( 'open_accessibility_target_group_selectors', function( $selectors, $group_name ) {
if ( 'readable_text' === $group_name ) {
$selectors[] = '.my-theme-readable-copy';
}
return $selectors;
}, 10, 2 );
Take Complete Control
open_accessibility_target_config receives the final full targeting array before it is sent to the browser.
add_filter( 'open_accessibility_target_config', function( $config ) {
$config['roots'] = array( '.site-main-content' );
$config['groups']['readable_text'] = array( '.entry-copy', '.article-summary' );
$config['groups']['headings'] = array( '.entry-title', '.entry-copy h2' );
$config['excluded'][] = '.site-navigation';
return $config;
} );
Returning an empty selector array intentionally disables that default selector set:
add_filter( 'open_accessibility_target_config', function( $config ) {
$config['groups']['media'] = array();
return $config;
} );
If roots is empty, Open Accessibility does not fall back to document.body. A template can still opt a region back in with data-oa-root.
Widget Presentation Filters
These filters were added in 1.4.0 and control what the widget says and links to, rather than where controls apply.
Override Any Widget String
open_accessibility_strings receives the full array of widget labels.
add_filter( 'open_accessibility_strings', function( $strings ) {
$strings['reading_mask'] = __( 'Focus band', 'my-theme' );
return $strings;
} );
Change The Panel Title
The Panel Title setting covers most cases. Use the filter when the title needs to vary by context.
add_filter( 'open_accessibility_panel_title', function( $title ) {
if ( is_singular( 'product' ) ) {
return __( 'Product accessibility tools', 'my-theme' );
}
return $title;
} );
Adjust Panel Links
The Links settings tab populates Help, Feedback, Sitemap, and Statement links. Filter the resolved list to add, remove, or reorder them.
add_filter( 'open_accessibility_panel_links', function( $links ) {
$links[] = array(
'url' => home_url( '/accessibility-contact/' ),
'label' => __( 'Contact the accessibility team', 'my-theme' ),
);
return $links;
} );
Control Where Skip-To-Content Lands
As of 1.4.0 the skip link resolves a real target even on themes without an #content element, and moves keyboard focus to it. Use this filter to control the candidate list.
add_filter( 'open_accessibility_skip_target_candidates', function( $candidates ) {
array_unshift( $candidates, '#primary-article' );
return $candidates;
} );
Candidates are tried in order, and the first one present in the document wins.
HTML Attributes
Use HTML attributes for one-off template cases.
Add A Root
<main data-oa-root>
...
</main>
Add An Element To Target Groups
<article data-oa-target="readable_text headings">
<h2>Story title</h2>
<p>Readable story text.</p>
</article>
Ignore A Region
<aside data-oa-ignore>
This region will not be modified by Open Accessibility target mutations.
</aside>
The class alias also works:
<div class="open-accessibility-ignore">
Do not modify this region.
</div>
data-oa-ignore and .open-accessibility-ignore are built-in safety exclusions. They continue to work even if configurable exclusions are emptied.
Opt Into Layout Relief
<div class="story-card" data-oa-relax-layout>
<p>Text that may grow when a visitor increases text size.</p>
</div>
Preserve A Layout
<div data-oa-preserve-layout>
This region will stay out of layout relief.
</div>
JavaScript API
Open Accessibility exposes window.OpenAccessibility after the widget initializes.
window.OpenAccessibility.refresh();
window.OpenAccessibility.getState();
window.OpenAccessibility.setState({ textSize: 2 });
window.OpenAccessibility.getTargets('readable_text');
window.OpenAccessibility.debug();
Refresh After Dynamic Rendering
Use refresh() after AJAX, sliders, faceted search, or other frontend rendering changes.
document.addEventListener('myTheme:cardsRendered', function() {
window.OpenAccessibility.refresh();
});
Inspect Targets
const readableTargets = window.OpenAccessibility.getTargets('readable_text');
const diagnostics = window.OpenAccessibility.debug();
debug() returns current state and target counts, including invalid selectors.
Apply State
window.OpenAccessibility.setState({
textSize: 2,
lineHeightLevel: 1,
linksUnderline: true
});
The public state setter normalizes supported values before applying them. Malformed enum values are reset to safe defaults, and numeric levels are clamped to supported ranges.
Lifecycle Events
The plugin dispatches lifecycle events on document:
openAccessibility:readyopenAccessibility:targetsRefreshedopenAccessibility:beforeApplyopenAccessibility:afterApplyopenAccessibility:reset
Example:
document.addEventListener('openAccessibility:afterApply', function(event) {
console.log(event.detail.state);
console.log(event.detail.targets);
});
Browser Diagnostics
Enable browser-side diagnostics while testing:
localStorage.setItem('openAccessibilityDebug', '1');
location.reload();
Then inspect:
window.OpenAccessibility.debug();
Turn diagnostics back off:
localStorage.removeItem('openAccessibilityDebug');
location.reload();
Testing Checklist For Theme Integrations
After adding integration rules, test:
- Home page.
- Single post or article page.
- Archive or category page.
- Mobile viewport.
- Text size increase and reset.
- Line height increase and reset.
- Link underlining.
- Hide images.
- Reading guide.
- Reading mask.
- Skip to content, including keyboard focus landing on the intended target.
- Each contrast mode, confirming the widget itself stays reachable.
- Widget open, close, Escape key, and focus return.
Watch navigation, sidebars, ad containers, code blocks, and fixed-height cards. These are the most common places where whole-page accessibility controls can get spicy.