WidgetCoreWidgetCore Documentation

Accessibility

How WidgetCore meets accessibility requirements — the combobox pattern, ARIA roles, live regions, working without JavaScript, FAQ semantics, reduced motion, contrast and an audit checklist.

Accessibility in this plugin is not an extra layer: the markup, the keyboard behaviour and the ARIA attributes are built into every widget from the start. This page explains what is already handled and what you should check when you customise the output.

Live Search widget

The combobox pattern

The field follows the WAI-ARIA combobox pattern:

ElementAttributeMeaning
The inputrole="combobox"Announced as a combined field and list
The inputaria-expanded="true/false"Whether the results panel is open
The inputaria-controls="…-list"The id of the results list
The inputaria-autocomplete="list"Suggestions come from a list
The inputaria-activedescendant="…"The currently highlighted result
The results listrole="listbox"A selectable list
Each resultrole="option"A selectable item
The selected resultaria-selected="true"The highlighted option

Label and accessible name

Every field has an accessible name: a visible <label> when there is room, otherwise aria-label. The panel has aria-label too, and the results list is associated with the field through aria-controls.

Live regions

Two live regions keep screen readers informed without stealing focus:

Regionaria-liveAnnounces
The status textpolite“8 results found.”, “No results found.”
The page counterpolite“Page 2 of 5”

The results list itself is not a live region: announcing every list change would be noisy, so only the count is announced.

Working without JavaScript

The markup contains a real <form> that submits with GET to the site root:

html
<form class="wgcr-search-form" role="search" method="get" action="https://example.com/">
	<input type="search" name="s" class="wgcr-search-field" autocomplete="off">
	<input type="hidden" name="post_type" value="post">
	<button type="submit" class="wgcr-search-submit">Search</button>
</form>

Without JavaScript the submit button still works and the visitor lands on the theme's native search results page. This means the widget never becomes a dead end for assistive technology or for a visitor with scripts disabled.

FAQ widget

Semantic structure

ElementMarkupNotes
The questionA <button type="button"> inside a heading tagThe heading level is a control (H2/H3/H4/DIV)
The answer<div role="region" aria-labelledby="…">A navigable landmark region
The statearia-expanded="true/false" on the buttonAnnounced by screen readers
The connectionaria-controls and aria-labelledbyUnique per widget instance and item
The iconaria-hidden="true" on the SVGDecorative only

Closed state and focus

A closed answer is not merely visually hidden — it also leaves the tab order:

css
.wgcr-faq-a {
	overflow: hidden;
	max-height: 0;
	visibility: hidden;
}
.wgcr-faq-item.open .wgcr-faq-a {
	visibility: visible;
}

Using visibility (rather than only max-height) guarantees that links inside a closed answer cannot receive focus, so keyboard users never tab into invisible content.

Structured data

With the “FAQ schema” control on, the widget prints FAQPage JSON-LD. Two rules keep it valid:

  • Only items with both a question and an answer are included.
  • Only the first FAQ widget on a page prints schema, avoiding duplicate markup.

Reduced motion

All widgets respect prefers-reduced-motion:

css
@media (prefers-reduced-motion: reduce) {
	.wgcr-faq-a,
	.wgcr-faq-ic svg,
	.wgcr-search-panel,
	.wgcr-search-item {
		transition: none !important;
		animation: none !important;
	}
}
WidgetWith reduced motion
FAQItems open and close instantly; the icon does not rotate with a transition
Live SearchThe panel appears without a fade; infinite scroll still works

The behaviour stays complete — only the animation is removed. Nothing is hidden or disabled.

Colour contrast

The default palette was chosen for readable contrast:

PairRatioLevel
Result title (#0f172a) on whiteAbove 15:1AAA
Excerpt (#64748b) on whiteAbout 4.8:1AA
Placeholder (#94a3b8) on whiteAbout 2.9:1Decorative text only
FAQ question (#1F2937) on the cardAbove 13:1AAA
FAQ answer (#6B7280) on the cardAbout 5.0:1AA

The focus ring uses a 2px outline in the accent colour with outline-offset, giving at least 3:1 contrast against both the light and the dark backgrounds.

Text direction and layout

All layout rules use logical properties, so right-to-left and left-to-right both work from the same stylesheet:

Logical propertyInstead of
inset-inline-start / inset-inline-endleft / right
margin-inline / padding-inlinemargin-left / padding-right
border-inline-startborder-left
text-align: starttext-align: left

The icon position, the panel alignment and the pagination order therefore flip correctly on an RTL site without a second stylesheet.

Markup when customising

If you build a custom Elementor template for results, keep these attributes:

KeepWhy
role="option" on each resultSo aria-activedescendant keeps working
A focusable link inside the resultSo Enter opens the result
Text alternatives for imagesA meaningful alt, or alt="" when decorative
The heading level of the titleSo the results fit the page outline

The plugin wraps whatever your template prints, so the list roles stay intact; but a result with no link cannot be opened from the keyboard.

Publishing checklist

  1. Test with the keyboard only

    Tab through the field, open results with ArrowDown and Enter, close with Escape.

  2. Test with a screen reader

    Check that the field name, the result count and the FAQ state are announced.

  3. Test without JavaScript

    The search form must still submit and the FAQ must still open (details/summary fallback or the CSS cap).

  4. Check contrast

    Every text pair you changed should meet at least 4.5:1.

  5. Check reduced motion

    Enable the OS setting and confirm nothing animates.

  6. Validate the schema

    Run the page through the Rich Results Test.

Keyboard details for each widget are on the keyboard shortcuts page.