Make WordPress Core

Opened 9 years ago

Closed 16 months ago

Last modified 15 months ago

#32170 closed defect (bug) (fixed)

List table: sortable column headers accessibility

Reported by: afercia's profile afercia Owned by: joedolson's profile joedolson
Milestone: 6.3 Priority: normal
Severity: normal Version: 4.2
Component: Administration Keywords: has-patch commit
Focuses: ui, accessibility Cc:

Description

List tables can be sorted activating the links in the sortable table headers (if any), in ascending and descending order. See screenshot:

https://cldup.com/2h3fIgOJH1.png

For screen reader users, there's no indication at all the columns can be sorted. A far as I see, this feature is not even mentioned in the Help tab. There are just some links and users don't have a clue what they're meant for. Screen readers will read out, for example:

column 2
Title link
column 6
Comments link
column 7
Date link

It would be very beneficial to add a clear, concise, information about the header links purpose.

  • which columns are sortable
  • which order users will get when activating the links (descending or ascending?)
  • the current sorting and order

Also sighted users would probably benefit from a clear indication of the initial sorting. In fact, the arrow is displayed only when you change the default sorting so you already have to know the columns are sortable. Displaying the arrow in the initial view could help, as it's done in all similar applications I can think of.

I would also suggest to review the ordering associated with the "first click" on a header link. For example, in the Posts table clicking the Comments header the first time gives an ascending order by Comments count, showing the Posts with 0 comments first, while probably would be more useful to have the Posts with the higher number of Comments displayed first.

Any thoughts and patches more than welcome.

Attachments (11)

32170.patch (1.6 KB) - added by joedolson 9 years ago.
Add screen reader text for sort directions; turn on sort icon
32170.2.patch (15.7 KB) - added by afercia 9 years ago.
32170.3.patch (17.4 KB) - added by afercia 9 years ago.
32170.4.patch (17.5 KB) - added by afercia 9 years ago.
32170.5.patch (17.6 KB) - added by afercia 9 years ago.
32170.6.diff (36.9 KB) - added by joedolson 17 months ago.
Refresh patch
32170.7.diff (21.1 KB) - added by joedolson 17 months ago.
Update patch with visual changes
32170.8.diff (21.0 KB) - added by alexstine 16 months ago.
Refresh and try less verbose approach.
32170.9.diff (20.5 KB) - added by joedolson 16 months ago.
Verbosity compromise
32170.10.diff (20.8 KB) - added by alexstine 16 months ago.
Screen reader text shorten.
32170.11.diff (4.3 KB) - added by joedolson 16 months ago.
Follow up patch

Download all attachments as: .zip

Change History (85)

This ticket was mentioned in Slack in #accessibility by matthew. View the logs.


9 years ago

This ticket was mentioned in Slack in #accessibility by rianrietveld. View the logs.


9 years ago

@joedolson
9 years ago

Add screen reader text for sort directions; turn on sort icon

#3 @joedolson
9 years ago

The attached patch adds screen reader text that says "Sorted in %s order. Click to sort %s" according to the current sort order, and adds that to the link text.

It also makes the sort icon visible by default for any column where the sort has been changed.

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


9 years ago

#5 @joedolson
9 years ago

  • Milestone changed from Awaiting Review to 4.3
  • Owner set to afercia
  • Status changed from new to assigned

This ticket was mentioned in Slack in #core by joedolson. View the logs.


9 years ago

#7 @afercia
9 years ago

I fear we can't do it this way.Unfortunately, any text added in the table headers (which have scope=col) will be read out again by screen readers for each table cell in that column.

Also, unrelated to the patch but makes things a bit more difficult, in the initial view $current_order is always set to "asc" even when, for example in the Posts screen, is "desc".

if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] )
	$current_order = 'desc';
else
	$current_order = 'asc';

#8 follow-ups: @joedolson
9 years ago

Blah. That's a good point, and nasty. The only solution I can think of to that is to move the sorting link out of the table heading, but that's an ugly thing o do, as well, and will make it harder to find.

If we set up the text as an aria-describedby or aria-labelledby and associated it with the link, do you think that should be read as part of the th scope?

