Skip to content

Commit 74a82a9

Browse files
committed
More accessible menu
1 parent ec2c889 commit 74a82a9

File tree

5 files changed

+106
-70
lines changed

5 files changed

+106
-70
lines changed

src/_includes/nav.html

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,52 @@
1-
<ul
2-
id="NavMenu"
3-
class="flex-col flex-1 hidden w-full gap-6 py-8 text-xl font-semibold lg:flex-row lg:gap-8 lg:items-center lg:py-0 lg:flex lg:justify-end">
4-
<li class="lg:sr-only"><a href="/">Home</a></li>
5-
<li class="relative">
6-
<a href="/about" data-menu-trigger>About</a>
7-
<ul
8-
data-menu-list
9-
class="flex-col hidden gap-6 px-4 py-2 mt-2 border-l-4 border-purple lg:absolute lg:top-full lg:border-4 lg:bg-white lg:left-1/2 lg:translate-x-[-50%] lg:w-[24ch] lg:p-6 rounded font-medium">
10-
<li><a href="/about/" role="menuitem">About DjangoCon US</a></li>
11-
<li><a href="/tickets/" role="menuitem">Tickets</a></li>
12-
<li><a href="/faq/" role="menuitem">FAQ</a></li>
13-
<li><a href="/conduct/" role="menuitem">Code of Conduct</a></li>
14-
<li><a href="/public-health/" role="menuitem">Public Health</a></li>
15-
<li><a href="/opportunity-grants/" role="menuitem">Opportunity Grants</a></li>
16-
<li><a href="/visas/" role="menuitem">Visa Support</a></li>
17-
<li><a href="/organizers/" role="menuitem">Organizers</a></li>
18-
</ul>
19-
</li>
20-
{% comment %}<li><a href="/schedule/">Schedule</a></li>{% endcomment %}
21-
<li><a href="/venue/">Venue</a></li>
22-
<li class="relative">
23-
<a href="/speaking/" data-menu-trigger>Speaking</a>
24-
<ul
25-
data-menu-list
26-
class="flex-col hidden gap-6 px-4 py-2 mt-2 border-l-4 border-purple lg:absolute lg:top-full lg:border-4 lg:bg-white lg:left-1/2 lg:translate-x-[-50%] lg:w-[26ch] lg:p-6 rounded font-medium">
27-
<li><a href="/speaking/">Speaking at DjangoCon US</a></li>
28-
<li><a href="/speaking/speaker-resources/">Speaker Resources</a></li>
29-
</ul>
30-
</li>
31-
<li class="relative">
32-
<a href="/sponsors/" data-menu-trigger>Sponsors</a>
33-
<ul
34-
data-menu-list
35-
class="flex-col hidden gap-6 px-4 py-2 mt-2 border-l-4 border-purple lg:absolute lg:top-full lg:border-4 lg:bg-white lg:left-1/2 lg:translate-x-[-50%] lg:w-[24ch] lg:p-6 rounded font-medium">
36-
<li><a href="/sponsors/">Our Sponsors</a></li>
37-
<li><a href="/sponsors/information/">Sponsorship Prospectus</a></li>
38-
</ul>
39-
</li>
40-
<li><a href="/news/">News</a></li>
41-
<li><a href="{{ site.ticket_link }}" class="button bg-light-blue">Buy Tickets</a></li>
42-
</ul>
1+
<ul class="hidden site-nav lg:flex">
2+
<li class="lg:sr-only"><a href="/">Home</a></li>
3+
<li>
4+
<a href="/about"
5+
data-menu-trigger
6+
aria-haspopup="true"
7+
aria-expanded="false">About</a>
8+
<ul
9+
data-menu-list
10+
role="menu"
11+
class="hidden site-nav-menu">
12+
<li><a href="/about/" role="menuitem">About DjangoCon US</a></li>
13+
<li><a href="/tickets/" role="menuitem">Tickets</a></li>
14+
<li><a href="/faq/" role="menuitem">FAQ</a></li>
15+
<li><a href="/conduct/" role="menuitem">Code of Conduct</a></li>
16+
<li><a href="/public-health/" role="menuitem">Public Health</a></li>
17+
<li><a href="/opportunity-grants/" role="menuitem">Opportunity Grants</a></li>
18+
<li><a href="/visas/" role="menuitem">Visa Support</a></li>
19+
<li><a href="/organizers/" role="menuitem">Organizers</a></li>
20+
</ul>
21+
</li>
22+
{% comment %}
23+
<li><a href="/schedule/">Schedule</a></li>
24+
{% endcomment %}
25+
<li><a href="/venue/">Venue</a></li>
26+
<li>
27+
<a href="/speaking/"
28+
data-menu-trigger
29+
aria-haspopup="true"
30+
aria-expanded="false">Speaking</a>
31+
<ul
32+
data-menu-list
33+
class="hidden site-nav-menu">
34+
<li><a href="/speaking/" role="menuitem">Speaking at DjangoCon US</a></li>
35+
<li><a href="/speaking/speaker-resources/" role="menuitem">Speaker Resources</a></li>
36+
</ul>
37+
</li>
38+
<li>
39+
<a href="/sponsors/"
40+
data-menu-trigger
41+
aria-haspopup="true"
42+
aria-expanded="false">Sponsors</a>
43+
<ul
44+
data-menu-list
45+
class="hidden site-nav-menu">
46+
<li><a href="/sponsors/" role="menuitem">Our Sponsors</a></li>
47+
<li><a href="/sponsors/information/" role="menuitem">Sponsorship Prospectus</a></li>
48+
</ul>
49+
</li>
50+
<li><a href="/news/">News</a></li>
51+
<li><a href="{{ site.ticket_link }}" class="button bg-light-blue">Buy Tickets</a></li>
52+
</ul>

