Step by Step guide | Customisable WordPress Mega Menu | Code

You are here:

Summary

I have remediated almost 100+ WordPress websites and making the WordPress menu accessible is always a challenging task.

I and also not very happy with my website’s existing design so I thought let’s create a WordPress theme that provides full customization and maximum accessibility.

The first thing that comes to mind is the mega-menu of the theme should be accessible and can be customized as per the owner’s requirements.

So Hi I am shadab saifi bringing my research code to share with you guys. Here is my step-by-step guide to make accessible WordPress mega-menu.

Give Credit

This code is free to use and modify by just adding the below HTML to the footer of your website for Credits.

<p>Mega-Menu Credit: <a href="https://halfaccessible.com/">https://halfaccessible.com/<a></p>

Step 1: Create custom_functions.php file for WordPress Mega menu

Create a custom_functions.php file in your theme or child theme and paste the below code:

file: custom_functions.php

<?php

function createMenuHierarchy($args = array())
{
    $menu_name = 'header';
    $locations = get_nav_menu_locations();
    $menu =  wp_get_nav_menu_object($locations[$menu_name]);
    $menu_items = wp_get_nav_menu_items($menu->term_id);

    $defaults = array(
        'top-menu-id-prefix' => '',
        'top-menu-classes' => '',
        'top-menu-item-id-prefix' => '',
        'top-menu-item-classes' => '',
        'top-menu-item-anchor-classes' => '',

        'dropdown-button-id-prefix' => '',
        'dropdown-button-classes' => '',

        'dropdown-ul-classes' => '',
        'dropdown-li-classes' => '',
        'dropdown-a-classes' => '',

    );

    $finalArgs = wp_parse_args($args, $defaults);

    $modifiedMenuItems = array();

    if (isset($menu_items)) {
        foreach ((array) $menu_items as $menu_item) {
            if (!isset($modifiedMenuItems[$menu_item->menu_item_parent])) {
                $modifiedMenuItems[$menu_item->menu_item_parent] =  array();
            }
            array_push($modifiedMenuItems[$menu_item->menu_item_parent], $menu_item);
        }
    }
    renderAllMenuItems($finalArgs, $modifiedMenuItems, 0);
}

function renderAllMenuItems($finalArgs, $modifiedMenuItems, $hierarchyKey)
{
    if ($hierarchyKey == 0) {
        echo '<ul id="' . $finalArgs['top-menu-id-prefix'] . $hierarchyKey . '" class="' . $finalArgs['top-menu-classes'] . '" >';
    } else {
        echo '<ul class="' . $finalArgs['dropdown-ul-classes'] . '" id="drpdwn-container' . $hierarchyKey . '">';
    }
    foreach ($modifiedMenuItems[$hierarchyKey] as $key => $menu) {
        $haschildrenClasses = isset($modifiedMenuItems[$menu->ID]) ? 'has-children' : '';
        if ($hierarchyKey == 0) {
            echo '<li id="' . $finalArgs['top-menu-item-id-prefix'] . $hierarchyKey . '" class="' . $finalArgs['top-menu-item-classes'] . ' ' . $haschildrenClasses . ' " >';
        } else {
            echo '<li class="' . $finalArgs['dropdown-li-classes'] . ' ' . $haschildrenClasses . '" >';
        }
        echo '<a class="' . $finalArgs['top-menu-item-anchor-classes'] . '" href="' . $menu->url . '">' . $menu->title . '</a>';
        if (isset($modifiedMenuItems[$menu->ID])) {
            echo '<button data-toggle-handles="drpdwn-container' . $menu->ID . '" id="' . $finalArgs['dropdown-button-id-prefix'] . $hierarchyKey . '" class="' . $finalArgs['dropdown-button-classes'] . '" >+</button>';
            renderAllMenuItems($finalArgs, $modifiedMenuItems, $menu->ID);
        }
        echo '</li>';
    }
    echo '</ul>';
}

Step 2: include custom_functions.php file into your functions.php file