(Not *is* it read, necessarily - I'm thinking more about whether or not it *should* be read, in principle.)

#9 in reply to: ↑ 8 @afercia
9 years ago

Replying to joedolson:

If we set up the text as an aria-describedby or aria-labelledby and associated it with the link, do you think that should be read as part of the th scope?

Theoretically, it shouldn't. Looks promising, will try and let you know :)

#10 @afercia
9 years ago

Related: #32416

This ticket was mentioned in Slack in #accessibility by afercia. View the logs.


9 years ago

#12 @rianrietveld
9 years ago

@afercia and I have been brainstorming and we came up with the following idea:

We make a drop down menu above the list table and add the rows that can be sorted, like

<option>Title ascending</option>
<option>Title descending</option>
<option>Comments descending</option>
<option>Comments ascending</option>

Then we hide this drop down menu with screen reader text.

The advantage is that a screen reader user now can tell by the selected option, how the table is sorted.
The main reason for removing this info outside header (TH) is because else it will read out for every cell in the table.

Then, to reduce the noise for screen readers even more we can add aria-hidden to <span class="sorting-indicator"></span> to prevent the dash icon to be read out

<span class="sorting-indicator" aria-hidden="true"></span>

#13 in reply to: ↑ 8 @afercia
9 years ago

Replying to joedolson:

If we set up the text as an aria-describedby or aria-labelledby and associated it with the link, do you think that should be read as part of the th scope?

Experimented a bit in the last days and couldn't find a clean way to add aria-describedby on the table headers and at the same time to avoid the description being read out when navigating through the table cells. Basically, anything inside a table header will be read out as the header content.
To keep it simple, maybe we should just provide information about the sortable headers and a separate control outside the table and then hide this with screen-reader-text.
In addition to what Rian pointed out in the previous comment, here's a summary and some other points discussed in our brainstorming session:

  • add info in the Help tab
  • make visually clear the difference between sortable and not sortable columns
  • add screen-reader-text before the table about sorting and order
  • show the arrow on the currently sorted column, if any
  • on hover and focus show the arrows on sortable columns
  • use aria-sort, while not universally supported, WordPress is in the position to actually encourage web standards adoption; as far as I know, it works at least in JAWS and NVDA

#14 @afercia
9 years ago

Thinking some information could be added in an aria-describedby attribute on the table itself:
<table aria-describedby="table-desc" ...
that would be read out just one time when entering the table, similarly to the old, now discouraged, summary attribute.

This ticket was mentioned in Slack in #core by afercia. View the logs.


9 years ago

This ticket was mentioned in Slack in #accessibility by afercia. View the logs.


9 years ago

#17 @afercia
9 years ago

For reference and to make things clear, see the screenshot below. This is one of the things we would like to do in this ticket, should be hidden with screen-reader-text or maybe used as target for aria-describedby, details still to define, just to give an idea:
https://cldup.com/VN6FNuePgt.png

This ticket was mentioned in Slack in #core by afercia. View the logs.


9 years ago

This ticket was mentioned in Slack in #core by afercia. View the logs.


9 years ago

@afercia
9 years ago

#20 @afercia
9 years ago

Updated patch, first pass. I guess there are things to discuss and better practices to follow, but it's a start. Happy for any feedback and improvements.

To keep things simple, I've decided to not create a new method to get additional information about sortable columns. get_sortable_columns() appeared to me the most logical place to add them to. This way, the new information will be available also in get_column_info() where there's already a filter that custom post types and custom taxonomies can use to add their own things. See screenshot:

https://cldup.com/q_bJc33x0S.png

Added a new method print_table_description() (similar to print_column_headers(), there's a bit of repetition in the code here) to print out the table information. For now, the new info is visible for testing purposes right before the tables, maybe we'll hide them with screen-reader-text.

About header links, couldn't find any clean way to add orderby and asc/desc feedback and at the same time to avoid that being read out when navigating through the table cells. Open to any suggestions. I'm tempted to just keep the plain links and add some hint in the table description, something like: "Activate the table header links to change order." Accessibility team, any thoughts?

Finally, aria-sort will make compliant screen readers announce the asc/desc order for the currently sorted column. Added bonus, the arrow is now correctly displayed also in the initial view.

@todo:

  • add some info in the Help tabs
  • consider to visually increase the difference between sortable and non-sortable columns
  • improve documentation :)

Tested with NVDA, when entering the table it will read out, for example:

table with 22 rows and 7 columns
Table ordered by Date. Descending order. <-- `aria-describedby`
row 1  column 1
Select All checkbox  not checked
column 2
link Title
column 3
Author
column 4
Categories
column 5
Tags
column 6
link Comments
column 7 sorted descending <-- `aria-sort`
link Date
Last edited 5 years ago by afercia (previous) (diff)

#21 @afercia
9 years ago

See point 3 in this NVDA bug report: http://community.nvda-project.org/ticket/3566
Accessibility team, any thoughts more than welcome. See also:
http://www.w3.org/TR/html5/tabular-data.html#attr-th-abbr
https://bugzilla.mozilla.org/show_bug.cgi?id=673418
Maybe abbr is not universally supported yet, but looks like is going to stay with us in the future, see the HTML 5.1 working draft
http://www.w3.org/TR/html51/semantics.html#attr-th-abbr

#22 @rianrietveld
9 years ago

Adding abbr to a th seems like a good idea, if it's in the HTML5 specs, and it doesn't break anything, why not.

#23 @joedolson
9 years ago

I definitely give preference to meeting specifications, even if the assistive tech isn't supporting it properly. It's a better long-term strategy than attempting a work around.

#24 @joedolson
9 years ago

  • Keywords has-patch added; needs-patch removed

This ticket was mentioned in Slack in #accessibility by rianrietveld. View the logs.


9 years ago

@afercia
9 years ago

#26 @afercia
9 years ago

In the updated patch:

  • hide the table description paragraph with screen-reader-text
  • add some screen-reader-text in the table header cells to indicate which columns are sortable and which order users will get when activating the link
  • use the th abbr attribute as alternative, shorter, label for the header cell, as per discussion in the accessibility team

Would greatly appreciate feedback from native English speakers about all the new text proposed in the patch and suggestions for better wording.

#27 @afercia
9 years ago

  • Keywords dev-feedback added

Will try to summarize for devs and committers:

  • we need to give feedback about the current tables 'order by' and 'asc/desc order', also in the initial view
  • we also need to make clear which columns are sortable and what will happen when users click on the table header links
  • hence, we need to get additional information about the sortable columns extending what is set in get_sortable_columns()
  • a new method print_table_description() prints a hidden table description, referenced as target for the table aria-describedby attribute

Of course we're totally open to discuss a different implementation and better practices, any thoughts more than welcome.

This ticket was mentioned in Slack in #accessibility by afercia. View the logs.


9 years ago

This ticket was mentioned in Slack in #core by davidakennedy. View the logs.


9 years ago

#30 @afercia
9 years ago

Patch still applies after r32644.

@afercia
9 years ago

#31 @afercia
9 years ago

Refreshed patch after latest relevant changes to List Tables, see r32721 and following ones, r32736 and following ones, r32752 and following ones.
Would greatly appreciate some devs eyes on this ticket :)

