From fb49399400e86dd83840053adc039cdd227ded40 Mon Sep 17 00:00:00 2001 From: David Arcos Date: Wed, 7 Oct 2026 18:51:37 +0200 Subject: [PATCH] Stop telling a reader the menu sections are ARIA menus A section of the main menu opens a list of links. It was marked up as an ARIA menu and is not one: the control carried aria-haspopup="true", which means a menu, and the list under it named itself after the control with aria-labelledby on a plain div, which the HTML validator rejects. That is three errors on each of the 253 built pages that carry the menu, and on the home page they are the only errors it has. The way to make them valid is role="menu" on the div and role="menuitem" on each link, and that is a promise this cannot keep. An ARIA menu owes the keyboard arrow keys between the items, a roving tabindex, and Escape to close, and Bootstrap 4 gives none of the three here. A reader who is told it is a menu and then finds a list of links is worse off than one who was told nothing. So two attributes go instead of one arriving. What is left is the disclosure pattern of the ARIA practices, which is what this already is: a control that says whether it is open, and the content it shows. role="button" and aria-expanded stay and carry it. The id of the control goes with the label, because nothing else read it. Measured over the whole build, leaving the frozen copies under /archives/ out: 759 divs took aria-labelledby with no role, 3 on each of 253 pages, and there are none now. 7 aria-haspopup per page become none. No aria-labelledby anywhere pointed at a missing id before or after, which is the other half of the same item of #190, fixed earlier. The menu still works: the three sections open and close on a click, the control flips aria-expanded between true and false, and the first section shows its 10 links. --- themes/pybcn_theme/layouts/partials/nav.html | 27 +++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/themes/pybcn_theme/layouts/partials/nav.html b/themes/pybcn_theme/layouts/partials/nav.html index a233ed94..b06a635a 100644 --- a/themes/pybcn_theme/layouts/partials/nav.html +++ b/themes/pybcn_theme/layouts/partials/nav.html @@ -18,13 +18,32 @@ {{ $currentPage := . }} {{ range .Site.Menus.main }} {{ if .HasChildren }} - {{ $dropdown_id := printf "navbar_dropdown_%s" (.Name | urlize) }} + {{/* A section of the menu that opens a list of links, which + is the disclosure pattern of the ARIA practices: a + control that says whether it is open, and the content + it shows. role="button" and aria-expanded carry that. + + Not an ARIA menu. aria-haspopup="true" means a menu, + and the div under it used to name itself after the + control with aria-labelledby, which the HTML validator + rejects on a div with no role: three errors on each of + the 247 pages. The way to make them valid is + role="menu" on the div and role="menuitem" on each + link, and that is a promise this does not keep. An + ARIA menu owes the keyboard arrow keys between the + items, a roving tabindex, and Escape to close, and + Bootstrap 4 gives none of the three here. A reader who + is told it is a menu and finds a list of links is + worse off than one who was told nothing. Two + attributes go instead of one arriving. + + The id went with the label: nothing else read it. */}}