include(get_template_directory() . '<path>/custom_functions.php');

Step 3: Create mega-menu.js & mega-menu.css file and include them in functions.php

file: mega-menu.js

(function () {
    document.querySelectorAll('button[data-toggle-handles]').forEach(function (singleHandler) {
        singleHandler.setAttribute("aria-expanded", false);
        singleHandler.addEventListener("click", function () {
            singleHandler.setAttribute("aria-expanded", singleHandler.getAttribute("aria-expanded") == "false");
            singleHandler.parentElement.classList.toggle("show");
        });
    });
})();

file: mega-menu.css

:root {
  --backgroundColor: #212529;
  --forgroundColor: #ffffff;
}

.has-children {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-content: center;
  justify-content: flex-start;
  align-items: center;
  position: relative;
}

ul.top-main-menu .has-children > ul ul {
  top: 100%;
}
.has-children > ul {
  position: absolute;
  top: calc(100% + 15px);
  left: 15px;
  display: none;
  padding: 0;
  flex-direction: column;
}

.has-children ul li {
  padding: 15px;
}
.has-children ul li [data-toggle-handles] {
  padding: 0 0 0 15px;
}

.has-children.show > ul {
  display: flex;
  min-width: max-content;
}

[data-toggle-handles] {
  padding: 0;
  background-color: var(--backgroundColor);
  border: 0;
  color: var(--forgroundColor);
}

ul.top-main-menu {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-content: flex-start;
  justify-content: flex-start;
  align-items: center;
  background-color: var(--backgroundColor);
  margin: 0 0;
  list-style: none;
}
ul.top-main-menu ul {
  list-style: none;
}

ul.top-main-menu > li {
  padding: 0 15px 0 5px;
}

ul.top-main-menu > li > a {
  padding: 0 10px 0 5px;
}

@media (max-width: 992px) {
  ul.top-main-menu {
    flex-direction: column;
  }
  ul.top-main-menu > li,
  .has-children ul li {
    width: 100%;
    display: block;
  }
  .has-children.show > ul {
    position: static;
  }
}

ul.top-main-menu li > a {
  text-decoration: none;
}

ul.top-main-menu li > a:focus,
ul.top-main-menu li > button:focus {
  outline: 2px dotted var(--forgroundColor);
}

Include both files in functions.php

function theme_enqueue_scripts()
{
    wp_enqueue_style('mega-menu-style', get_template_directory_uri() . '/assets/css/mega-menu.css', array(), '1.0', 'all');
    wp_enqueue_script('mega-menu-script', get_template_directory_uri() . '/assets/js/mega-menu.js', array(), '1.0', true);
}

add_action('wp_enqueue_scripts', 'theme_enqueue_scripts');

Step 4: Paste below code to display mega-menu in header file

<?php
$args = array(
    'top-menu-id-prefix' => 'main-menu-top',
    'top-menu-classes' => 'top-main-menu',
    'top-menu-item-id-prefix' => 'menu-item-top',
    'top-menu-item-classes' => 'top-main-menu-item',
    'top-menu-item-anchor-classes' => 'top-menu-item-anchor',
    'dropdown-button-id-prefix' => 'custom-menu-handle',
    'dropdown-button-classes' => 'custom-menu-toggle',

    'dropdown-ul-classes' => 'custom-menu-toggle-container',
    'dropdown-li-classes' => 'dropdown-li',
    'dropdown-a-classes' => 'dropdown-li-a',
);

createMenuHierarchy($args); ?>

Screenshots

Image showing mega menu expanded state to 4 levels
Image showing the mega menu expanded state to 4 levels

Image showing mega menu in collapsed state
Image showing the mega menu in the collapsed state

Final conclusion

There are lots of things to add but starting with this code will give you a space to work. The above code will auto-generate the menu no matter what hierarchy you choose.

Share

Share on facebook
Facebook
Share on twitter
Twitter
Share on linkedin
LinkedIn
Share on whatsapp
WhatsApp