How to Create a Custom Right-Click Menu With JavaScript

Stan Georgian
ITNEXT
Published in
5 min readApr 20, 2021

--

Photo by Ilya Pavlov on Unsplash

As the complexity of the web applications and the number of actions the user can perform in a specific direction increases, it becomes increasingly difficult to maximize UX efficiency and also keep the interface clean.

A good approach for this situation is to display the actions a user can take in a customized context menu, rather than creating UI buttons all over the place.

I’ll use Gmail as an example to show what I mean.

Context menu from Gmail

The context menu is a GUI that appears upon user interaction, such as a right-click.

The use of these menus is clear. Imagine how a designer could fit all these options near each email without making the UI look awful.

Without further ado here’s how you can create a custom context menu.

Step I — The Template

The first step is to use HTML and CSS and create the template for the context menu.

To keep this article simple, we’ll define some basic HTML and CSS for a custom context menu with 5 random options.

Raw

And to stylize it a bit, we can use the following CSS code:

RAW

With the code above, we should get something similar with the next screenshot as a starting point.

The UI at this stage

At first, the menu will be hidden and will only appear when the user performs a right-click action. Therefore, we need to update the existing CSS to hide this HTML element.

RAW

By default, it will have the display:none property and when we want to show it we’ll simply add the visible class.

Step II — Display the menu only on right-click

To make this HTML menu visible when right-clicking in the browser, we need to listen for contextmenu events.

RAW

We can bind the event listener directly on the document or we can limit the area that a user can right-click to see the custom context menu.

In our example, the area for right-click is the entire body element.

To display a customized context menu, we’ll need to prevent the default behavior, and then set up, trigger, and position our own menu, exactly what we did in the code above.

At this point, we should have something that looks like this when we right-click.

Step III — Close the menu when the user clicks outside

This menu appears on the interface when we right-click, but because it has no close button, it will be visible forever without the option to be removed.

Let’s make it close when the user clicks outside of it.

To do this, all we have to do is add a click event listener on the same HTML element, and as long as the clicked element is not the context menu, we can remove it.

RAW

Step IV — Animation

Let’s also add some animation to this custom menu and make it appear like this:

Animated context menu

To do this, we need to do the following update in the CSS and replace display property with transform.

RAW
  • transform:scale(0) — will make the element not visible in the initial state because it will have a length and width of 0;
  • transform-origin: top left — will make the element scale starting from the top left corner;

And in the JavaScript code…

RAW

Our menu not only disappears when we left-click outside of it but also when we right-click again. The context menu will be deleted from the initial position and recreated at the new position. For this, we needed to remove the class visible in this function as well.
Also, so that the menu doesn’t appear suddenly at the new position, we used setTimeout. Without it, the animation will have no effect, because both the remove action and the add action are done in the same event loop.

If you want to find out more about the event-loop, then take a look at this YouTube video.

Step V — Prevent the menu from going out of bounds

Lastly, to complete this context menu we should prevent it from going out of bounds. At this point, if you go as close to the edge of the page as possible and right-click, the menu should look like this:

The menu is out of bounds

The idea is to achieve the following:

If we right-click right at the edge of the page, the menu should still be visible and its position shifted to fit the page.

To do this, we can write a function to normalize the position of our context menu.

RAW

This function will first convert the absolute position of the mouse on the page to a position relative to the container element and then it will check if the mouse position plus the width or height of the element exceeds the container limits. If so, it will display the item exactly in the corner, but without it going out of bounds.

Next, we need to use the values that this function returns when we position the context menu.

RAW

Wrap up

Creating a context menu is something very generic where some simple steps need to be fulfilled:

  • bind contextmenu listener on the desired element
  • prevent the default behavior
  • compute the position at which this menu will be displayed
  • show the menu

If you want to use this code in your projects then you can take the code from this Github repository or you can use this NPM package.

--

--