This ticket was mentioned in Slack in #design by afercia. View the logs.


9 years ago

#33 @afercia
9 years ago

  • Keywords commit added; dev-feedback removed

#34 follow-up: @wonderboymusic
9 years ago

  • Keywords commit removed

There's a lot going on here, will take a look

@afercia
9 years ago

#35 @afercia
9 years ago

Refreshed patch after recent responsive list table changes see 33016. Also, the initial asc or desc order defaults now to "false" because there are tables that don't have a column corresponding to the initial order, e.g. Comments (initially sorted by comment date but there's no "date" column).

This ticket was mentioned in Slack in #accessibility by afercia. View the logs.


9 years ago

#37 in reply to: ↑ 34 @afercia
9 years ago

Replying to wonderboymusic:

There's a lot going on here, will take a look

@wonderboymusic anything we can do to help this ticket move on? :)

Last edited 5 years ago by afercia (previous) (diff)

#38 @obenland
9 years ago

  • Milestone changed from 4.3 to Future Release

Given the size of the patch and how it changes the way sortable columns work, I feel like we should give this more time rather than trying to squeeze it in late in the beta cycle.

#39 @johnjamesjacoby
8 years ago

There's some good work in this ticket, so kudos everyone!

I just ran across another case where these arrows act strangely: wp-admin/network/users.php

