Skip to content

Fixed #36460 -- Improve accessibility and add new feature to column sorting in admin ChangeList. #19564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Antoliny0919
Copy link
Contributor

@Antoliny0919 Antoliny0919 commented Jun 14, 2025

Trac ticket number

ticket-36460

Branch description

I updated the design of the ChangeList column sorting to improve accessibility.

Checklist

  • This PR targets the main branch.
  • The commit message is written in past tense, mentions the ticket number, and ends with a period.
  • I have checked the "Has patch" ticket flag in the Trac system.
  • I have added or updated relevant tests.
  • I have added or updated relevant docs, including release notes if applicable.
  • I have attached screenshots in both light and dark modes for any UI changes.

@sarahboyce
Copy link
Contributor

Screenshot from 2025-06-18 14-33-52
When the table column is small and the column is not sorted, the sorting icons overlap

Also when testing with a screen reader, the column header is not announced with the buttons
Perhaps this gives an example of what we might want to try and achieve: https://www.w3.org/WAI/ARIA/apg/patterns/table/examples/sortable-table/

We also have no test coverage for generating screenshots with the change list which might be nice to add

@Antoliny0919
Copy link
Contributor Author

Screenshot from 2025-06-18 14-33-52 When the table column is small and the column is not sorted, the sorting icons overlap

Also when testing with a screen reader, the column header is not announced with the buttons Perhaps this gives an example of what we might want to try and achieve: https://www.w3.org/WAI/ARIA/apg/patterns/table/examples/sortable-table/

We also have no test coverage for generating screenshots with the change list which might be nice to add

Thank you, sarahboyce. Even though I already referred to the article you provided and worked on it, reading it again made me realize that my work was lacking in many ways. I will do my best to review it carefully and redo the work.

@Antoliny0919 Antoliny0919 force-pushed the ticket_36460 branch 5 times, most recently from e5422bb to 9eb02d4 Compare June 21, 2025 05:41
@Antoliny0919
Copy link
Contributor Author

@sarahboyce I might be misunderstanding something, but I have a question...

When applying the approach where the column header is announced together with the button, it seems necessary to have only a single sort button inside each column (like in the W3C sortable table example).

If we adopt this method, the sort order would cycle like this: none → ascending → descending → none
I’m a bit concerned that it may reduce some of the flexibility we currently have such as being able to directly choose a sort direction from either state.

Do you think the benefit of having just a single sort button per column outweighs that trade-off?
Personally, I’m leaning toward keeping the current flexibility, but I’d love to hear your thoughts.

@sarahboyce
Copy link
Contributor

When applying the approach where the column header is announced together with the button, it seems necessary to have only a single sort button inside each column (like in the W3C sortable table example).

I don't know if the @django/accessibility team has examples of accessible tables with multiple sort buttons.
It does seem quite a common pattern to have to click on a sort button multiple times to get the sort direction you want so I don't think adopting that is too big of an issue

Currently in this PR:

  • the buttons don't announce what they are sorting when I am focused on the button (not sure if this will be fixed via a single button or "aria-labelledby" etc)
  • the animation of the sort buttons is too much. I know they already had some "movement" but with the two sorts together this very distracting. I would be tempted to remove the animation and have a different way to indicate it's clickable if the color change is not enough
  • just noticed that in light mode the grey toggle icon against the selected column grey doesn't have sufficient color contrast
  • the aria-sort attribute would be good to add in

@Antoliny0919
Copy link
Contributor Author

I don't know if the @django/accessibility team has examples of accessible tables with multiple sort buttons. It does seem quite a common pattern to have to click on a sort button multiple times to get the sort direction you want so I don't think adopting that is too big of an issue

I agree. It is common to have only one sort button. I tried to preserve the existing structure as much as possible. 😅

the buttons don't announce what they are sorting when I am focused on the button (not sure if this will be fixed via a single button or "aria-labelledby" etc)

Yes, When the button is focused, information such as the item, sort direction, and priority should be announced.

