Fixing mobile nav state with 'autocomplete=off': Obscure HTML attributes FTW
by Ryan Bethel
Photo by Tekton on Unsplash
Updated: February 08, 2023 to include the affects of
bfcache (back/forward cache) on this solution.
Building the enhance.dev site, we used a checkbox for the mobile nav control. This technique is not new and has been written about in lots of other places (i.e. here). But one edge case caused an annoying navigation problem. If you open the mobile nav and follow a link, and then use the back button to return to the previous page, the mobile menu will be open. This is because of the way form elements work in browsers.
The input check box was checked when you navigated away, so the browser tries to help you when you return by restoring the state of that input. This would usually be the desired behavior if this were a normal form. It would allow the user to start where they left off. But as a control for a mobile nav menu, this is very unexpected behavior.
It is a simple problem that a few lines of code could fix.
There is a way! HTML inputs have an
autocomplete attribute that has many useful settings.
We can set the value to
autocomplete=”off” to solve this problem.
This tells the browser not to try to restore the checkbox state even when the back button is pressed.
bfcache(back/forward cache) in some browsers can interfere with this
autocompletesetting. This fix works for Enhance/Begin/Architect projects because they set the
Cache-Control:no-storeheader for HTML content which blocks the
<input id="burger-control" class="absolute opacity-0 z-1" type="checkbox" name="open-burger" autocomplete="off" aria-label="Open navigation" />
Ok, so the
autocomplete attribute is not that obscure but using it to fix this edge case was not easy to google for,
so I am putting it out here for anyone trying to do the same (also for future me).
The other lesson here that was reinforced for me is never to count HTML and CSS out.
MDN Docs are your friend.
It doesn’t always work, but when it does, your app will be better for it.
Better how you ask:
- More robust - No fragile code connecting by ids or
- Simpler - An attribute directly on the HTML is collocated and with the thing it controls.