On a computer the menu is fine. On a phone you tap the three-line button and nothing happens, or it needs two or three taps, or it opens and the links cannot be tapped. Most visitors arrive on a phone, so for them the site has no menu at all. The usual causes are a speed plugin holding back the script that opens the menu, an invisible layer sitting on top of the button, or a menu that was never assigned to the mobile spot. Below is a rebuilt example (not a real client), how to tell which cause you have, and the fix for each.
jQuery is not defined, $ is not a function or Cannot read properties of null means the menu's script did not run (the first three rows below).| Cause | How to spot it | What to do |
|---|---|---|
| A speed plugin delays or defers the menu's script | The menu broke after a speed setting was turned on: "Delay JavaScript execution" or "Load JavaScript deferred" (WP Rocket), "Load JS Deferred" set to Delayed (LiteSpeed Cache), "Aggregate JS-files" (Autoptimize), or a similar option in SiteGround Optimizer or Perfmatters. Typical sign: the first tap does nothing, the second works | Turn that one setting off, clear the cache and test. If the menu works again, turn it back on and add the theme's navigation script and jQuery to that setting's exclusion box (WP Rocket and LiteSpeed both have one; the file is usually named navigation.js, menu.js or the theme's main.js) |
| An older theme's script after a WordPress update | The console shows $ is not a function or a "jQuery.fn..." warning, and the menu stopped after a WordPress update. Older themes used jQuery functions that newer jQuery versions removed | Update the theme. If it has no update, the "Enable jQuery Migrate Helper" plugin restores the old functions while you plan a theme change; it is a stopgap, not a fix |
| A plugin conflict | A red error names a plugin's file, or the menu broke right after a plugin was installed or updated (menu, slider, popup and chat plugins most often) | Use the Health Check & Troubleshooting plugin's troubleshooting mode, which turns plugins off for you only, and switch them back on one at a time. More in the plugin conflict guide |
| Something invisible on top of the button | No console error, and the button does not even change colour when tapped. A sticky header, a cookie banner's empty container, a chat widget's frame or a slider can sit over it | Find the layer with the line in the next section. Then give the header a higher layer than it (in Appearance > Customize > Additional CSS, for example .site-header { position:relative; z-index:999; } with your theme's header class), or shrink the widget's container |
| The menu opens, but behind the page or off screen | The button changes to an X but no links appear, or the page goes dark with nothing on it | Same layer problem in reverse: the opened menu needs a higher z-index than the content in front of it. Also check the menu's text is not white on a white panel (theme Customizer > Colors or Header) |
| No menu assigned to the mobile spot | The button is there but opens an empty panel, or there is no button at all | Classic themes: Appearance > Menus > Manage Locations, and give the "Mobile" or "Primary" location a menu. Block themes: in Appearance > Editor open the header, select the Navigation block and set "Overlay menu" to Mobile. Page builders (Elementor, Divi) set this in the header template's menu widget |
| Sub-menus cannot be opened | The menu opens, but tapping "Services" just closes it or goes to # instead of showing the pages under it | On a phone there is no hover, so the theme needs a small arrow next to each parent item. Turn on the theme's "sub-menu toggle" option if it has one, or give the parent item a real page of its own so the tap leads somewhere useful |
In the browser's phone view, open the Console tab, paste this line and press Enter. It prints the menu button, then whatever element is really on top at its centre. If the second one is not the button (or an icon inside it), that element is blocking the tap:
var b=document.querySelector('.menu-toggle, .hamburger, .elementor-menu-toggle, button[aria-controls], [class*=menu-toggle]');var r=b.getBoundingClientRect();console.log(b, document.elementFromPoint(r.left+r.width/2, r.top+r.height/2))
If it prints an error about null, your theme's button has another name: right-click the button, choose Inspect, and put its class in place of the list at the start.
For most sites this is one setting or one CSS line, a few minutes' work once you know which cause it is. If you would rather hand it over, that is what the box below is for. Related: a site that is hard to use on a phone, changes not showing, and a sidebar that dropped below the post.