Why will my Shopify mobile menu not open when I tap it?
If tapping the menu icon on your Shopify store does nothing, the menu is almost always already on the page and stuck at display: none. The rule that opens it slides the panel into position but never restores a display value, so the panel animates correctly while remaining completely invisible. Confirming that takes about two minutes and it points straight at a one line fix.
Everything below is measured from our own themes rather than collected from general advice. We keep a defect catalog of every way a generated theme has failed, and mobile navigation has produced three separate entries in it, dated 3 July, 4 July and 27 August 2026. On 4 September 2026 we also read the CSS of the 20 distinct theme designs we have stored locally and counted how each one writes its hide rule and its open rule. Both sets of numbers are below, including the count that went against what we expected.
How do I tell whether the menu is opening at all?
You do not need a phone for this first step. Open the store on a desktop browser and drag the window narrow until the menu icon appears, which is the same state your phone is in. Then right click the menu icon, choose Inspect, and find the panel element in the markup, usually a div or nav sitting just after the header. Watch that element while you click the icon.
| What happens to the panel element when you tap | What it means | Where to look |
|---|---|---|
| Nothing changes at all, no class is added | The button is not wired to the panel, or the script did not run | Console errors, and the id the script is looking for |
A class such as open or is-open appears, and the panel is still invisible |
The open rule does not restore a display value | The next section. This is the common case |
| The panel is visible in the elements list but sits off screen | A transform or position value is not being reset | Computed styles for transform and right |
| The panel appears behind the page content | Stacking order | The z-index on the panel and on the header |
| The panel shows on desktop too, as a stack of plain links | The rule that hides it stopped matching the element | The section on selectors that stop matching |
With the class visible in the markup, select the panel and read its computed styles. If display still says none while the open class is applied, you have found the fault and the rest of the page is about that.
Why does the panel get the open class and still not appear?
Because display: none removes an element from the layout completely, and no amount of moving it brings it back. A panel that is hidden with both display: none and a transform, and then opened by a rule that only changes the transform, is being slid from one invisible position to another.
Here is the exact shape, taken from a theme in our 3 July 2026 comparison set where the menu never opened on any phone:
.mobile-nav { display: none; transform: translateX(100%); }
.mobile-nav.open { transform: translateX(0); }
Read the second line on its own. It restores the position. It never says anything about display, so the value from the first line still applies, and the panel is not rendered at any point in the animation. There is no console error, nothing fails, and the browser is doing precisely what it was told.
The fix is to give the open rule a display value, and to put it inside the same width band that shows the menu icon so the panel cannot reappear on desktop:
@media (max-width: 820px) {
.mobile-nav.open { display: flex; transform: translateX(0); }
}
Match the display value to what the panel was designed as. If the base rule sets flex-direction or gap, use flex. If it sets grid properties, use grid. Otherwise block is correct. Using flex on a panel that was written for block will open the menu and lay the links out sideways, which reads as a second bug.
What does a correct hide rule and open rule look like?
There are two patterns that work, and one that cannot. On 4 September 2026 we read all 20 theme designs stored in our research folder. Four of them ship no mobile panel rule at all, which leaves 16 with a panel to classify.
| Pattern | Hidden with | Opened with | Designs, of 16 | Works? |
|---|---|---|---|---|
| Display swap | display: none |
display: flex or display: block |
9 | Yes |
| Slide from off screen | transform: translateX(100%) and no display rule |
transform: translateX(0) |
5 | Yes |
| Mismatched pair | display: none and a transform |
the transform only | 2 | No. The menu never appears |
The rule that decides it is simple. Whatever property you hid the panel with, the open rule has to name that same property. A hide that uses two properties needs an open rule that undoes both.
The slide pattern is worth a note because it avoids the problem entirely. If the panel is never set to display: none, and is instead parked off screen with a transform, then the open rule has only one thing to undo and the pair cannot fall out of step. Designs written that way also animate smoothly, because a property that switches straight from none to flex cannot be transitioned. The cost is that the panel stays in the layout, so it needs visibility: hidden or pointer-events: none as well, or its links stay reachable by keyboard while the menu looks closed.
One more count from the same read: 4 of the 16 open the menu with a hidden checkbox and a :checked selector rather than JavaScript. Those menus keep working when a script fails to load, which on mobile connections is not a rare event.
Why does my mobile menu show on desktop as a stack of plain links?
Because the rule that hides it stopped matching the element it was written for. The panel is not appearing because something turned it on. It is appearing because nothing is turning it off, which is the default state of any div.
We recorded this on 3 July 2026. The theme hid its panel with an ID selector, #mnav { display: none }. Shopify sections have to survive being added to a page more than once, so element IDs inside a section are commonly rewritten to include the section ID, which makes them unique. Once the element was renamed, the CSS rule pointed at a name that no longer existed on the page, the hide silently stopped applying, and the panel rendered at every screen width on every page of the store, since the header is site wide chrome.
Two things follow from this, and both are useful even if you never touch Liquid:
- Hide the panel by class, not by ID. Class names are not rewritten, so a rule written against
.mobile-navkeeps matching. In our set, the designs that used classes never showed this fault and the ones that used IDs did. - Duplicate nav text under the header is a CSS matching problem, not a duplicate menu. Deleting menu items in the theme editor will not help, because there is only one menu. It is the second copy of it that is failing to stay hidden.
Can I just force the panel to hide on desktop?
You can, and it is a reasonable repair, but the selector has to name the panel exactly. This is where our worst mobile menu incident came from, and it is worth reading before you write a rule with !important in it.
On 27 August 2026 a safety rule intended to hide a mobile panel on desktop was written against an ID prefix that also matched every section wrapper in the theme. All 13 to 14 sections were hidden at once. Three of six themes we were testing went completely blank above a screen width, and the width was different in each one:
| Theme | Correct up to | Blank at and above |
|---|---|---|
| Theme A | 1040px | 1041px |
| Theme B | 1180px | 1181px |
| Theme C | 1400px | 1401px |
The theme uploaded, validated and rendered without a single error. It was simply invisible above a width, which is covered in more detail in why a Shopify homepage goes blank after installing a theme. The lesson for any hand written repair is short: a rule that hides things with display: none !important should point at one class you can see in the markup, never at a prefix or a pattern, because the cost of matching too much is the whole page and the cost of matching too little is one visible panel.
A safe version looks like this, using the class of the panel itself and a minimum width one pixel above the width where the menu icon disappears:
@media (min-width: 821px) {
.mobile-nav { display: none; }
}
What screen width should I test at?
Whatever width your theme actually switches at, which is not a standard number and is very unlikely to be one you would have guessed. Across the 14 designs in our set that declare both a menu icon and a desktop navigation, the switch happens here:
| Switch width | Designs |
|---|---|
| 640px | 1 |
| 720px | 3 |
| 760px and 768px | 2 |
| 820px and 860px | 2 |
| 900px | 3 |
| 960px | 2 |
| 1040px | 1 |
The median is 840px and the full range runs from 640px to 1040px. Testing at 375px because that is roughly an iPhone, or at 768px because that is roughly an iPad, checks two arbitrary points on that range and tells you nothing about the switch itself. Drag the browser window slowly from wide to narrow and watch the header. The width where the links collapse into an icon is your theme's real breakpoint, and it is the only width where the swap can go wrong.
One result went against what we expected, so it is worth stating plainly. We checked whether the menu icon appears at the same width the desktop links disappear, since a mismatch there would leave a band of widths with no navigation at all. In 14 of 14 designs the two thresholds were identical. That failure mode is real in principle and we did not find a single instance of it, so if your header shows neither a menu icon nor links, look for something else hiding the icon rather than for a breakpoint that is off by a few pixels.
Will theme check tell me any of this?
No, and this is why a broken mobile menu survives so much testing. shopify theme check reads your files and validates Liquid syntax, schema shape, translation keys and asset references. Every fault on this page is valid CSS doing exactly what it says. Not one of them produces a console error, a Liquid error, or a failed upload.
The same blind spot applies to the automated checks that most people run. A check that measures page width catches a store that scrolls sideways on mobile but sees nothing when a panel never opens, because a panel at display: none has no width to measure. The only reliable test is to tap the icon and look, at your own theme's switch width, which takes about ten seconds once you know where that width is.
The order to check things in
- Narrow the desktop window until the menu icon appears. Note that width.
- Tap the icon and watch the panel element in Inspect. Does a class get added?
- If no class appears, check the console for a script error and check that the id in the script matches the id on the panel.
- If the class appears, read the computed
display. If it isnone, add a display value to the open rule inside the mobile width band. - If display is fine, read the computed
transformandz-index. The panel is open and either off screen or underneath something. - Widen the window back to full width and confirm the panel is hidden again, and that no content vanished when you crossed the breakpoint.
Any theme we generate goes through this pair of checks automatically before it is packaged, because we hit all three of these faults in our own output first. If you would rather start from a theme where the mobile menu has already been proved to open, the free theme gallery has live demos you can tap on your own phone before downloading anything.
Frequently asked questions
Why will my Shopify mobile menu not open when I tap the hamburger?
In most cases the panel is already on the page and its computed display is still none. Themes commonly hide the panel with both display none and a transform, then open it with a rule that only restores the transform, so the panel slides into position while remaining unrendered. Inspect the panel element after tapping: if the open class is applied and display still reads none, that is the fault, and the fix is to add a display value to the open rule.
How do I inspect a mobile menu without a phone?
Drag your desktop browser window narrow until the menu icon appears. That is the same state your phone is in, because the theme switches on window width rather than on device type. Right click the menu icon, choose Inspect, find the panel element in the markup, and watch it while you click the icon.
What is the difference between hiding a menu with display none and with a transform?
Display none removes the element from the layout completely, so nothing else you do to it has any visible effect until display is changed back. A transform leaves the element in the layout and moves it off screen, so restoring the transform is enough to bring it back. Mixing the two is where menus break: if you hide with both, the open rule has to undo both.
Why does my Shopify mobile menu show on desktop as a list of stacked links?
The rule that hides it has stopped matching the panel. This happens most often when the panel is hidden by an ID selector and the element ID has been rewritten to make it unique within its section, which Shopify sections commonly do. The panel is not being switched on, it is failing to be switched off, which is the default for any div. Hiding by class rather than by ID avoids it.
My whole page goes blank above a certain screen width. Is that related to the mobile menu?
It can be. A rule written to hide a mobile panel on desktop will hide anything else its selector matches. In one case a guard aimed at a panel was written against an ID prefix that also matched every section wrapper, and three of six themes went blank above 1041px, 1181px and 1401px respectively. Any rule using display none with important should name one class you can see in the markup rather than a prefix or a pattern.
What screen width does a Shopify mobile menu switch at?
There is no standard width. Across 14 theme designs we measured on 4 September 2026 the switch ranged from 640px to 1040px with a median of 840px. Testing at 375px or 768px checks two arbitrary points and can miss the switch entirely. Drag the browser window from wide to narrow and note the width where the links collapse into an icon.
Does shopify theme check catch a mobile menu that will not open?
No. Theme check reads your files and validates Liquid syntax, schema shape, translation keys and asset references. A mismatched hide rule and open rule is valid CSS doing exactly what it says, so it produces no error, no failed upload and nothing in the console. It can only be found by tapping the icon and looking at the result.
Generate a theme that looks like your brand
A complete Shopify 2.0 theme with conversion features built in, ready in minutes. No credit card required.
Generate my theme freeNo Shopify store yet? Start one here, then bring the theme. Themr may earn a commission if you start a paid plan; it does not change what you pay.