An Accessible Mega Menu
582 |583 | Content for the links and text within the mega menu comes from the 584 | Web Content Accessibility Guidelines (WCAG) 2.0. 587 |
588 |Keyboard Accessibility
589 |590 | The accessible mega menu supports keyboard interaction modeled after 591 | the behavior described in the 592 | WAI-ARIA Menu or Menu bar (widget) design pattern, however it also respects users' general expectations for the 595 | behavior of links in a global navigation. The accessible mega menu 596 | implementation permits tab focus on each of the six top-level menu 597 | items. 598 |
599 |-
600 |
-
601 | When one of the menu items has focus, pressing the
602 |
Enter
key,Spacebar
or 603 |Down
arrow will open the submenu panel, and pressing 604 | theLeft
orRight
arrow key will shift 605 | focus to the adjacent menu item. 606 |
607 | - 608 | Links within the submenu panels are included in the tab order when 609 | the panel is open. Links can also be navigated with the arrow keys 610 | or by typing the first character in the link name, which speeds up 611 | keyboard navigation considerably. 612 | 613 |
-
614 | Pressing the
Escape
key closes the submenu and restores 615 | focus to the parent menu item. 616 |
617 |
Screen Reader Accessibility
619 |
620 | The accessible mega menu models its use of WAI-ARIA roles, states, and
621 | properties after those described in the
622 | WAI-ARIA Menu or Menu bar (widget) design pattern
625 | with some notable exceptions, so that it behaves better with screen
626 | reader user expectations for global navigation. The accessible mega
627 | menu doesn't use role="menu"
for the menu container and
628 | role="menuitem"
for each of the links therein; if it did,
629 | assistive technology will no longer interpret the links as
630 | links, but instead as menu items, and the links in the
631 | global navigation will no longer show up when a screen reader user
632 | executes a shortcut command to bring up a list of links in the page.
633 |
635 | This approach maintains the semantic structure of the submenu panels
636 | in the accessible mega menu by omitting role="menu"
and
637 | role="menuitem"
for the global navigation; the links are
638 | organized into lists and separated by headings.
639 |
Usage
641 |HTML
642 |
643 | The HTML for the accessible mega menu is a nav
element
644 | — or any other container element — containing a list. Each
645 | list item contains a link which is followed by a div
or
646 | any other container element which will serve as the pop up panel.
647 |
649 | The panel can contain any HTML content; in the following example, each
650 | panel contains three lists of links. You can explicitly define groups
651 | within the panel, between which a user can navigate quickly using the
652 | left and right arrow keys; in the following example, the CSS class
653 | .sub-nav-group
identifies a navigable group.
654 |
657 | <nav>
658 | <ul class="nav-menu">
659 | <li class="nav-item">
660 | <a href="?music">Music</a>
661 | <div class="sub-nav">
662 | <ul class="sub-nav-group">
663 | <li><a href="?music&genre=0">Alternative</a></li>
664 | <li><a href="?music&genre=3">Country</a></li>
665 | <li>…</li>
666 | </ul>
667 | <ul class="sub-nav-group">
668 | <li><a href="?music&genre=1">Dance</a></li>
669 | <li><a href="?music&genre=4">Electronic</a></li>
670 | <li>…</li>
671 | </ul>
672 | <ul class="sub-nav-group">
673 | <li><a href="?music&genre=2">Hip-Hop/Rap</a></li>
674 | <li><a href="?music&genre=5">Jazz</a></li>
675 | <li>…</li>
676 | </ul>
677 | </div>
678 | </li>
679 | <li class="nav-item">
680 | <a href="?movies">Movies</a>
681 | <div class="sub-nav">
682 | <ul class="sub-nav-group">
683 | <li><a href="?movies&genre=10">New Release</a></li>
684 | <li><a href="?movies&genre=13">Comedy</a></li>
685 | <li>…</li>
686 | </ul>
687 | <ul class="sub-nav-group">
688 | <li><a href="?movies&genre=11">Drama</a></li>
689 | <li><a href="?movies&genre=14">Sci-Fi</a></li>
690 | <li>…</li>
691 | </ul>
692 | <ul class="sub-nav-group">
693 | <li><a href="?movies&genre=12">Horror</a></li>
694 | <li><a href="?movies&genre=15">Documentary</a></li>
695 | <li>…</li>
696 | </ul>
697 | </div>
698 | </li>
699 | </ul>
700 | </nav>
701 |
702 | 704 | By default, the accessible mega menu uses the the following CSS 705 | classes to define the top-level navigation items, panels, groups 706 | within the panels, and the hover, focus, and open states. It also 707 | defines a prefix for unique ID strings, which are required to indicate 708 | the relationship of a top-level navigation item to the panel it 709 | controls. 710 |
711 |
713 | defaults = {
714 | // unique ID's are required to indicate aria-owns, aria-controls and aria-labelledby
715 | uuidPrefix: 'menu',
716 |
717 | // default CSS class used to define the megamenu styling
718 | menuClass: 'menu',
719 |
720 | // default CSS class for a top-level navigation item in the megamenu
721 | topNavItemClass: 'menu-top-nav-item',
722 |
723 | // default CSS class for a megamenu panel */
724 | panelClass: 'menu-panel',
725 |
726 | // default CSS class for a group of items within a megamenu panel
727 | panelGroupClass: 'menu-panel-group',
728 |
729 | // default CSS class for the hover state
730 | hoverClass: 'hover',
731 |
732 | // default CSS class for the focus state
733 | focusClass: 'focus',
734 |
735 | // default CSS class for the open state
736 | openClass: 'open'
737 | }
738 |
739 | 741 | You can optionally override the defaults to use the CSS classes you 742 | may have already defined for your mega menu. 743 |
744 |JavaScript
745 |
746 | Be sure to include the latest version of jQuery and the
747 | accessible-mega-menu.js
script. The following initializes
748 | the first nav element in the document as an
749 | accessibleMegaMenu
, with optional CSS class overrides.
750 |
753 | $("nav:first").accessibleMegaMenu({
754 | // prefix for generated unique id attributes, which are required
755 | // to indicate aria-owns, aria-controls and aria-labelledby
756 | uuidPrefix: "accessible-megamenu",
757 |
758 | // CSS class used to define the megamenu styling
759 | menuClass: 'nav-menu',
760 |
761 | // CSS class for a top-level navigation item in the megamenu
762 | topNavItemClass: 'nav-item',
763 |
764 | // CSS class for a megamenu panel
765 | panelClass: 'sub-nav',
766 |
767 | // CSS class for a group of items within a megamenu panel
768 | panelGroupClass: 'sub-nav-group',
769 |
770 | // CSS class for the hover state
771 | hoverClass: 'hover',
772 |
773 | // CSS class for the focus state
774 | focusClass: 'focus',
775 |
776 | // CSS class for the open state
777 | openClass: 'open'
778 | });
779 |
780 | CSS
782 |
783 | AccessibleMegaMenu
handles the showing and hiding of
784 | panels by adding or removing a CSS class. No inline styles are added
785 | to hide elements or create animation between states.
786 |
788 | This CSS example enables the showing/hiding of and the layout of lists 789 | panels in the mega menu. 790 |
791 |
793 | /* mega menu list */
794 | .nav-menu {
795 | display: block;
796 | list-style: none;
797 | margin: 0;
798 | padding: 0;
799 | position: relative;
800 | z-index: 15;
801 | }
802 |
803 | /* a top level navigation item in the mega menu */
804 | .nav-item {
805 | display: inline-block;
806 | list-style: none;
807 | margin: 0;
808 | padding: 0;
809 | }
810 |
811 | /* first descendant link within a top level navigation item */
812 | .nav-item > a {
813 | border: 1px solid transparent;
814 | display: inline-block;
815 | margin: 0 0 -1px 0;
816 | padding: 0.5em 1em;
817 | position: relative;
818 | }
819 |
820 | /* focus/open states of first descendant link within a top level navigation item */
821 | .nav-item > a:focus,
822 | .nav-item > a.open {
823 | border: 1px solid #dedede;
824 | }
825 |
826 | /* open state of first descendant link within a top level
827 | navigation item */
828 | .nav-item > a.open {
829 | background-color: #fff;
830 | border-bottom: none;
831 | z-index: 1;
832 | }
833 |
834 | /* sub-navigation panel */
835 | .sub-nav {
836 | background-color: #fff;
837 | border: 1px solid #dedede;
838 | display: none;
839 | margin-top: -1px;
840 | padding: 0.5em 1em;
841 | position: absolute;
842 | top: 2.2em;
843 | }
844 |
845 | /* sub-navigation panel open state */
846 | .sub-nav.open {
847 | display: block;
848 | }
849 |
850 | /* list of items within sub-navigation panel */
851 | .sub-nav ul {
852 | display: inline-block;
853 | margin: 0 1em 0 0;
854 | padding: 0;
855 | vertical-align: top;
856 | }
857 |
858 | /* list item within sub-navigation panel */
859 | .sub-nav li {
860 | display: block;
861 | list-style-type: none;
862 | margin: 0;
863 | padding: 0;
864 | }
865 |
866 | Browser Support
868 |869 | The accessible mega menu works in current versions of Chrome, Firefox, 870 | Safari, and Edge. 871 |
872 |