Skip to content

Themes: Fix disabled button semantics and focus visibility in theme installer - #13390

Closed
SainathPoojary wants to merge 6 commits into
WordPress:trunkfrom
SainathPoojary:fix/66038
Closed

SainathPoojary wants to merge 6 commits into
WordPress:trunkfrom
SainathPoojary:fix/66038

Conversation

@SainathPoojary

Copy link
Copy Markdown
Member

This PR fixes two accessibility issues in the Theme Installer related to disabled buttons and focus visibility:

  1. Disabled semantics: Replaces the visual-only .disabled CSS class with proper semantic attributes (disabled for <button> elements, and aria-disabled="true" tabindex="-1" for <a> elements). This removes them from the tab order.
  2. Invisible focus ring: Updates the focus ring color to #fff for secondary buttons on the active theme card. Previously, the default focus ring color blended exactly with the theme name background, making it invisible when reached via keyboard.

Trac ticket: https://core.trac.wordpress.org/ticket/66038

Use of AI Tools

AI assistance: Yes
Tool(s): Github Copilot
Model(s): Claude Sonnet 4.6
Used for: Edge-case checks, and assistance with the PR description; implementation and testing were reviewed and verified by me.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions

github-actions Bot commented Sep 3, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props sainathpoojary, afercia, nicoblandel, joedolson.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

.theme-browser .theme.active .theme-actions .button:not(.button-primary):focus {
background: #fff;
box-shadow: 0 0 0 var(--wp-admin-border-width-focus, 1.5px) #fff;
outline: 1px solid transparent;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please compare with the 'Activate' button of the other cards and notice the focus style in Core uses a double box-shadow and a border. Using only a single box-shadow makes the thickness of the focus style inconsistent. Screenshot:

Image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @afercia! I just pushed a fix to match the double box-shadow and border of the Core styles. Appreciate the feedback.

image

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested the keyboard navigation and it works perfectly!

@afercia
afercia requested a review from joedolson September 11, 2026 10:30

@joedolson joedolson left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't note every instance, but these are inconsistent with some prior choices we've made elsewhere, making buttons that are disabled focusable, so that they information within them is still communicated. See https://core.trac.wordpress.org/ticket/39074, for example.

We should try and be consistent about this. I think the issue is still accurate here, since when in the theme browser, the only place that it's communicated that a theme is currently active is this disabled button.

That may be an argument that we need to add that to the notice that shows a theme is installed, as well. But I think we should try and make our patterns consistent, one way or the other.

Comment thread src/wp-admin/theme-install.php Outdated
<a class="button button-primary button-compact activate" href="{{ data.activate_url }}" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _e( 'Activate' ); ?></a>
<# } else { #>
<button class="button button-primary button-compact disabled"><?php _ex( 'Activated', 'theme' ); ?></button>
<button class="button button-primary button-compact disabled" disabled><?php _ex( 'Activated', 'theme' ); ?></button>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the disabled attribute is inconsistent with what we do elsewhere; we've generally tried to use aria-disabled and leave the button focusable, so that the content of the button is still communicated. This is the pattern we've followed in the dashboard widget mover buttons, for example.

Comment thread src/wp-admin/theme-install.php Outdated
?>
<# if ( data.activate_url ) { #>
<a class="button button-primary button-compact disabled" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _ex( 'Cannot Activate', 'theme' ); ?></a>
<a class="button button-primary button-compact disabled" aria-label="<?php echo esc_attr( $aria_label ); ?>" aria-disabled="true" tabindex="-1"><?php _ex( 'Cannot Activate', 'theme' ); ?></a>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly remove tabindex="-1"

@SainathPoojary

Copy link
Copy Markdown
Member Author

Done @joedolson. Switched all button elements to aria-disabled="true" instead of the native disabled attribute, and removed tabindex="-1" from the anchor elements so everything stays in the tab order.

One thing came up on the CSS side. The global .disabled class in buttons.css suppresses box-shadow with !important, which means these buttons now receive focus but have no visible focus ring. To fix this, I added rules in themes.css using !important to override the global styling and force the focus rings to show.

Does this approach make sense or is there any other way we can handle the focus ring here?

@joedolson

Copy link
Copy Markdown
Contributor

@SainathPoojary Another option would be to remove the .disabled class and attach the styles to [aria-disabled="true"], but that could introduce other complications. That's what's going on for the metabox mover buttons in the dashboard (common.css, .postbox .handle-order-higher[aria-disabled="true"], .postbox .handle-order-lower[aria-disabled="true"])

Overall, avoiding introducing !important is preferable, if possible. But if removing the class requires a ton of other changes, it may not be worth it.

If you change the class, make sure that all functionality is still properly nooped.

@joedolson

Copy link
Copy Markdown
Contributor

@afercia and I discussed this, and agreed that our preferred pattern is to use aria-disabled and leave the control focusable with disabled styles, like we currently use on the dashboard.

@afercia
afercia force-pushed the fix/66038 branch 2 times, most recently from 835aff0 to fe4f9ed Compare October 6, 2026 11:59
@afercia

afercia commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

I rebased on top of latest trunk.
Will post a comment on the Trac ticket as there is a decision that should be made.

@afercia

afercia commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

I pushed a commit to use aria-disabled buttons rather than links.

I'm not addressing the focus style for aria-disabled buttons and I think it should be addressed in a separate ticket / PR as it is a broader change that impacts all the styles from buttons.css, colors, with a few !important annotations.

@afercia afercia added the props-bot Adding this label triggers the Props Bot workflow for a PR. label Oct 8, 2026
@github-actions github-actions Bot removed the props-bot Adding this label triggers the Props Bot workflow for a PR. label Oct 8, 2026

@afercia afercia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

wporg-sync pushed a commit that referenced this pull request Oct 8, 2026
…sabled controls.

Most of the disabled controls in the Theme installer were rendered as `<a>` elements without a `href` attribute. Just a few of them were rendered as buttons when disabled. This change improves semantics, interaction, and accessibility by making all these controls buttons that are still focusable and that use `aria-disabled` instead of a `disabled` attribute.

Developed in #13390

Props sainathpoojary, arkaprabhachowdhury, sanayasir, kthibault, nicoblandel, joedolson, afercia.
Fixes #66038.


git-svn-id: https://develop.svn.wordpress.org/trunk@64243 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 64243
GitHub commit: 20ae9fa

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Oct 8, 2026
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 8, 2026
…sabled controls.

Most of the disabled controls in the Theme installer were rendered as `<a>` elements without a `href` attribute. Just a few of them were rendered as buttons when disabled. This change improves semantics, interaction, and accessibility by making all these controls buttons that are still focusable and that use `aria-disabled` instead of a `disabled` attribute.

Developed in WordPress/wordpress-develop#13390

Props sainathpoojary, arkaprabhachowdhury, sanayasir, kthibault, nicoblandel, joedolson, afercia.
Fixes #66038.

Built from https://develop.svn.wordpress.org/trunk@64243


git-svn-id: http://core.svn.wordpress.org/trunk@63394 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants