Fixed #36367 -- Improving the accessibility of the date_hierarchy layout in the admin.#19688
Conversation
sarahboyce
left a comment
There was a problem hiding this comment.
Thank you for the PR 👍
I added some thoughts. The @django/accessibility team might be able to advise as to what would be the best approach
| @@ -1,5 +1,5 @@ | |||
| {% if show %} | |||
| <nav class="toplinks"> | |||
| <nav class="toplinks" aria-label="Date hierarchy"> | |||
There was a problem hiding this comment.
We need to translate this, like the other nav aria-labels e.g. <nav aria-label="{% translate 'Breadcrumbs' %}">
I also think "Date hierarchy" is not the best label here, maybe "Filter by date" or "Filter by {field_name} date"
In order to make the title more descriptive, this could be determined within django.contrib.admin.templatetags.admin_list.date_hierarchy().
I also think if we create something descriptive, we may want to make this visible to all users rather than an aria-label. I don't think it is clear to anyone what these do, especially if there are multiple date fields that could be being filtered
Finally, this will need a test to be accepted 😁
There was a problem hiding this comment.
Hello Sarah!
Personally, I feel that the word “hierarchy” should definitely be included, no matter what.
That’s because the links within the date hierarchy are structured in a hierarchical way.
I believe including that word could help users better understand the element when navigating through it.
Also, since it's actually possible to filter by date using the sidebar filters as well,
I think it's important to clearly distinguish between the two.
There was a problem hiding this comment.
I think it’s good to add the field_name as well.
However, the real issue is that not only screen readers but also visual users cannot easily identify which field is being filtered.
Of course, we can see it from the query, but I have heard before that the admin page is no longer just a space used by developers.
This part definitely needs improvement.
There was a problem hiding this comment.
I guess I personally find “hierarchy” a bit odd, maybe "filter drill-down" 🤔
But I agree it's not just a filter and so communicating that would be nice
There was a problem hiding this comment.
I agree as well.
Since there is a unique structure to the hierarchy, I think users need to understand that part.
Perhaps, as you mentioned an appropriate aria-labelledby would be necessary for that.
|
I think this is the right direction. We might play around with the wording and styling/layout but this kind of thing is what I had in mind 👍 |
569b955 to
7ea5089
Compare
Antoliny0919
left a comment
There was a problem hiding this comment.
Thank you for working on this ticket ⭐️
I like the structure you suggested.
This is just my personal opinion, but I think it would be better to structure the elements generated by the date hierarchy (links) and the tag used for the label function in a column layout.

The design aspect will probably need to be discussed with the accessibility team, but I created a simple example for reference.
And as sarah pointed out, I think testing will be necessary!
| <nav class="toplinks"> | ||
| <nav class="toplinks" aria-labelledby="date-hierarchy-label"> | ||
| <span id="date-hierarchy-label"> | ||
| {% blocktrans with field_name=field_name|title %} Filter by {{ field_name }} {% endblocktrans %} |
There was a problem hiding this comment.
I think using blocktranslate is better than blocktrans.
Also, since verbose_name is already intended to be human readable,
I'm not sure if the title filter is really necessary 🤔
| </span> | ||
| {% block date-hierarchy-toplinks %} | ||
| {% block date-hierarchy-back %} | ||
| {% if back %}<a href="{{ back.link }}" class="date-back">‹ {{ back.title }}</a>{% endif %} |
There was a problem hiding this comment.
The current link elements are made up of <a> tags.
I think using a ul/li structure would be more appropriate in terms of accessibility.
There was a problem hiding this comment.
I’d agree but not sure it’s worthwhile. It would allow people to know how many items there are to navigate with, which is a plus, but not really related to other changes in this PR.
|
++ If you always want to get your work reviewed, please don’t forget to switch the ticket flags to off :) |
|
If there are more links in the hierarchy then wouldn't it be better to put them in a drop-down menu? Any thoughts on this |
|
Static PR demo link - releases changelist. I will try to find time to test this / provide input on the forum later this week ⭐️ |
|
Any suggestions/feedback on the date hierarchy structure/remodelling please write them here. |
There was a problem hiding this comment.
Working all as expected! Tested w/ macOS VoiceOver. Was wondering whether the label should be a heading rather than a span, but since it’s all in the same line, probably a span is good. There’s more possible improvements on the links’ markup as mentioned, but they strike me as clear "nice-to-have", while the absence of a label is way more problematic
There was a problem hiding this comment.
Thank you @XChaitanyaX! I pushed minor tweaks.
Thanks @Antoliny0919, @thibaudcolas, Sarah, and space reviewers! 👾
(I plan to land soon, but Antoliny, let me know if you have any suggested tweaks to the wording, I know you were originally in favor of "hierarchy", but I think what we have is clear.)
| <span id="date-hierarchy-label"> | ||
| {% blocktranslate %}Filter by {{ field_name }}{% endblocktranslate %} | ||
| </span> |
There was a problem hiding this comment.
Other <span>s in the admin seem to be careful about not introducing whitespace:
| <span id="date-hierarchy-label"> | |
| {% blocktranslate %}Filter by {{ field_name }}{% endblocktranslate %} | |
| </span> | |
| <span id="date-hierarchy-label">{% blocktranslate %}Filter by {{ field_name }}{% endblocktranslate %}</span> |
I'll roll this in for you 👍
| Event.objects.create(date=datetime(2017, 1, 1)) | ||
| response = self.client.get(reverse("admin:admin_changelist_event_changelist")) | ||
| self.assertEqual(response.status_code, 200) | ||
| self.assertContains(response, "Filter by") |
There was a problem hiding this comment.
I think instead of testing the template we could test that the view provided the dynamic content.
| <span id="date-hierarchy-label"> | ||
| {% blocktranslate %}Filter by {{ field_name }}{% endblocktranslate %} | ||
| </span> |
There was a problem hiding this comment.
Looked like a slight visual misalignment here, traced to a font-size delta, assuming that was not intentional, I will add some consistency.
3c45292 to
92e00a9
Compare
Thanks Sarah Boyce for the implementation idea.
92e00a9 to
dc67dbb
Compare
Antoliny0919
left a comment
There was a problem hiding this comment.
(I plan to land soon, but Antoliny, let me know if you have any suggested tweaks to the wording, I know you were originally in favor of "hierarchy", but I think what we have is clear.)
Yes, I agree as well :)



Trac ticket number
ticket-36367
Branch description
Checklist
mainbranch.