the animation of the sort buttons is too much. I know they already had some "movement" but with the two sorts together this very distracting. I would be tempted to remove the animation and have a different way to indicate it's clickable if the color change is not enough

I believe it’s best if the visual cues can be understood through color changes alone. If possible, I feel it would be better to remove the animations (I also find the current animations to be quite cluttered).

the aria-sort attribute would be good to add in

As far as I know, the aria-sort attribute is recommended to be used on only one column.
Hmm... I’m not sure how to apply it in tables like ChangeList, where multiple columns can be sorting criteria.
I’ll have to ask the accessibility team about this...

@Antoliny0919 Antoliny0919 force-pushed the ticket_36460 branch 2 times, most recently from 06d96e2 to 7fd300d Compare June 26, 2025 11:31
@thibaudcolas thibaudcolas self-requested a review June 26, 2025 12:05
@Antoliny0919 Antoliny0919 force-pushed the ticket_36460 branch 4 times, most recently from 45b28fa to 712cda0 Compare June 29, 2025 23:48
@Antoliny0919
Copy link
Contributor Author

Changed...

Unsorted State

Screenshot 2025-06-30 at 7 30 14 AM

In an unsorted state, sortable columns are marked with the symbol "△".
This visual indicator makes it easy to identify which columns are sortable at a glance.

Sorted State

Screenshot 2025-06-30 at 7 38 42 AM

When columns are sorted, the symbols "▲" and "▼" are used to indicate the sorting direction.
Additionally, if two or more columns are sorted, the sorting priority is also displayed.

Sorting is performed in the following directions.
none -> ascending -> descending -> none

Screen reader

When a sortable header is focused, the sorting direction is announced.

Screenshot 2025-06-30 at 10 29 52 AM
  • none: toggle sorting ascending
  • ascending: toggle sorting descending
  • descending: toggle sorting remove
Screenshot 2025-06-30 at 10 34 31 AM

When multiple columns are sorted, indicate the sorting priority (for all sortable columns).

++ Additionally...

Screenshot 2025-06-30 at 10 38 54 AM

Information related to aria-sort is also provided.

Color Contrast

In dark mode, the color contrast of the column in a sorted state has been adjusted to meet the WCAG AA requirements.

Before

  • Admin
Screenshot 2025-06-30 at 10 40 49 AM
  • Color contrast
Screenshot 2025-06-30 at 10 44 09 AM

After

  • Admin
Screenshot 2025-06-30 at 10 47 58 AM
  • Color contrast
Screenshot 2025-06-30 at 10 45 18 AM

Copy link
Contributor

@sarahboyce sarahboyce left a comment

Choose a reason for hiding this comment

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

Thank you for the updates @Antoliny0919
This looks promising to me

The "no sort" icon appears to be bigger or misaligned to the sorted ascending/descending icons. I also think I prefer them to be right aligned to the column as this design pattern seems to be the most common
Screenshot from 2025-07-18 13-32-08

I will let the accessibility team give feedback on the approach 👍

@Antoliny0919
Copy link
Contributor Author

Thank you for the updates @Antoliny0919 ⭐ This looks promising to me

The "no sort" icon appears to be bigger or misaligned to the sorted ascending/descending icons. I also think I prefer them to be right aligned to the column as this design pattern seems to be the most common Screenshot from 2025-07-18 13-32-08

I will let the accessibility team give feedback on the approach 👍

Sort priority and sort button were originally positioned on the right side of the column, and I’ve adjusted them to remain in the same position.
I’ve tested the sort button size across various environments, including mine, and didn’t notice any issues.
Would you mind sharing the environment you used for testing? 🥲

@sarahboyce
Copy link
Contributor

Testing with Firefox 140.0.4 on Ubuntu

@Antoliny0919
Copy link
Contributor Author

Antoliny0919 commented Jul 26, 2025

Changed..

Light Mode

Screenshot 2025-07-26 at 8 11 26 PM