To start, the arrow is backwards. Clicking the "Registered" column header sorts the same direction, but inverts the arrow. Clicking again inverts the arrow again, and orders the other direction. It's pretty weird.

This ticket was mentioned in Slack in #accessibility by afercia. View the logs.


8 years ago

#41 @afercia
6 years ago

  • Owner afercia deleted

#42 @afercia
5 years ago

#47047 was marked as a duplicate.

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


18 months ago

#44 @joedolson
18 months ago

  • Milestone changed from Future Release to 6.3
  • Owner set to joedolson
  • Status changed from assigned to accepted

I'm assigning this to myself and milestoning for 6.3. That may be ambitious, but there was a lot of work done here and I think we should be able to move it on. There's been a fair amount of progression in support for sortable states in tables for ARIA, so we may have better options now.

@joedolson
17 months ago

Refresh patch

#45 @joedolson
17 months ago

Refreshed patch. This is just a starting point. I'm going to re-implement this using aria-sort & some revisions to the visual indicators.

@joedolson
17 months ago

Update patch with visual changes

#46 @joedolson
17 months ago

aria-sort was already in the previous patch; I just overlooked it when refreshing. However, this patch incorporates some visual changes:

1) Sort arrows are always visible. This helps make it more obvious that sorting links are controls; otherwise the distinction between a linked header and an unlinked header is very minimal.

2) Both up and down arrows are visible by default. Neither are highlighted if the column is not used for sorting, if a sort is active, the sort direction currently engaged is highlighted.

This ticket was mentioned in Slack in #accessibility by joesimpsonjr. View the logs.


17 months ago

This ticket was mentioned in Slack in #accessibility by joedolson. View the logs.


16 months ago

#49 @alexstine
16 months ago

  • Keywords needs-testing added

@joedolson I found this approach to be way too verbose. I took a try at it for the generic list table class. Let me know if you think this is an okay approach. I also refreshed the patch a bit so it applies more cleanly.

The caption approach is inspired by: https://www.w3.org/WAI/ARIA/apg/patterns/table/examples/sortable-table/

Thanks.

@alexstine
16 months ago

Refresh and try less verbose approach.

#50 @joedolson
16 months ago

I can see this less-verbose approach being useful for users with a high level of comfort with how list tables work, but I'm not sure it includes enough information.

In the more verbose patch, since the sortability information is after the header name, it seems like highly skilled users can still move past without being bothered by the verbosity, while less skilled users will get all the information they need.

Do you think screen reader users with a lower skill level would still get as much information as they need with the less verbose information?

#51 @alexstine
16 months ago

@joedolson I think so because the information is still in the caption. It sets expectations for users what will happen when selecting the link. Besides, I would bet that screen reader users who are less advanced might take the word "click" out of context so either way, its not a perfect solution. Generally, I like to use "select" or "activate" in place of "click". I wish we could get another opinion on this though... Either way, I think the caption approach is better over using aria-describedby due to the way Voiceover on Mac handles defined ARIA descriptions.

#52 @joedolson
16 months ago

@alexstine I actually think that the instruction 'Click' is unnecessary. It should just say "Sort descending" or "Sort ascending" without any action verb. "Sort" is an action verb, so I don't think an additional action is needed.

But I do think that having information about what activating a header control will do. If the header isn't currently sorted, right now the user has no way of knowing which way it will be sorted on activation.

#53 @alexstine
16 months ago

@joedolson Fair enough. It might be be less verbose to remove the click meaning already given via the link. Do you have time to adjust it from your latest patch? If not, I can work on this soon.

#54 @joedolson
16 months ago

I can do it; but if you get to it before me, go to town.

@joedolson
16 months ago

Verbosity compromise

#55 @joedolson
16 months ago

@alexstine Uploaded a new patch that should be a reasonable compromise in verbosity. Less than the original, but a bit more than yours.

This ticket was mentioned in PR #4666 on WordPress/wordpress-develop by @joedolson.


16 months ago
#56

