We'd like to set Google Analytics cookies to learn how people use the Knowledge Base, so we can improve it. We set them only if you accept.

Skip to main content
Digital Accessibility Knowledge Base

Toggle Button

UI pattern

A toggle button activates a mode or condition when pressed. An accessible toggle button carries the button role, a fixed name, and an aria-pressed state that changes when users click it or press Enter or Space.

A toggle button toggles between pressed and not-pressed states, activating a mode or condition when it's pressed and deactivating it when it's not pressed. For example, a "Line numbers" button in a code editor shows line numbers when it's pressed and hides them when it's not.

A toggle button can have a mixed state. For example, selected text could have a mix of bold and regular font weights. Activating a "Bold" button either sets bold for all of it or removes bold from all of it, regardless of the initial mix.

A toggle button in a web interface is modeled after a push button that stays pressed until it's pressed again. Its visual presentation is typically compact, showing one style for its pressed state and another for its not-pressed state, which makes it a good choice for use in a toolbar.

Other controls can also activate and deactivate a mode or condition, but with different semantics. The following table compares them, using a media player's play control as the example.

Toggle buttonCommand buttonSwitch
NameNames the state: "Playing"Names the command: "Play", then "Pause"Names the state: "Playing"
Name changes when pressedNoYesNo
Rolebuttonbuttonswitch
State attributearia-pressed: true, false, or mixedNonearia-checked: true or false
Visual presentationPressed and not-pressed stylesThe icon or text changes with the commandOn and off styles, often with "On" and "Off" text

While these controls can perform the same function, choose the one whose semantics match the visual design and provide the best user experience. Their UI patterns are listed in Related Patterns.

Other than its requirement to convey its pressed state, a toggle button has the same accessibility requirements as any other button.

When to Use

Use a toggle button when:

  • Its purpose is to immediately set or reset a condition or mode, such as a "Bold" button that sets and removes bold font on selected text.
  • The visual design of the button models that of a push button with separate pressed and not-pressed presentations.

Do not use a toggle button when:

  • Its name changes with the command it performs, such as "Play" and "Pause". Use a command button instead.
  • An on-off switch better fits the semantics and visual design.
  • A checkbox that lets users select a value or option to take effect after a subsequent submit, save, or confirm action is a better fit.
  • The button controls a related element that can be expanded or collapsed. In that case, use a button with aria-expanded rather than aria-pressed.

Examples

Code in this section is meant to demonstrate techniques rather than requirements and lacks features needed in a production application.

The following examples show a toggle button that can start in a mixed state, then a command button for comparison. Both use the native HTML <button> element. Refer to Button › Examples for requirements when a custom button is used as a base.

Changing State with a Toggle Button

A common example of a toggle button that can have a mixed state is a "Bold" button in a text editor that changes the state of selected text.

If the selected text contains a mix of bold and regular weights, the button should set aria-pressed to mixed so screen reader users know about the mix.

