How about a sweet dropdown menu to throw in a tight area of your site? Or maybe use it as a simple navigation tool for your minimalistic layout? Or switch to this smaller menu when the screen shrinks to smaller size.
Table of Contents
- Preliminary Junk
- Menu Component
- Menu CSS
- React Router
To get this going, I made a
create-react-app, installed React Router, deleted any unneeded default code, and set up a file structure that looks like this:
There are essentially four parts:
useStatehook holding a boolean that dictates if the menu should open. I call this
- A function called
setClassNames()which conditionally adds classes to the menu items. The CSS of the classes will animate the menu.
- A function called
pushToRoute()which employs React Router to render a new component after a menu item is clicked.
Menucomponent’s return JSX for rendering the structure and bringing together all the functionality.
The CSS does all the work opening the menu. There are five important parts.
.Menu class is the most outer container. It’s important to give it a property of
The individual menu items will have a
position: absolute;, so they will render based on the nearest component with a position. I want the basis of
position to be the outer div of our
.m-item class is applied to each individual menu item. They are absolutely positioned with an initial
top: 0;. This will render all the items on top of each other at the top of the
em units for
width and all the properties so I can ensure the items will fit perfectly on top of each other and still be responsive (
em units are relative to the font-size of the element).
For aesthetics, I give them a
flexbox properties vertically and horizontally center the text in each div. The
cursor property lets the user know the menu items are clickable. Finally,
transition will animate changing properties applied by the
setClassNames() function and CSS
.m-item:hover adds a small border to the menu items on hover. The added 1 px of border causes the items to move slightly on hover giving them a little bit of life.
.m-logo is a special class added to the first menu item. The
z-index: 1; brings that div to the top so all other divs will hide underneath it.
z-index has a default of 0 so if only one item has it, 1 will be enough to bring it to the top of everything.
A series of classes called
.open-3 cause the animation of the drop down. These classes are applied via
setClassNames() once the the top menu item is clicked.
Once clicked, each item will
transition to the new properties in their
open-# class. Namely, they will drop to the specified
top and new
All the aesthetic aspects of the
Menu component are set up at this point. All that’s left is to set up the React Router so that clicking on the items navigates you to the correct component.
Let’s wire this up in the following three steps:
App.js file is the main run file for the whole project so this is where I set up the basic Router stuff.
App's return with
BrowserRouter so the soon-to-be
Routes will be available to all components contained.
I set up a
Switch so that when one
Route is rendered, the others will be disabled. Then, I define each specific
Route needed for the project (obviously , these are made up for the sake of demonstration).
Menu component is placed outside the
Switch so it will render whenever
App is rendering. This makes it an efficient navigation tool, available on any screen of the app.
Menu component, I import
withRouter and wrap the
Menu with it in the export statement.
Menu props that will allow us to manipulate the
react-router-dom so we have to give our
Menu a parameter of props.
Finally, I set up the function
pushToRoute() which takes a parameter string of a route and pushes our app to that route. Then, it closes the
Menu by calling
The menu items call
onClick and there I define the destination.
I enjoyed making this menu. It’s a very efficient and easy tool that fits in a number of scenarios. I hope you find some of the concepts useful.
I love feedback. Got any suggestions? I’d be happy to add your knowledge to my own. Hit me up in the comments or email me:
Best! Jason Melton.