Adds aria sort attributes & state descriptions to list tables.

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

@alexstine
16 months ago

Screen reader text shorten.

#57 @alexstine
16 months ago

@joedolson I think it is implied that a column can be sorted with just "Sort X" so I tried it in my latest patch. Do you think that is good enough? That mirrors what aria-sort does for us. Having the word "Sortable." feels redundant.

#58 @joedolson
16 months ago

  • Keywords commit added; needs-testing removed

Yeah, I debated that one for myself for a while. That works for me.

#59 @joedolson
16 months ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 55971:

Administration: Set accessible state for list table headers.

Implement aria-sort and change icon states to indicate current sort for list tables. Allow screen reader users to get context about the current sort and allow sighted users to know how the table is currently sorted.

Props afercia, rianrietveld, joedolson, alexstine, johnjamesjacoby.
Fixes #32170.

@joedolson commented on PR #4666:


16 months ago
#60

Resolved in r55971

#61 @kebbet
16 months ago

The function print_table_description() added in [55971] has a @since thats says 4.3.0, is that correct? Should it be 6.3.0?

This ticket was mentioned in PR #4670 on WordPress/wordpress-develop by @kebbet.


16 months ago
#62

Minor fix, updates docblock for print_table_description()

https://core.trac.wordpress.org/ticket/32170

#63 @kebbet
16 months ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

#64 @kebbet
16 months ago

In the follow up PR, I also added translator comments for the screen-reader-texts.

#65 @Chouby
16 months ago

@joedolson [55971] introduces a backward compatibility issue for all plugins extending WP_List_Table and overriding get_sortable_columns().

Indeed, these plugins do not provide all the keys expected in
see list( $orderby, $desc_first, $abbr, $orderby_text, $initial_order ) = $sortable[ $column_key ];

list( $orderby, $desc_first, $abbr, $orderby_text, $initial_order ) = $sortable[ $column_key ];

This results in the error Undefined array key 2

Last edited 16 months ago by Chouby (previous) (diff)

#66 @Chouby
16 months ago

Further debugging this issue, I must add that an additionnal condition to reproduce the bug is to set $this->_column_header before the method get_column_info() is called by WordPress. Given that this method has been introduced in WP 3.1, this may be frequent in old plugins and also seems to be popular in more recent plugins, probably copying code from older ones: See https://wpdirectory.net/search/01H3HDSAM828TE3JKYKNMMCS2E

#67 @joedolson
16 months ago

Thanks @kebbet! I completely forgot that we were now adding those translator comments; good catch.

@chouby Looking into making this backwards compatible.

@joedolson
16 months ago

Follow up patch

#68 @joedolson
16 months ago

  • Keywords reporter-feedback added

Patch incorporates changes from @kebbet, fixes a mismatched closing tag on the caption element, and switches the use of list() to a set of isset() checks on the new sortable parameters. list()

An alternate solution would be to insert the missing keys into the array, but I think that this is more readable.

If you want to test this, @chouby, that would be great. I tested against only one of the listed plugins (Complianz).

#69 @Chouby
16 months ago

@joedolson I confirm that 32170.11.diff fixes the issue I noticed previously.

#70 @joedolson
16 months ago

  • Keywords reporter-feedback removed

#71 @joedolson
16 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 56004:

Administration: Backwards compatibility for new sortable keys.

Replace use of list to parse array keys into variables. list throws errors if the keys don't exist, and many extenders will not define the new array keys. The code path already falls back effectively for empty values.

Also add translator comments to screen reader hidden text, fix a docblock, and fix an HTML error.

Follow up to [r55971].

Props kebbet, chouby, joedolson.
Fixes #32170.

#73 @SergeyBiryukov
15 months ago

In 56260:

Coding Standards: Use strict comparison for static strings in wp-admin/includes/class-wp-list-table.php.

Follow-up to [55971], [56004].

See #32170, #57839.

#74 @SergeyBiryukov
15 months ago

In 56261:

Administration: Add a missing closing </span> tag for column sorting indicators.

Includes wrapping a few other long markup lines for better readability.

Follow-up to [55971], [56004], [56260].

See #32170, #57839.

Note: See TracTickets for help on using tickets.