How to Preserve the Menu State on Page Load (Using Local Storage)

Final product imageFinal product imageFinal product image
What You’ll Be Creating

In this tutorial, we’ll create a simple static site with Tailwind CSS and then learn how to preserve its menu state on page load.

The first time we visit the site, the menu will be hidden. However, as soon as we open it and close the browser, we’ll use local storage and JavaScript to keep the menu open the next time we visit the site. In fact, it will stay open until we close it again.

Ready for another challenge?

1. Create the Project

As a first step, we have to set up the project structure and decide where we’ll host it.

One option is to develop it locally and then, once ready, upload it to GitHub Pages. I’ve used this method in the past for different demos. For example, take a look at this one that customizes Bootstrap 4 tabs.

An alternative approach is to use CodePen Projects for both the development and hosting. It’s worth noting that depending on your CodePen plan, you’ll be able to host a different number of projects.

For this tutorial, as we haven’t done it before, let’s create a CodePen Project and take advantage of all the powerful features that come with it.

How to create a CodePen Project

By default, CodePen provides various starter project templates. Here, we’ll select the most basic one.

The selected starter template for our CodePen ProjectThe selected starter template for our CodePen ProjectThe selected starter template for our CodePen Project

Our project will include four similar HTML files, an SCSS file that will compile to a CSS one, and a JavaScript file, like this:

The project structureThe project structureThe project structure

Last but not least, you can export and run it from your local machine.

You can export a CodePen Project

2. Tailwind CSS

Instead of creating the styles from scratch, we’re going to make use of Tailwind CSS, a popular new utility-first CSS framework that has gained a lot of traction from developers. Created by Adam Wathan, its philosophy is to move all the complexity to the HTML files by adding pre-existing classes to the elements.

Tailwind CSS frameworkTailwind CSS frameworkTailwind CSS framework

As I always liked this concept, I’ve followed it in the past for some demos like this one. Learn more here:

3. The HTML

All HTML files will contain a header and some dummy content.

Inside the header we will place:

  • The company logo
  • The hamburger icon
  • The navigation menu

We’ll also need to include the following required files:

  • The Tailwind CSS file
  • Our own CSS and JavaScript files

To make the hamburger icon a little more accessible, we’ll use the aria-label, aria-expanded, and aria-controls ARIA attributes. As we’ll see later on, the values of the first two attributes will change depending on the menu state.

Here’s the markup for the index.html page:

Don’t feel overwhelmed by the amount of helper CSS classes. These are all coming from Tailwind CSS (apart from the toggle-button and menu ones that we’ll use in the JavaScript part to reference the target elements).

As this isn’t a Tailwind tutorial, I’m not going to explain what each class does. Most of these are self-explanatory, but there are some others like text-5xl that aren’t so clear, so you’ll have to dig into the documentation or browser console and see its exact use.

Just to give you an idea, consider the classes that we apply to the .menu element along with the generated CSS:

Utility Class Generated CSS
flex display: flex;
transition-property: transform;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
translate-y-full --tw-translate-y: 100%;

4. Toggle the Menu

Each time we click on the menu link, the following actions will happen:

  • We’ll toggle its is-active class. If it contains this class, it will be converted smoothly to a minus icon. 
  • We’ll toggle the translate-y-full class of the menu. This is a Tailwind class that will determine whether the menu will appear or not.
  • Depending on the menu state, we’ll update the aria-label and aria-expanded ARIA attributes.

Here’s the JavaScript code that will implement this functionality:

And the related SCSS styles:

Persist Menu State on Page Load

So far, our menu works great. But let’s go a step further and learn how to preserve its state. That said, the very first time we visit the site, the menu will be invisible. However, as soon as we open it and close the browser, this will remain open the next time we visit the site until we close it again.

This is a perfect case for showing how local storage can solve this kind of request.

Let’s be more specific:

  • Upon hamburger icon click, we’ll store on local storage the menu-state key. Possible values can be open and closed.
Store the menu state in local storageStore the menu state in local storageStore the menu state in local storage
  • When the page loads, we’ll check the value of this key. If the user has already opened the menu, the hamburger icon will receive the is-active class, the menu won’t contain the translate-y-full class, and the ARIA-related attributes will change accordingly.
The open state of the menuThe open state of the menuThe open state of the menu

Let’s look at the JavaScript code that will handle this logic:

Of course, as an improvement, you can prevent the animations from running on page load. But I’ll leave this from now as it’s of secondary importance.

You’ve Learned How to Use Local Storage!

We’ve just finished, folks! Today, we learned to build a CodePen Project that uses Tailwind CSS for its styles and persists its menu state on page load using JavaScript and local storage. I hope you’ve learned one or two new things and you’ll soon be able apply them to your projects.

Feel free to enhance the demo by making the menu even more accessible or adding more Tailwind features. If so, don’t forget to share it with us!

As Tailwind is a hot topic at the moment, I’m planning to write a Tailwind-oriented tutorial that will describe how to customize its default options or combine it with another popular framework like Bootstrap. If you want something specific like this, let us know via social media.

As always, thanks for reading!

More Practical JavaScript Projects

We have a ton of interesting JavaScript tutorials to help you learn. Dig in!

Leave a comment

Your email address will not be published.