基于CSS/HTML的移动端手风琴菜单开发需求咨询
Got it, let's build that mobile-friendly accordion menu you need. Here's a complete, lightweight solution using HTML, CSS, and vanilla JavaScript—no frameworks required, so it's perfect for mobile performance.
HTML Structure
First, we'll adjust your base markup to include submenu toggles, nested submenus, and accessibility attributes:
<ul class="nav-menu"> <li> <a href="/about">About</a> </li> <li class="has-submenu"> <div class="menu-item-wrapper"> <a href="/news">News & Updates</a> <button class="submenu-toggle" aria-expanded="false"> <span class="sr-only">Toggle submenu for News & Updates</span> <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor"> <path d="M8 11L3 6L4.41 4.59L8 8.17L11.59 4.59L13 6L8 11Z"/> </svg> </button> </div> <ul class="submenu"> <li><a href="/news/latest">Latest News</a></li> <li><a href="/news/archive">News Archive</a></li> </ul> </li> <li> <a href="/contact">Contact</a> </li> </ul>
- We use a
<button>for the toggle (instead of a div) for native accessibility support. - The
sr-onlytext helps screen reader users understand the toggle's purpose. - Nested
<ul class="submenu">holds the dropdown items.
CSS Styles
This mobile-first CSS handles layout, toggle animations, and responsive behavior:
/* Base reset and mobile-first setup */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: Arial, sans-serif; } .nav-menu { list-style: none; background-color: #f0f0f0; width: 100%; max-width: 400px; /* Adjust to fit your layout */ margin: 20px auto; border-radius: 8px; overflow: hidden; } .nav-menu li { border-bottom: 1px solid #ddd; } .nav-menu li:last-child { border-bottom: none; } .nav-menu a { display: block; padding: 16px 20px; color: #333; text-decoration: none; transition: background-color 0.2s ease; } .nav-menu a:hover { background-color: #e0e0e0; } /* Submenu toggle wrapper - keeps link and arrow aligned */ .has-submenu .menu-item-wrapper { display: flex; justify-content: space-between; align-items: center; } .submenu-toggle { background: none; border: none; padding: 16px 20px; cursor: pointer; color: #333; transition: transform 0.2s ease; } /* Rotate arrow when submenu is open */ .submenu-toggle[aria-expanded="true"] svg { transform: rotate(180deg); } /* Submenu styling with smooth expand/collapse */ .submenu { list-style: none; background-color: #fff; max-height: 0; overflow: hidden; transition: max-height 0.3s ease; } .submenu.open { max-height: 200px; /* Adjust based on how many subitems you have */ } .submenu li { border-bottom: 1px solid #eee; } /* Indent submenu items for hierarchy */ .submenu a { padding-left: 40px; } /* Screen reader only class for accessibility */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; }
JavaScript Interaction
This vanilla JS handles the toggle functionality with event delegation (efficient for dynamic menus):
document.addEventListener('DOMContentLoaded', function() { const navMenu = document.querySelector('.nav-menu'); // Use event delegation to handle toggle clicks navMenu.addEventListener('click', function(e) { const toggleButton = e.target.closest('.submenu-toggle'); if (toggleButton) { e.preventDefault(); // Prevent button from triggering form submits const parentLi = toggleButton.closest('.has-submenu'); const submenu = parentLi.querySelector('.submenu'); const isExpanded = toggleButton.getAttribute('aria-expanded') === 'true'; // Update accessibility attribute and toggle submenu toggleButton.setAttribute('aria-expanded', !isExpanded); submenu.classList.toggle('open'); } }); });
Key Features & Customization Tips
- Clickable Main Links: The main text links (like "News & Updates") still work as regular navigation links—only the arrow triggers the submenu.
- Accessibility: Includes
aria-expandedattributes and screen-reader-only text to support assistive technologies. - Smooth Animations: Uses CSS transitions for the submenu expand/collapse and arrow rotation.
- Customization:
- Change colors by modifying
background-colorandcolorvalues. - Replace the SVG arrow with an icon font or image.
- Adjust padding/max-height values to match your design system.
- Change colors by modifying
内容的提问来源于stack exchange,提问作者Brendan
相关产品推荐
相关产品推荐

