this repo has no description

Fix mobile menu

Hilke Ros 1540761d d3571460

Changed files
+74 -16
members
templates
+74 -16
members/templates/base.html
··· 5 5 <meta charset="UTF-8"> 6 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 7 <title>{% block title %}Indiemusi.ch{% endblock %}</title> 8 - <!-- Add any meta tags, CSS links, or other header elements here --> 9 - <link rel="stylesheet" href="{% static 'css/indiemusich.css' %}"> 8 + <link rel="stylesheet" href="{% static 'css/indiemusich.css' %}"> 10 9 <script src="https://cdn.tailwindcss.com"></script> 10 + <style> 11 + #menu-toggle-button:focus { 12 + outline: 2px solid #2563eb; 13 + outline-offset: 2px; 14 + } 15 + </style> 11 16 </head> 12 17 <body> 13 18 <header class="bg-white shadow-md"> 14 19 <nav class="container mx-auto px-4"> 20 + <input id="menu-toggle-checkbox" type="checkbox" class="hidden peer" aria-hidden="true" tabindex="-1" /> 15 21 <div class="flex items-center justify-between h-16"> 16 22 <div class="flex items-center"> 17 23 <a href="{% url 'home_page' %}" class="text-xl font-bold text-gray-800 hover:text-blue-600"> 18 24 Indiemusi.ch 19 25 </a> 20 26 </div> 21 - <!-- Hamburger for mobile and menu toggle input --> 22 27 <div class="md:hidden flex items-center"> 23 - <input id="menu-toggle" type="checkbox" class="hidden peer" /> 24 - <label for="menu-toggle" class="cursor-pointer flex flex-col justify-center w-8 h-8"> 25 - <span class="block w-8 h-1 bg-gray-700 mb-1 rounded transition-all"></span> 26 - <span class="block w-8 h-1 bg-gray-700 mb-1 rounded transition-all"></span> 27 - <span class="block w-8 h-1 bg-gray-700 rounded transition-all"></span> 28 - </label> 28 + <button id="menu-toggle-button" class="menu-toggle-button flex flex-col justify-center w-8 h-8 focus:outline-none" 29 + aria-expanded="false" aria-controls="mobile-menu"> 30 + <span class="sr-only">Open main menu</span> <span class="block w-8 h-1 bg-gray-700 mb-1 rounded transition-all transform origin-center" id="bar-1"></span> 31 + <span class="block w-8 h-1 bg-gray-700 mb-1 rounded transition-all" id="bar-2"></span> 32 + <span class="block w-8 h-1 bg-gray-700 rounded transition-all transform origin-center" id="bar-3"></span> 33 + </button> 29 34 </div> 30 - <!-- Desktop Menu --> 31 35 <div class="hidden md:flex space-x-4"> 32 36 <a href="{% url 'home_page' %}" class="px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">Home</a> 33 37 <a href="{% url 'members_list' %}" class="px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">Members</a> ··· 36 40 <a href="{% url 'about_page' %}" class="px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">About</a> 37 41 </div> 38 42 </div> 39 - <!-- Move the mobile menu here, as a sibling to the input --> 40 - <div class="peer-checked:block hidden md:hidden mt-2" id="mobile-menu"> 43 + 44 + <div id="mobile-menu" class="peer-checked:block hidden md:hidden mt-2" role="navigation" aria-label="Mobile Navigation"> 41 45 <a href="{% url 'home_page' %}" class="block px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">Home</a> 42 46 <a href="{% url 'members_list' %}" class="block px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">Members</a> 47 + <a href="{% url 'post_list' %}" class="block px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">Articles</a> 43 48 <a href="{% url 'links_list' %}" class="block px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">Resources</a> 44 49 <a href="{% url 'about_page' %}" class="block px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">About</a> 45 50 </div> 46 51 </nav> 47 52 </header> 48 - 49 53 <main role="main"> 50 54 <div class="container mx-auto px-4"> 51 55 {% if messages %} ··· 58 62 </div> 59 63 {% endif %} 60 64 {% block content %} 61 - <!-- Content goes here --> 62 65 {% endblock %} 63 66 </div> 64 67 </main> 65 68 66 69 <footer class="footer mt-auto py-3"> 67 - <!-- Your footer content here --> 68 - </footer> 70 + </footer> 71 + 72 + <script> 73 + document.addEventListener('DOMContentLoaded', function() { 74 + const menuToggleButton = document.getElementById('menu-toggle-button'); 75 + const menuToggleCheckbox = document.getElementById('menu-toggle-checkbox'); 76 + const mobileMenu = document.getElementById('mobile-menu'); 77 + const menuLinks = mobileMenu.querySelectorAll('a'); 78 + 79 + // Function to update ARIA attributes and visually toggle the button 80 + function updateMenuState() { 81 + const isExpanded = menuToggleCheckbox.checked; 82 + menuToggleButton.setAttribute('aria-expanded', isExpanded); 83 + if (isExpanded) { 84 + menuToggleButton.querySelector('.sr-only').textContent = 'Close main menu'; 85 + 86 + // Focus the first link in the mobile menu when it opens 87 + if (menuLinks.length > 0) { 88 + menuLinks[0].focus(); 89 + } 90 + } else { 91 + menuToggleButton.querySelector('.sr-only').textContent = 'Open main menu'; 92 + } 93 + } 94 + 95 + // Sync the button's state with the checkbox 96 + menuToggleButton.addEventListener('click', function() { 97 + menuToggleCheckbox.checked = !menuToggleCheckbox.checked; 98 + updateMenuState(); 99 + }); 100 + 101 + // Handle keyboard navigation for the menu when open 102 + mobileMenu.addEventListener('keydown', function(event) { 103 + if (event.key === 'Escape' && menuToggleCheckbox.checked) { 104 + menuToggleCheckbox.checked = false; 105 + updateMenuState(); 106 + menuToggleButton.focus(); // Return focus to the toggle button 107 + } 108 + }); 109 + 110 + // Close menu if a link is clicked (optional, but common behavior) 111 + mobileMenu.querySelectorAll('a').forEach(link => { 112 + link.addEventListener('click', () => { 113 + if (menuToggleCheckbox.checked) { 114 + menuToggleCheckbox.checked = false; 115 + updateMenuState(); 116 + // Focus is usually lost here, but if the page doesn't reload, 117 + // you might want to return focus to the toggle button. 118 + // However, clicking a link implies navigating, so focus will shift naturally. 119 + } 120 + }); 121 + }); 122 + 123 + // Initialize the ARIA state on page load 124 + updateMenuState(); 125 + }); 126 + </script> 69 127 </body> 70 128 </html>