Activating the button in the mixed state could change all selected text to either bold or regular (that's a design decision), but aria-pressed must reflect the resulting state. Subsequent activations change the font weight and the aria-pressed value but do not change the label.

Bold button states HTML
HTML
<!-- when selected text is a mix of regular and bold weights -->
<button
    class="toolbar-button"
    aria-pressed="mixed"
    aria-label="Bold">B</button>


<!-- when all selected text is regular weight -->
<button
    class="toolbar-button"
    aria-pressed="false"
    aria-label="Bold">B</button>


<!-- when all selected text is bold -->
<button
    class="toolbar-button"
    aria-pressed="true"
    aria-label="Bold">B</button>

Changing State with a Command Button

A command button names the command it performs and changes its name when the state changes, so it doesn't carry aria-pressed. A common example is a "Play/Pause" button for a media player, where the name identifies the command rather than the state of the player.

Play/Pause button HTML
HTML
<!-- media player not playing -->
<button
    class="player-button"
    aria-label="Play">â–¶</button>


<!-- media player playing -->
<button
    class="player-button"
    aria-label="Pause">▮▮</button>

Structure and Semantics

A toggle button extends the semantics of a button by setting the ARIA attribute aria-pressed with the value true, false, or mixed. When the button controls several items that don't all share one state, such as selected text in mixed weights, it sets aria-pressed="mixed".

Activating a toggle button in the false state changes it to the true (pressed) state, and activating it in the true state changes it to the false (not pressed) state. Activating it in the mixed state changes it to either true or false, whichever the design chooses.

In any button state, its accessible name remains the same, indicating the mode or condition the button controls.

Without aria-pressed, assistive technologies report a plain button. A button that toggles a state without it is a command button, and its name identifies a command that changes the state when it's activated.

Refer to Button › Structure and Semantics for more information about button semantics.

Role

A toggle button must expose the button role to assistive technology so that users know its purpose and how they can interact with it.

The HTML <button> and <input type="button"> elements expose the button role implicitly, requiring no additional ARIA. When you can't use them, build a custom toggle button from a generic element, such as a <div> or <span>, that has no role or state of its own, and set role="button" on it.

Without its button role, screen readers announce it as plain, non-interactive content or, with a different role, as the wrong kind of element. Users won't know its purpose or how to interact with it.

Has the correct role

Reported as: Element has incorrect role

A toggle button must carry the button role.

When a toggle button built from a <div> or <span> has no role, or carries another one, screen readers don't announce it as a toggle button even when it sets aria-pressed, and users can't tell they can press it.

Use a <button> element, or set role="button" on a custom toggle button.

Severity: Critical

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Applies role to the correct element

Reported as: Incorrect root element

Sanity check. Evinced checks that the button role sits on the selected element, the one users focus and press, rather than on one of its descendants. This check runs on every UI pattern, not only on toggle buttons.

The button role should sit on the same element that receives focus, carries aria-pressed, and handles activation.

When the role sits on a descendant while a wrapper takes focus or handles the click, screen readers announce a button that isn't the element users operate, and they may not hear its pressed state.

Put the role, the accessible name, aria-pressed, the ability to focus, and the activation handling on that one element, and keep any wrapper free of roles and handlers.

Button Name

Like any other button, a toggle button must have an accessible name. Without a meaningful name, screen readers announce only "button," and users can't know what it does or tell it apart from other buttons.

The name of a toggle button should tell what condition the button toggles rather than the action the button performs and should stay fixed when the button is toggled. Its activation state changes when toggled, not its name.

A command button, which has no aria-pressed, is named for the command it performs, and its name changes when the command does.

Has an accessible name

Reported as: Accessible name

A toggle button must have an accessible name that identifies the mode or condition it controls.

When an icon-only toggle button, such as a toolbar "B" for bold, has no text alternative, screen readers announce only "toggle button, pressed" or "not pressed," and users can't tell what is turned on.

Give the button a name through visible text, an image's alt text, or an aria-label attribute.

Severity: Critical

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.

aria-pressed

A toggle button conveys its pressed state through aria-pressed. A command button conveys its state through a name that changes instead, so it doesn't carry aria-pressed.

Declares its current state

Reported as: No toggle indicator

A toggle button must declare its current state with aria-pressed.

When the pressed look comes from a CSS class and aria-pressed is missing, assistive technologies report a plain button. Screen reader users can't tell that it toggles, whether the mode is on, or whether their press took effect.

Set aria-pressed to true, false, or mixed when the button first renders. Use mixed only when the button controls several items that don't all share one state.

Severity: Critical

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Uses a defined state value

Reported as: Invalid toggle attribute value

The aria-pressed attribute on a toggle button must be set to a recognized value: true, false, or mixed.

When aria-pressed carries a value the spec doesn't define, such as "checked", "on", "yes", or an empty string, browsers and assistive technology ignore it or assume a default of their own, so screen reader users can be told the button isn't pressed, or hear it as a plain button, whatever it shows.

Set it to true when the button is pressed, false when it's not, and mixed only when the button represents a group of two-state items whose individual states don't all match.

Severity: Moderate

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.

Color Alone State Indication

A toggle button keeps the same label whether it's pressed or not, so its appearance is what tells sighted users the state. That change must go beyond color, such as a thicker or inset border, a filled rather than outlined icon, or a checkmark beside the label.

Shows state by more than color

Reported as: State indicated by color alone

A toggle button must show whether it's pressed with a visual change other than color.

When the only difference between states is the button's background or text color, such as a "Bold" button that turns blue when pressed, people with color vision deficiency or low vision, or using a high-contrast display, can't tell whether the mode is on. Exposing the state to assistive technology doesn't help, because most of these users don't use any.

Add a cue that changes with aria-pressed, such as a thicker or inset border, a filled icon, or a checkmark, and keep any color change alongside it. Whatever tells the states apart needs a contrast of at least 3:1 with the colors around it. Draw the cue with an SVG, a border, or text rather than a CSS background color, which high-contrast modes can remove.

Severity: Serious

StandardSuccess CriterionReference
WCAG 2.21.4.1 Use of Color (A)Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.

Disabled

Like any button, a toggle button must convey its disabled state to assistive technologies.

Avoids conflicting disabled states

Reported as: Conflicting disabled values

A toggle button must declare its disabled state one way only: the disabled attribute on a native <button>, or aria-disabled on a custom toggle button.

When a native button carries aria-disabled instead of disabled, it stays operable and in the tab order while assistive technology reports it as disabled. When both attributes are set and disagree, assistive technology can report a state the browser doesn't enforce. Either way, screen reader users are told the wrong thing about whether the button works.

Use disabled alone on a native <button> and aria-disabled alone on a custom toggle button, removing it or setting it to false when the button is enabled again.

Severity: Serious

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Uses aria-disabled rather than disabled

Reported as: Element does not support the disabled attribute

A toggle button built from an element that doesn't support the disabled attribute must convey its disabled state with aria-disabled instead.

When disabled is set on a custom toggle button built from a <div> or <span>, browsers ignore it. The button looks unavailable but still toggles, and assistive technology doesn't report it as disabled, so users can change a mode that's meant to be locked.

Set aria-disabled="true", and block activation in the button's event handlers while it's set.

Severity: Serious

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Disables only elements that support it

Reported as: Element type does not support disabled state

An element in a toggle button must carry disabled or aria-disabled only when its role supports a disabled state.

When the state sits on an element whose role has none, such as a wrapper, a list item or a heading, assistive technology may drop it or report it on something users can't operate, while the control that really is unavailable is still reported as available.

Remove the attribute from that element, and set the disabled state on the control itself, using an element or role that supports it, such as a native <button>.

Severity: Serious

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.

Forbidden Interactive Children

A toggle button, like any button, must not contain other interactive elements. Nested interactive elements create ambiguity for all users because they can't be certain which element will respond to their interaction.

Avoids nested interactives

Reported as: Forbidden interactive children; Nested interactive elements

A toggle button must not contain or be nested inside another interactive element, such as a link or another button.

A toggle button's children are presentational, so a control nested inside it can't be perceived or operated as a control by screen reader users, and pointer users can't tell whether a click toggles the button or operates the nested control.

Place any other control beside the toggle button, not inside it.

Severity: Serious

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.

Relationships

A toggle button is a single, self-contained button with no internal structure of its own. When a toggle button's state controls a related element elsewhere on the page, it's appropriate to set aria-controls pointing to that element's id so assistive technologies can convey the relationship.

aria-owns

The attribute aria-owns conveys a parent-child relationship, which is never appropriate for a button. A button can control but can't own another element. Elements contained within a button are presentational. Only its text content is exposed to assistive technologies.

Avoids aria-owns

Reported as: Avoid aria-owns

General check. Evinced checks that the toggle button doesn't use aria-owns to claim elements elsewhere in the document as its children. This check runs on every UI pattern, not only on toggle buttons.

A toggle button should not use aria-owns.

When a toggle button owns an element, such as the content its state affects, that element becomes a presentational child of the button. Assistive technology users perceive it only as part of the button's name and can't operate anything interactive inside it.

Remove aria-owns and keep the content outside the button. When the button affects that content, reference it with aria-controls instead.

Operation

Like any button, a toggle button must be operable with both a pointer and a keyboard. Clicking or tapping the button activates it. On a keyboard, the Tab key moves focus to and away from a button, and pressing Enter or Space activates it. Semantic HTML buttons provide this keyboard behavior automatically.

A custom toggle button built with role="button" must reproduce that behavior: Add tabindex="0" so the element joins the tab order, and add event listeners to enable activation with the Enter or Space key. By convention, a button is activated on an Enter keydown event and a Space keyup event.

Focus Sequence

A toggle button must be in the tab order and reachable with the Tab key when it's enabled, and removed from the tab order when it's disabled.

Reachable by keyboard

Reported as: Keyboard accessible

A toggle button must be reachable in the keyboard tab order.

When a toggle button is built from markup that isn't focusable, such as a <div> or <span>, pointer users can press it, but keyboard users can't reach it to change the mode it controls.

A native <button> element is focusable by default. Give a custom toggle button tabindex="0".

Severity: Critical

StandardSuccess CriterionReference
WCAG 2.22.1.1 Keyboard (A)All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.
EN 301 5499.2.1.1 KeyboardSame as the WCAG text.
Section 5081194.21(a)When software is designed to run on a system that has a keyboard, product functions shall be executable from a keyboard where the function itself or the result of performing a function can be discerned textually.
508 Trusted Tester2.1.1-keyboard-access, 4.AAll functionality can be accessed and executed using only the keyboard.
Skips tab order when disabled

Reported as: Disabled element focusable

A disabled toggle button should not be a stop in the tab order.

When a disabled toggle button stays in the tab order, keyboard users land on a control they can't press. Screen reader users are told it's disabled, but the tab stop gives them nothing to do.

A native <button> with disabled leaves the tab order on its own. For a custom toggle button, set tabindex="-1" while aria-disabled="true" is set, and tabindex="0" when it's enabled.

Severity: Minor

This issue is classified as "Best Practice," meaning it isn't tied to a specific WCAG success criterion or any other regulation or standard; however it still affects the experience of some users. These issues fall outside formal compliance requirements, yet addressing them improves usability and accessibility in practice.
Element that carries the role receives focus

Reported as: Focusable offset

The element that carries the button role and aria-pressed must be the element that receives focus, not one of its descendants.

When a descendant takes focus instead, screen readers announce that element rather than the toggle button and its pressed state, and keyboard users may not be able to toggle it with Enter or Space.

Set tabindex="0" on the element that carries the role, and on no element inside it.

Severity: Minor

StandardSuccess CriterionReference
WCAG 2.22.1.1 Keyboard (A)All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.
EN 301 5499.2.1.1 KeyboardSame as the WCAG text.
Section 5081194.21(a)When software is designed to run on a system that has a keyboard, product functions shall be executable from a keyboard where the function itself or the result of performing a function can be discerned textually.
508 Trusted Tester2.1.1-keyboard-access, 4.AAll functionality can be accessed and executed using only the keyboard.

Keyboard Activation

A toggle button, like any button, activates with either Enter or Space when it has focus, and each activation toggles its pressed state. A native <button> responds to both keys without any code. A custom toggle button built with role="button" gets neither, so code must activate it on an Enter keydown event and a Space keyup event.

Operable by keyboard

Reported as: Button not activated by keyboard

Keyboard users must be able to activate a toggle button.

When a custom toggle button handles only the click event, pointer users can turn its mode on and off, but keyboard users can focus it and still can't change anything.

Use a native <button>, or add key handlers that toggle a custom button through the same code path as a click.

Severity: Critical

StandardSuccess CriterionReference
WCAG 2.22.1.1 Keyboard (A)All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.
EN 301 5499.2.1.1 KeyboardSame as the WCAG text.
Section 5081194.21(a)When software is designed to run on a system that has a keyboard, product functions shall be executable from a keyboard where the function itself or the result of performing a function can be discerned textually.
508 Trusted Tester2.1.1-keyboard-access, 4.AAll functionality can be accessed and executed using only the keyboard.
Ignores keyboard when disabled

Reported as: Disabled button keyboard activation

A toggle button that reports itself as disabled should not respond to Enter or Space.

When a custom toggle button carries aria-disabled="true" but its key handlers still run, screen reader users are told it's unavailable and then hear its state change, so they can't trust either signal.

Use a native <button> with disabled, which blocks activation automatically. For a custom toggle button, return from the key handlers while aria-disabled="true" is set.

Severity: Serious

This issue is classified as "Best Practice," meaning it isn't tied to a specific WCAG success criterion or any other regulation or standard; however it still affects the experience of some users. These issues fall outside formal compliance requirements, yet addressing them improves usability and accessibility in practice.
Activates with Enter and Space

Reported as: Button requires space key activation

A custom toggle button must activate with both Enter and Space, as a <button> element does.

When a toggle button answers only one of the two keys, users who press the other, as they would on any other button, conclude it's unresponsive.

Activate a custom toggle button on an Enter keydown event and a Space keyup event, or use a native <button>.

Severity: Minor

StandardSuccess CriterionReference
WCAG 2.22.1.1 Keyboard (A)All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.
EN 301 5499.2.1.1 KeyboardSame as the WCAG text.
Section 5081194.21(a)When software is designed to run on a system that has a keyboard, product functions shall be executable from a keyboard where the function itself or the result of performing a function can be discerned textually.
508 Trusted Tester2.1.1-keyboard-access, 4.AAll functionality can be accessed and executed using only the keyboard.

Toggle Activation

Like any button, a toggle button must be operable by all users, by clicking with a pointing device or by pressing either the Enter or Space key when the button has keyboard focus. A toggle button must also convey the current activation state of the mode or condition it controls.

A toggle button sets aria-pressed="true" when it activates the condition and aria-pressed="false" when it deactivates it, and its name stays the same.

A command button doesn't set aria-pressed. Instead, it changes its name to identify the command it performs, such as "Play" or "Pause".

Updates state or name when pressed

Reported as: Toggle state not updated

A button that toggles a state must report every press, either through aria-pressed on a toggle button or through the name of a command button.

When a press changes neither, screen reader users aren't told that anything happened and can't tell what state the button is in, so they may press it again and undo what they meant to do.

On a toggle button, toggle aria-pressed between true and false and keep the name fixed. On a command button, change the name to the command it now performs. Handle pointer and keyboard activation through one code path.

Severity: Critical

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Updates aria-pressed when pressed

Reported as: Element's state did not change

Activating a toggle button that carries aria-pressed, with a pointer or the keyboard, must update aria-pressed to its new state.

When aria-pressed keeps its starting value, assistive technology reports the old state after every press. A screen reader user who turns on "Bold" hears no change and, returning to the button later, is told it's still not pressed.

Update aria-pressed in the code that toggles the button's state, and handle pointer and keyboard activation through that one code path.

Evinced reports this issue as Critical or as Serious, depending on the context where it shows up.

Severity: Critical

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Returns to its earlier state

Reported as: Toggle state not resetting

Activating a toggle button twice must return its reported state to where it started. A toggle button toggles both the mode or condition it controls and its reported state.

If the reported state stays the same or changes to yet another value on the next activation, users can't tell what the button does and can't set or reset the condition or mode it controls.

Evinced reports this issue as Critical or as Serious, depending on the context where it shows up.

Severity: Critical

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Changes state or name, not both

Reported as: Toggle button overlapping changes

Activating a toggle button must change its aria-pressed value without changing its accessible name.

When the button updates aria-pressed and swaps its name on the same activation, a screen reader announces something inconsistent, such as "Pause, pressed," that can confuse users about the actual state.

Keep the name fixed and let aria-pressed carry the state. If the name has to change, make it a command button by removing aria-pressed.

Severity: Serious

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Keeps a stateful name in step

Reported as: Toggle name not resetting

A command button, which has no aria-pressed, must change its accessible name every time it's activated.

When a "Play" button becomes "Pause" on the first press and then keeps that name, the name contradicts the player's state. Screen reader users hear "Pause" while nothing is playing, and voice control users who say the name they see may not reach the button.

Compute the name from the current state every time the state changes, rather than setting it once. Or make it a toggle button: Keep the name fixed and let aria-pressed carry the state.

Severity: Serious

StandardSuccess CriterionReference
WCAG 2.24.1.2 Name, Role, Value (A)For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to assistive technologies.
EN 301 5499.4.1.2 Name, Role, ValueSame as the WCAG text.
Section 5081194.21(d)Sufficient information about a user interface element including the identity, operation and state of the element shall be available to assistive technology. When an image represents a program element, the information conveyed by the image must also be available in text.
Ignores activation when disabled

Reported as: Disabled element active

A toggle button that presents as disabled must not change state when it's activated.

When a button is styled as unavailable, or carries aria-disabled="true", but its click and key handlers are enabled, activating it still changes the state. Users are told the button isn't available and then find it responds, leaving them unable to trust either signal.

Check the disabled state at the start of the handler and return without changing anything, covering both the pointer and keyboard paths. For a native button, using the HTML disabled attribute prevents activation in the browser without any additional code.

Severity: Moderate

StandardSuccess CriterionReference
WCAG 2.21.3.1 Info and Relationships (A)Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.
EN 301 5499.1.3.1 Info and RelationshipsSame as the WCAG text.

Event Listener Type

When script in a toggle button responds to keys, it listens for keydown or keyup. The keypress event is deprecated, and browsers don't fire it for many keys, including the arrow keys, Home, End and Escape.

Avoids the keypress event

Reported as: Deprecated keypress listener

A toggle button's key handling should use keydown or keyup, not keypress.

When a handler listens for keypress, keys the browser doesn't send through that event go unanswered, and keyboard users find the toggle button ignoring keys it's meant to respond to.

Replace each keypress listener with a keydown listener, and read the key from event.key.

Severity: Minor

This issue is classified as "Best Practice," meaning it isn't tied to a specific WCAG success criterion or any other regulation or standard; however it still affects the experience of some users. These issues fall outside formal compliance requirements, yet addressing them improves usability and accessibility in practice.

FAQ

Which WCAG success criteria do the toggle button issues relate to?

Most toggle button issues relate to 4.1.2 Name, Role, Value: the button role, an accessible name, a valid aria-pressed state that follows each activation, a name that stays fixed while the state changes, a correctly conveyed disabled state, and no nested interactive elements.

Reaching the button by keyboard, focus landing on the element that carries the role, and activating it with Enter and Space relate to 2.1.1 Keyboard. Showing the pressed state by more than color relates to 1.4.1 Use of Color, and a disabled toggle button that still changes state relates to 1.3.1 Info and Relationships.

Two criteria map to no WCAG success criterion and are best practices: removing a disabled toggle button from the tab order, and ignoring the keyboard when it's disabled.

Why are some toggle button issues marked as Critical and others as Minor?

Severity reflects how much an issue gets in users' way. Critical issues stop users outright: a toggle button with no role, name, or declared state, one keyboard users can't reach or activate, or one whose reported state doesn't follow activation.

Serious issues confuse users though tasks are still possible, such as showing the state by color alone, a wrong disabled state, nested controls, a name that changes along with the state, a command button's name that stops changing, or a disabled button that still responds to the keyboard.

An invalid aria-pressed value, or a disabled toggle button that still changes state, is Moderate. A custom toggle button that ignores Enter or Space, focus that lands inside the button rather than on it, or a disabled button left in the tab order is Minor.

The aria-owns check and the check on where the role sits carry no severity: Evinced reports them as a general check and a sanity check.

  • Button: performs an action, including a command button that changes its name to toggle a state, and covers the requirements every toggle button shares
  • Switch: carries the switch role and reports on or off with aria-checked, with no mixed state
  • Checkbox: selects an option, usually for a later submit, and can be mixed
  • Disclosure: a button that shows and hides content, with its state conveyed by aria-expanded rather than aria-pressed