Themes: Fix accessibility issues with controls in themes screen.

Add accessible names to several theme controls so provide better context for screen reader users. Change theme details element into a button that can receive focus. Ensure focus is set back on existing theme when theme details modal is closed.

props alexstine, poena.
Fixes #52649.
Built from https://develop.svn.wordpress.org/trunk@51083


git-svn-id: http://core.svn.wordpress.org/trunk@50692 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
joedolson 2021-06-07 23:10:57 +00:00
parent 47fb9c7f3d
commit 637282bb0f
8 changed files with 75 additions and 43 deletions

View File

@ -67,7 +67,7 @@ body.js .theme-browser.search-loading {
}
.theme-browser .theme:hover,
.theme-browser .theme:focus {
.theme-browser .theme.focus {
cursor: pointer;
}
@ -96,8 +96,7 @@ body.js .theme-browser.search-loading {
}
.theme-browser .theme:hover .theme-actions,
.theme-browser .theme.focus .theme-actions,
.theme-browser .theme:focus .theme-actions {
.theme-browser .theme.focus .theme-actions {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
opacity: 1;
}
@ -141,12 +140,12 @@ body.js .theme-browser.search-loading {
}
.theme-browser .theme:hover .theme-screenshot,
.theme-browser .theme:focus .theme-screenshot {
.theme-browser .theme.focus .theme-screenshot {
background: #fff;
}
.theme-browser.rendered .theme:hover .theme-screenshot img,
.theme-browser.rendered .theme:focus .theme-screenshot img {
.theme-browser.rendered .theme.focus .theme-screenshot img {
opacity: 0.4;
}
@ -157,6 +156,7 @@ body.js .theme-browser.search-loading {
top: 35%;
left: 20%;
right: 20%;
width: 60%;
background: #1d2327;
background: rgba(0, 0, 0, 0.7);
color: #fff;
@ -170,22 +170,26 @@ body.js .theme-browser.search-loading {
transition: opacity 0.1s ease-in-out;
}
.theme-browser .theme:focus {
.theme-browser .theme .more-details:focus {
box-shadow: 0 0 0 1px #fff, 0 0 0 3px #2271b1;
}
.theme-browser .theme.focus {
border-color: #4f94d4;
box-shadow: 0 0 2px rgba(79, 148, 212, 0.8);
}
.theme-browser .theme:focus .more-details {
.theme-browser .theme.focus .more-details {
opacity: 1;
}
/* Current theme needs to have its action always on view */
.theme-browser .theme.active:focus .theme-actions {
.theme-browser .theme.active.focus .theme-actions {
display: block;
}
.theme-browser.rendered .theme:hover .more-details,
.theme-browser.rendered .theme:focus .more-details {
.theme-browser.rendered .theme.focus .more-details {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
opacity: 1;
}
@ -878,12 +882,12 @@ body.folded .theme-browser ~ .theme-overlay .theme-wrap {
.theme:not(.active):hover .theme-actions,
.theme:not(.active):focus .theme-actions,
.theme:hover .more-details,
.theme:focus .more-details {
.theme.focus .more-details {
display: none;
}
.theme-browser.rendered .theme:hover .theme-screenshot img,
.theme-browser.rendered .theme:focus .theme-screenshot img {
.theme-browser.rendered .theme.focus .theme-screenshot img {
opacity: 1.0;
}
}

File diff suppressed because one or more lines are too long

View File

@ -66,7 +66,7 @@ body.js .theme-browser.search-loading {
}
.theme-browser .theme:hover,
.theme-browser .theme:focus {
.theme-browser .theme.focus {
cursor: pointer;
}
@ -95,8 +95,7 @@ body.js .theme-browser.search-loading {
}
.theme-browser .theme:hover .theme-actions,
.theme-browser .theme.focus .theme-actions,
.theme-browser .theme:focus .theme-actions {
.theme-browser .theme.focus .theme-actions {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
opacity: 1;
}
@ -140,12 +139,12 @@ body.js .theme-browser.search-loading {
}
.theme-browser .theme:hover .theme-screenshot,
.theme-browser .theme:focus .theme-screenshot {
.theme-browser .theme.focus .theme-screenshot {
background: #fff;
}
.theme-browser.rendered .theme:hover .theme-screenshot img,
.theme-browser.rendered .theme:focus .theme-screenshot img {
.theme-browser.rendered .theme.focus .theme-screenshot img {
opacity: 0.4;
}
@ -156,6 +155,7 @@ body.js .theme-browser.search-loading {
top: 35%;
right: 20%;
left: 20%;
width: 60%;
background: #1d2327;
background: rgba(0, 0, 0, 0.7);
color: #fff;
@ -169,22 +169,26 @@ body.js .theme-browser.search-loading {
transition: opacity 0.1s ease-in-out;
}
.theme-browser .theme:focus {
.theme-browser .theme .more-details:focus {
box-shadow: 0 0 0 1px #fff, 0 0 0 3px #2271b1;
}
.theme-browser .theme.focus {
border-color: #4f94d4;
box-shadow: 0 0 2px rgba(79, 148, 212, 0.8);
}
.theme-browser .theme:focus .more-details {
.theme-browser .theme.focus .more-details {
opacity: 1;
}
/* Current theme needs to have its action always on view */
.theme-browser .theme.active:focus .theme-actions {
.theme-browser .theme.active.focus .theme-actions {
display: block;
}
.theme-browser.rendered .theme:hover .more-details,
.theme-browser.rendered .theme:focus .more-details {
.theme-browser.rendered .theme.focus .more-details {
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
opacity: 1;
}
@ -877,12 +881,12 @@ body.folded .theme-browser ~ .theme-overlay .theme-wrap {
.theme:not(.active):hover .theme-actions,
.theme:not(.active):focus .theme-actions,
.theme:hover .more-details,
.theme:focus .more-details {
.theme.focus .more-details {
display: none;
}
.theme-browser.rendered .theme:hover .theme-screenshot img,
.theme-browser.rendered .theme:focus .theme-screenshot img {
.theme-browser.rendered .theme.focus .theme-screenshot img {
opacity: 1.0;
}
}

File diff suppressed because one or more lines are too long

View File

@ -404,11 +404,7 @@ themes.view.Theme = wp.Backbone.View.extend({
var data = this.model.toJSON();
// Render themes using the html template.
this.$el.html( this.html( data ) ).attr({
tabindex: 0,
'aria-describedby' : data.id + '-action ' + data.id + '-name',
'data-slug': data.id
});
this.$el.html( this.html( data ) ).attr( 'data-slug', data.id );
// Renders active theme styles.
this.activeTheme();
@ -764,7 +760,7 @@ themes.view.Details = wp.Backbone.View.extend({
// Return focus to the theme div.
if ( themes.focusedTheme ) {
themes.focusedTheme.trigger( 'focus' );
themes.focusedTheme.find('.more-details').trigger( 'focus' );
}
});
}
@ -952,7 +948,7 @@ themes.view.Preview = themes.view.Details.extend({
// Return focus to the theme div.
if ( themes.focusedTheme ) {
themes.focusedTheme.trigger( 'focus' );
themes.focusedTheme.find('.more-details').trigger( 'focus' );
}
}).removeClass( 'iframe-ready' );

File diff suppressed because one or more lines are too long

View File

@ -370,7 +370,7 @@ foreach ( $themes as $theme ) :
$active_class = ' active';
}
?>
<div class="theme<?php echo $active_class; ?>" tabindex="0" aria-describedby="<?php echo $aria_action . ' ' . $aria_name; ?>">
<div class="theme<?php echo $active_class; ?>">
<?php if ( ! empty( $theme['screenshot'][0] ) ) { ?>
<div class="theme-screenshot">
<img src="<?php echo $theme['screenshot'][0]; ?>" alt="" />
@ -503,7 +503,11 @@ foreach ( $themes as $theme ) :
}
?>
<span class="more-details" id="<?php echo $aria_action; ?>"><?php _e( 'Theme Details' ); ?></span>
<?php
/* translators: %s: Theme name. */
$details_aria_label = sprintf( _x( 'View Theme Details for %s', 'theme' ), $theme['name'] );
?>
<button type="button" aria-label="<?php echo esc_attr( $details_aria_label ); ?>" class="more-details" id="<?php echo $aria_action; ?>"><?php _e( 'Theme Details' ); ?></button>
<div class="theme-author">
<?php
/* translators: %s: Theme author name. */
@ -522,8 +526,12 @@ foreach ( $themes as $theme ) :
<div class="theme-actions">
<?php if ( $theme['active'] ) { ?>
<?php if ( $theme['actions']['customize'] && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { ?>
<a class="button button-primary customize load-customize hide-if-no-customize" href="<?php echo $theme['actions']['customize']; ?>"><?php _e( 'Customize' ); ?></a>
<?php
if ( $theme['actions']['customize'] && current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
/* translators: %s: Theme name. */
$customize_aria_label = sprintf( _x( 'Customize %s', 'theme' ), $theme['name'] );
?>
<a aria-label="<?php echo esc_attr( $customize_aria_label ); ?>" class="button button-primary customize load-customize hide-if-no-customize" href="<?php echo $theme['actions']['customize']; ?>"><?php _e( 'Customize' ); ?></a>
<?php } ?>
<?php } elseif ( $theme['compatibleWP'] && $theme['compatiblePHP'] ) { ?>
<?php
@ -531,8 +539,12 @@ foreach ( $themes as $theme ) :
$aria_label = sprintf( _x( 'Activate %s', 'theme' ), '{{ data.name }}' );
?>
<a class="button activate" href="<?php echo $theme['actions']['activate']; ?>" aria-label="<?php echo esc_attr( $aria_label ); ?>"><?php _e( 'Activate' ); ?></a>
<?php if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) { ?>
<a class="button button-primary load-customize hide-if-no-customize" href="<?php echo $theme['actions']['customize']; ?>"><?php _e( 'Live Preview' ); ?></a>
<?php
if ( current_user_can( 'edit_theme_options' ) && current_user_can( 'customize' ) ) {
/* translators: %s: Theme name. */
$live_preview_aria_label = sprintf( _x( 'Live Preview %s', 'theme' ), '{{ data.name }}' );
?>
<a aria-label="<?php echo esc_attr( $live_preview_aria_label ); ?>" class="button button-primary load-customize hide-if-no-customize" href="<?php echo $theme['actions']['customize']; ?>"><?php _e( 'Live Preview' ); ?></a>
<?php } ?>
<?php } else { ?>
<?php
@ -850,7 +862,11 @@ function wp_theme_auto_update_setting_template() {
</p></div>
<# } #>
<span class="more-details" id="{{ data.id }}-action"><?php _e( 'Theme Details' ); ?></span>
<?php
/* translators: %s: Theme name. */
$details_aria_label = sprintf( _x( 'View Theme Details for %s', 'theme' ), '{{ data.name }}' );
?>
<button type="button" aria-label="<?php echo esc_attr( $details_aria_label ); ?>" class="more-details" id="{{ data.id }}-action"><?php _e( 'Theme Details' ); ?></button>
<div class="theme-author">
<?php
/* translators: %s: Theme author name. */
@ -870,7 +886,11 @@ function wp_theme_auto_update_setting_template() {
<div class="theme-actions">
<# if ( data.active ) { #>
<# if ( data.actions.customize ) { #>
<a class="button button-primary customize load-customize hide-if-no-customize" href="{{{ data.actions.customize }}}"><?php _e( 'Customize' ); ?></a>
<?php
/* translators: %s: Theme name. */
$customize_aria_label = sprintf( _x( 'Customize %s', 'theme' ), '{{ data.name }}' );
?>
<a aria-label="<?php echo esc_attr( $customize_aria_label ); ?>" class="button button-primary customize load-customize hide-if-no-customize" href="{{{ data.actions.customize }}}"><?php _e( 'Customize' ); ?></a>
<# } #>
<# } else { #>
<# if ( data.compatibleWP && data.compatiblePHP ) { #>
@ -879,7 +899,11 @@ function wp_theme_auto_update_setting_template() {
$aria_label = sprintf( _x( 'Activate %s', 'theme' ), '{{ data.name }}' );
?>
<a class="button activate" href="{{{ data.actions.activate }}}" aria-label="<?php echo $aria_label; ?>"><?php _e( 'Activate' ); ?></a>
<a class="button button-primary load-customize hide-if-no-customize" href="{{{ data.actions.customize }}}"><?php _e( 'Live Preview' ); ?></a>
<?php
/* translators: %s: Theme name. */
$live_preview_aria_label = sprintf( _x( 'Live Preview %s', 'theme' ), '{{ data.name }}' );
?>
<a aria-label="<?php echo esc_attr( $live_preview_aria_label ); ?>" class="button button-primary load-customize hide-if-no-customize" href="{{{ data.actions.customize }}}"><?php _e( 'Live Preview' ); ?></a>
<# } else { #>
<?php
/* translators: %s: Theme name. */
@ -1108,7 +1132,11 @@ function wp_theme_auto_update_setting_template() {
</div>
<# if ( ! data.active && data.actions['delete'] ) { #>
<a href="{{{ data.actions['delete'] }}}" class="button delete-theme"><?php _e( 'Delete' ); ?></a>
<?php
/* translators: %s: Theme name. */
$aria_label = sprintf( _x( 'Delete %s', 'theme' ), '{{ data.name }}' );
?>
<a href="{{{ data.actions['delete'] }}}" class="button delete-theme" aria-label="<?php echo $aria_label; ?>"><?php _e( 'Delete' ); ?></a>
<# } #>
</div>
</div>

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.8-alpha-51082';
$wp_version = '5.8-alpha-51083';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.