src/_layouts/default.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
<body{% if templateClass %} class="{{ templateClass }}"{% endif %}>
4646
<header id="SiteHeader" class="fixed top-0 z-50 w-full py-4 bg-white lg:py-6 lg:relative">
4747
<div class="wrapper">
48-
<nav class="flex flex-wrap">
48+
<nav class="flex flex-wrap" role="navigation">
4949
<div class="flex items-center justify-between w-full lg:max-w-max">
5050
<a
5151
href="/"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
.site-nav {
2+
@apply flex-col w-full gap-6 py-8 text-xl font-semibold lg:flex-row lg:gap-8 lg:items-center lg:py-0 lg:flex flex-1 lg:justify-end;
3+
}
4+
5+
.site-nav li {
6+
@apply relative;
7+
}
8+
9+
.site-nav a:not(.button):hover {
10+
@apply text-purple underline;
11+
}
12+
13+
.site-nav-menu {
14+
@apply flex-col hidden gap-6 px-4 py-2 mt-2 border-l-4 border-purple lg:absolute lg:top-full lg:border-4 lg:bg-white lg:left-1/2 lg:translate-x-[-50%] lg:w-[24ch] lg:p-6 rounded font-medium;
15+
}
16+
17+
[data-menu-trigger] {
18+
@apply relative flex items-center gap-1;
19+
}
20+
21+
[data-menu-trigger]::after {
22+
@apply block w-5 h-5;
23+
@apply bg-purple;
24+
25+
mask: url('/assets/img/theme/icons/Triangle.svg');
26+
mask-size: cover;
27+
mask-repeat: no-repeat;
28+
29+
@apply rotate-180;
30+
31+
content: '';
32+
}
33+
34+
.site-nav [aria-expanded="true"]::after {
35+
@apply rotate-0;
36+
}

src/assets/css/main.css

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
@import "components/_badge.css";
55
@import "components/_buttons.css";
66
@import "components/_table.css";
7-
87
@import "components/_containers.css";
8+
@import "components/_site-nav.css";
99

1010
@import "tailwindcss/utilities";
1111

@@ -188,25 +188,6 @@
188188
.prose a {
189189
@apply link;
190190
}
191-
192-
193-
/* Nav styles */
194-
[data-menu-trigger] {
195-
@apply relative flex items-center gap-1;
196-
}
197-
198-
[data-menu-trigger]::after {
199-
@apply block w-5 h-5;
200-
@apply bg-purple;
201-
202-
mask: url('/assets/img/theme/icons/Triangle.svg');
203-
mask-size: cover;
204-
mask-repeat: no-repeat;
205-
206-
@apply rotate-180;
207-
208-
content: '';
209-
}
210191
}
211192

212193
@layer utilities {

src/assets/js/main.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
const navToggler = document.getElementById('NavToggler');
2-
const navMenu = document.getElementById('NavMenu');
3-
const allMenus = navMenu.querySelectorAll('[data-menu-list]');
2+
const siteNav = document.querySelector('.site-nav');
3+
const allMenus = siteNav.querySelectorAll('[data-menu-list]');
44

5-
/* TODO: Not accessible */
65
navToggler.addEventListener('click', () => {
76
const siteMain = document.getElementById('SiteMain');
87
const siteFooter = document.getElementById('SiteFooter');
98

10-
if (navMenu.classList.contains('flex')) {
11-
navMenu.classList.replace('flex', 'hidden');
9+
if (siteNav.classList.contains('hidden')) {
10+
siteNav.classList.replace('hidden', 'flex');
1211
} else {
13-
navMenu.classList.replace('hidden', 'flex');
12+
siteNav.classList.replace('flex', 'hidden');
1413
}
1514

1615
/*
@@ -28,6 +27,10 @@ navMenuTriggers.forEach(trigger => {
2827
evt.preventDefault();
2928
const target = trigger.nextElementSibling;
3029

30+
navMenuTriggers.forEach((trigger) => {
31+
trigger.setAttribute('aria-expanded', 'false');
32+
});
33+
3134
allMenus.forEach((menu) => {
3235
if (menu !== target) {
3336
menu.classList.replace('flex', 'hidden');
@@ -36,18 +39,24 @@ navMenuTriggers.forEach(trigger => {
3639

3740
if (target.classList.contains('hidden')) {
3841
target.classList.replace('hidden', 'flex');
42+
trigger.setAttribute('aria-expanded', 'true');
3943
} else {
4044
target.classList.replace('flex', 'hidden');
45+
trigger.setAttribute('aria-expanded', 'false');
4146
}
4247
});
4348
});
4449

4550
// Close all menus when the user clicks outside
4651
document.addEventListener('click', function (evt) {
47-
if (!navMenu.contains(evt.target) && navToggler !== evt.target) {
52+
if (!siteNav.contains(evt.target) && navToggler !== evt.target) {
4853
// Close all menus if you click outside of menu
4954
allMenus.forEach((menu) => {
5055
menu.classList.replace('flex', 'hidden');
5156
});
57+
58+
navMenuTriggers.forEach((trigger) => {
59+
trigger.setAttribute('aria-expanded', 'false');
60+
});
5261
}
5362
});

0 commit comments

Comments
 (0)