From cd413bd78ac65bd4282d26cc279bfd1bd4de707d Mon Sep 17 00:00:00 2001 From: Howard Cox Date: Fri, 2 Jun 2023 11:54:07 +0100 Subject: [PATCH] Fixed #34621 -- Made admin site header render in
tag. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was problematic for screen reader users because they use headings to navigate. Having two

is confusing, and the one in the header wasn’t particularly helpful since it’s the same on all pages. --- django/contrib/admin/sites.py | 2 +- django/contrib/admin/static/admin/css/base.css | 4 ++-- django/contrib/admin/static/admin/css/responsive.css | 4 ++-- django/contrib/admin/templates/admin/base_site.html | 2 +- docs/intro/tutorial07.txt | 2 +- docs/ref/contrib/admin/index.txt | 6 +++++- docs/releases/5.0.txt | 5 +++++ tests/admin_docs/test_views.py | 4 ++-- 8 files changed, 19 insertions(+), 10 deletions(-) diff --git a/django/contrib/admin/sites.py b/django/contrib/admin/sites.py index 3ff7088506c..2e400c2e190 100644 --- a/django/contrib/admin/sites.py +++ b/django/contrib/admin/sites.py @@ -45,7 +45,7 @@ class AdminSite: # Text to put at the end of each page's . site_title = gettext_lazy("Django site admin") - # Text to put in each page's <h1>. + # Text to put in each page's <div id="site-name">. site_header = gettext_lazy("Django administration") # Text to put at the top of the admin index page. diff --git a/django/contrib/admin/static/admin/css/base.css b/django/contrib/admin/static/admin/css/base.css index 0bde69d0135..c4b7de55f67 100644 --- a/django/contrib/admin/static/admin/css/base.css +++ b/django/contrib/admin/static/admin/css/base.css @@ -937,7 +937,7 @@ a.deletelink:focus, a.deletelink:hover { display: flex; } -#branding h1 { +#site-name { padding: 0; margin: 0; margin-inline-end: 20px; @@ -946,7 +946,7 @@ a.deletelink:focus, a.deletelink:hover { color: var(--header-branding-color); } -#branding h1 a:link, #branding h1 a:visited { +#site-name a:link, #site-name a:visited { color: var(--accent); } diff --git a/django/contrib/admin/static/admin/css/responsive.css b/django/contrib/admin/static/admin/css/responsive.css index 9ce4f67bf22..e3923448ac7 100644 --- a/django/contrib/admin/static/admin/css/responsive.css +++ b/django/contrib/admin/static/admin/css/responsive.css @@ -43,7 +43,7 @@ input[type="submit"], button { justify-content: flex-start; } - #branding h1 { + #site-name { margin: 0 0 8px; line-height: 1.2; } @@ -432,7 +432,7 @@ input[type="submit"], button { padding: 15px 20px; } - .login #branding h1 { + .login #site-name { margin: 0; } diff --git a/django/contrib/admin/templates/admin/base_site.html b/django/contrib/admin/templates/admin/base_site.html index d83ac0df9b6..4405998164e 100644 --- a/django/contrib/admin/templates/admin/base_site.html +++ b/django/contrib/admin/templates/admin/base_site.html @@ -3,7 +3,7 @@ {% block title %}{% if subtitle %}{{ subtitle }} | {% endif %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %} {% block branding %} -<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1> +<div id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></div> {% if user.is_anonymous %} {% include "admin/color_theme_toggle.html" %} {% endif %} diff --git a/docs/intro/tutorial07.txt b/docs/intro/tutorial07.txt index 71c13180fe6..7810ad7fad0 100644 --- a/docs/intro/tutorial07.txt +++ b/docs/intro/tutorial07.txt @@ -367,7 +367,7 @@ a section of code like: .. code-block:: html+django {% block branding %} - <h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1> + <div id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a><div> {% endblock %} We use this approach to teach you how to override templates. In an actual diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index d3c38843295..f8a8153a49e 100644 --- a/docs/ref/contrib/admin/index.txt +++ b/docs/ref/contrib/admin/index.txt @@ -2848,9 +2848,13 @@ Templates can override or extend base admin templates as described in .. attribute:: AdminSite.site_header - The text to put at the top of each admin page, as an ``<h1>`` (a string). + The text to put at the top of each admin page, as a ``<div>`` (a string). By default, this is "Django administration". + .. versionchanged:: 5.0 + + In older versions, ``site_header`` was using an ``<h1>`` tag. + .. attribute:: AdminSite.site_title The text to put at the end of each admin page's ``<title>`` (a string). By diff --git a/docs/releases/5.0.txt b/docs/releases/5.0.txt index f6377cd59b9..38b49986c57 100644 --- a/docs/releases/5.0.txt +++ b/docs/releases/5.0.txt @@ -419,6 +419,11 @@ Miscellaneous * :class:`~django.db.models.functions.Now` database function now uses ``LOCALTIMESTAMP`` instead of ``CURRENT_TIMESTAMP`` on Oracle. +* :attr:`.AdminSite.site_header` is now rendered in a ``<div>`` tag instead of + ``<h1>``. Screen reader users rely on heading elements for navigation within + a page. Having two ``<h1>`` elements was confusing and the site header wasn't + helpful as it is repeated on all pages. + .. _deprecated-features-5.0: Features deprecated in 5.0 diff --git a/tests/admin_docs/test_views.py b/tests/admin_docs/test_views.py index 4fe51f3d028..7969f6cd42f 100644 --- a/tests/admin_docs/test_views.py +++ b/tests/admin_docs/test_views.py @@ -27,7 +27,7 @@ class AdminDocViewTests(TestDataMixin, AdminDocsTestCase): self.assertContains(response, "<h1>Documentation</h1>", html=True) self.assertContains( response, - '<h1 id="site-name"><a href="/admin/">Django administration</a></h1>', + '<div id="site-name"><a href="/admin/">Django administration</a></div>', ) self.client.logout() response = self.client.get(reverse("django-admindocs-docroot"), follow=True) @@ -153,7 +153,7 @@ class AdminDocViewTests(TestDataMixin, AdminDocsTestCase): ) self.assertContains( response, - '<h1 id="site-name"><a href="/admin/">Django administration</a></h1>', + '<div id="site-name"><a href="/admin/">Django administration</a></div>', ) finally: utils.docutils_is_available = True