Build a Simple Responsive Menu with React and CSS

Jason Melton
4 min readJul 7, 2020

--

I built a little portfolio site for some of my projects. Filled with pride, I shared the link for feedback and got an instant reply. “What is this trash?”

The text is pushed off the screen. All of the navigation links are just gone — four components are impossible to find. My portfolio was a one button page where all you can do is refresh. Refresh all you want, things do not get fresher.

To solve my responsiveness issues, I studied an article on CSS-Tricks about responsive menus and incorporated some of the ideas there to create a responsive menu with React.

Special thanks to Alexandria Pugia for cleaning up my code and Keith Burgia for tips on @media queries.

Feel free to jump to the code on GitHub

The Key

~code here~

Don’t bother skimming the rest of the blog for the trick. This is it: CSS @media Rule. Basically, this rule says “Once, the screen hits this condition, change all the following CSS…”

Using React, I simply created two containers for navigation options. The first, with class “navbar”, displays my navigation options in a typical header menu kinda way. The other, with class “nav-small”, is drop down menu.

In the code above, if the screen size is greater than 44em, the full menu displays. Any smaller than that, you get the drop down menu.

Note: I’ve since learned that many front-end developers ascribe to a “Mobile First” mindset with CSS. This generally means a preference for min-width over max-width media queries. Once it looks good on small screens, it’s more natural to scale up to larger screens. There are many benefits to this approach, but I will leave my code as is for the time being. Something to consider!

My Plan

  1. Create a menu container with separate component for navigation options.
  2. Create a second menu container that is a drop down for the same navigation options.
  3. Change the CSS display property using the @media rule.

The Details

Full Screen Menu Container and Options

First, I built the full screen menu. Nothing special here. It is a simple functional component that displays the options. Remember, since it has a class of “navbar”, it will not display on small screens.

~code here~

The navigation options get a little bit complex.

Sorry, this is a lot! To summarize the above code:

  1. When the component is created, it sets the state to have an “activeItem” of “home.” This is how I select the “home” option to be highlighted with a different color (using CSS) when the component first renders.
  2. The component renders the navigation options by mapping an array of strings into individual divs. The strings are names for the locations you’d like to have on your menu.
  3. The navigation option divs contain a ternary class name that allows me to apply special CSS to the one that is selected based on the component’s state.
  4. The divs also contain an onClick event handler which, using React Router, pushes the user to the same path as the class. Also, if the click happens from the small screen menu, it gets passed the function handleToggle() as props which closes the drop down menu. More on that in the next section.

Small Screen Menu

Next, I built the drop down menu. This is a little more complex than the other container because it has toggle functionality.

~code here~

This second menu has the class “nav-small” which will display on small screens but not on large screens due to the CSS.

CSS Display Properties and @media Rule

I already mentioned this final step above, but will throw the image back down here for posterity.

~code here~

Adding this rule sets which menu will be displayed based on screen size.

The rest of my CSS styles things to look nice for the demo — highlighting the drop down options on hover, etc. I assume you will adjust the CSS to your personal projects so I won’t go through the trouble of explaining all the code but you can check it out here.

If you would like another example, check out my portfolio site where I use the logic of this blog with Semantic UI React for nicer looking results.

Thanks for reading. Hope this helps someone!

--

--

Jason Melton
Jason Melton

Responses (1)