Sorted column(Name, Age)

  • bg(#447996)
  • fg(#ffffff)
Screenshot 2025-07-26 at 8 13 06 PM

Unsorted Column(Gender)

  • bg(#f8f8f8)
  • fg(#666666)
Screenshot 2025-07-26 at 8 14 53 PM

Dark Mode

Screenshot 2025-07-26 at 8 18 22 PM

Sorted Column(Name, Age)

  • bg(#30586e)
  • fg(#eeeeee)
Screenshot 2025-07-26 at 8 16 04 PM

Unsorted Column(Gender)

  • bg(#212121)
  • fg(#d0d0d0)
Screenshot 2025-07-26 at 8 17 34 PM

@Antoliny0919 Antoliny0919 force-pushed the ticket_36460 branch 4 times, most recently from 0af8137 to 1471861 Compare July 26, 2025 11:33
Copy link
Contributor

@sarahboyce sarahboyce left a comment

Choose a reason for hiding this comment

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

Thank you for the updates!

Comment on lines 424 to 420
table thead th.sortable:not([aria-sort]) div span:nth-last-child(2):after,
table thead th.sortable[aria-sort="ascending"] div span:nth-last-child(2):after {
content: "▲";
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
table thead th.sortable:not([aria-sort]) div span:nth-last-child(2):after,
table thead th.sortable[aria-sort="ascending"] div span:nth-last-child(2):after {
content: "▲";
}
table thead th.sortable:not([aria-sort]) div span:nth-last-child(2):after {
content: "⇅";
}
table thead th.sortable[aria-sort="ascending"] div span:nth-last-child(2):after {
content: "▲";
}

I think we need a different icon for the sortable column, as currently if I am hovering over the column and click through, it's hard to tell that there is 3 states

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I really like the Unicode symbol you suggested :0
I think it would be great for indicating that sorting is available.
Thank you !!!

thead th.sorted {
background: var(--selected-bg);
thead th.sorted,
table thead th.sortable a:hover {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
table thead th.sortable a:hover {
table thead th.sortable:hover {

This issue was pre-existing but it is more pronounced when the background is blue. Currently only the inner background changes on hover (and I don't like it personally)
This suggestion doesn't quite work because when you are on the th boarder, rather than the a tag, the text is grey and unreadable but hopefully you understand what I mean

Copy link
Contributor Author

@Antoliny0919 Antoliny0919 Aug 9, 2025

Choose a reason for hiding this comment

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

You mean that in light mode, when you hover the pointer over the edge of a th, the background color of the th changes but the text color does not, making it hard to distinguish, right?
I think it should be fine to revert the background color back to the original 😁
(foreground color will be fixed to a single color.)

Screenshot 2025-08-09 at 6 17 06 PM

Comment on lines 48 to 49
--table-sorted-bg: #447996;
--table-sorted-fg: #fff;
Copy link
Contributor

Choose a reason for hiding this comment

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

I personally preferred using shades of grey for the sorted columns but that is just personal preference (not sure if we have any design spec around colors)

Copy link
Contributor Author

@Antoliny0919 Antoliny0919 Aug 9, 2025

Choose a reason for hiding this comment

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

I agree.
In fact, the main reason I changed the background color was because I was trying to indicate sorting using only two characters("▲", "▼")

model_admin=cl.model_admin,
return_attr=True,
)
priority_description += "%s priority %d, " % (text, index + 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

We should probably make all descriptions translatable and you might want to think how best to make this clear for translators

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've been thinking about this, and how about making it like this?
_("Next sort direction, %(direction)s, Sort priority, %(priority)s")

The sentence will probably be something like the following...
"Next sort direction, ascending, Sort priority, col_xx, col_yy, col_zz"
Could I get some advice on this part? 🥲

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
screenshots 🖼️ selenium Apply to have Selenium tests run on a PR
Projects
Development

Successfully merging this pull request may close these issues.

2 participants