Accessibility
BladewindUI components carry their own ARIA roles and keyboard handling. You do not
switch this on and there is no accessible variant of a component to reach for. A
Tab is a real tablist, a
Toggle announces itself as a switch, and an
Accordion header answers to
Enter and Space because it is a
real disclosure button rather than a div that happens to be clickable.
This page describes what you get, and the few places where only you can supply the missing piece.
Keyboard Support
Every component below is reachable with Tab and operable
without a mouse.
| Component | Keys | Behaviour |
|---|---|---|
| Select | ↑ ↓ Home End Enter Esc Tab |
Arrows move the highlight, Home and
End jump to the ends of the list,
Enter selects, and
Esc or Tab closes.
Typing jumps to the first item that starts with what you typed.
|
| Tab | ← → Home End |
Left and right move between tabs and wrap around at the ends.
Only the selected tab sits in the page tab order, so
Tab moves past the tab strip rather than
through every tab in it. Disabled tabs are skipped.
|
| Accordion | Enter Space |
Opens and closes the section the header belongs to. |
| Checkcards | Enter Space |
Selects the focused card. These were previously reachable only with a mouse. |
| Rating | ← → ↑ ↓ Home End |
Right and up step the rating up, left and down step it down, and
Home and End jump to
0 and 5. Only a clickable rating is focusable. See
Rating below.
|
| Dropmenu | Enter Space |
Opens the menu from the trigger. |
| Slider | ← → |
Handled by the browser. The slider is a native range input, so it was
always operable. What it lacked was a name, which
aria_label now supplies.
|
What Each Component Reports
Roles and states are kept in step with what is actually on screen. Opening an accordion
section updates its aria-expanded, switching a tab updates
aria-selected, and moving the highlight in a select updates
aria-activedescendant. They cannot drift from the visible
state, including when opening one accordion item closes another.
| Component | Reported as |
|---|---|
| Select |
A combobox trigger with
aria-expanded, aria-required
and aria-disabled, over a
listbox of options.
The empty-state item is marked disabled so it is not offered as a choice.
|
| Dropmenu |
A button trigger with
aria-haspopup="menu", over a
menu of menuitems.
Headers are presentational and dividers are separators.
|
| Tab | tablist, tab and tabpanel, each tab tied to its panel both ways. |
| Accordion | A button header with aria-expanded, controlling a labelled region. |
| Toggle | switch with aria-checked. It was always a real checkbox, so it was operable; it just announced itself as the wrong kind of control. |
| Checkcards | A group of checkbox cards, each with aria-checked. |
| Rating | slider when clickable, img with a text alternative when not. See below. |
| Alert |
Errors and warnings are an assertive alert.
Info and success are a polite status, so a success
message does not interrupt whatever is being read.
|
| Notification | A polite status region on the container, since notifications are injected after the page has settled. |
Read-only And Clickable Ratings
A rating is two different controls depending on
clickable, and it reports itself accordingly.
A clickable rating is a focusable slider with
aria-valuemin, aria-valuemax and
aria-valuenow, operable with the arrow keys listed above.
A read-only rating is not focusable, because there is nothing to operate. It is
exposed as an image with a text alternative, so it reads as "4 out of 5" rather than
as five anonymous stars.
What You Need To Supply
Three things cannot be worked out from the markup, because only you know the answer.
Icon-only dropmenu triggers
The common dropmenu trigger is a bare icon, which reaches a screen reader as nothing at
all. Give it a name with trigger_label.
<x-bladewind::dropmenu trigger_label="Row actions">...</x-bladewind::dropmenu>
Icon-only buttons
A button with no visible text takes its accessible name from
title, which is the attribute most people
already set on these. An explicit aria-label always wins if
you would rather be exact.
<x-bladewind::button.circle title="Delete user" />
<x-bladewind::button.circle aria-label="Delete user" />
aria-label and no
visible text ships as an unlabelled control. Nothing can be derived from an icon name.Sliders
Slider takes an
aria_label. It defaults to a translatable
string, which is better than nothing but says nothing about what the slider adjusts.
Set it where you have more than one on a page.
<x-bladewind::slider aria_label="Maximum price" />
Keyboard Support Needs The JavaScript
Roles and states are rendered into the markup and are there whatever else happens. The
key handling is not: it lives in helpers.js, which every
component assumes, and in the per component scripts. If a component is reachable but
does not answer to the keys above, check that
@bladewindScripts is in your layout. See
First-time setup.
onclick. See
Content Security Policy.