Black Friday: Enjoy a 35% discount on the bundles. Apply the code BLACKFRIDAY35 ( uppercase ) at checkout! Limited offer.
Hello everyone, today we are going to create a circular menu with Tailwind CSS and JavaScript.
A circular menu is a user interface element where menu items are arranged in a circular or radial layout, emanating from a central button or point. This type of menu is often used to save space and create a visually appealing, interactive navigation experience. When triggered, the menu items fan out in a circle or semi-circle around the central button, offering users quick access to various options.
Circular menus are particularly useful in the following scenarios:
ID’s
id="menuContainer"
: This line of code will define the id of the wrapper. This id will be used to target the wrapper in the JavaScript code.
Classesrelative
: This class will make the wrapper element relative to its position on the page.<div
class="relative"
id="menuContainer">
<!-- Menu items goe here -->
</div>
ID’s
id="menuToggle"
: This line of code will define the id of the button. This id will be used to target the button in the JavaScript code.
Classesabsolute
: This class will make the button element absolutely positioned.top-1/2
: This class will position the button at the top of the screen, centered horizontally.left-1/2
: This class will position the button at the left of the screen, centered vertically.transform -translate-x-1/2 -translate-y-1/2
: This class will translate the button by half its width and half its height.<button
id="menuToggle"
class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
Menu
</button>
ID’s
id="circularMenu"
: This line of code will define the id of the link wrapper.
Classesabsolute
: This class will make the link wrapper element absolutely positioned.top-0
: This class will make the link wrapper element start at the top of the page.left-0
: This class will make the link wrapper element start at the left of the page.w-full
: This class will make the link wrapper element take up the full width of the page.h-full
: This class will make the link wrapper element take up the full height of the page.size-full
instead of w-full
and h-full
if you prefer.Classes
menu-item
: This is a custom class that will be used to grab them with the querySelectorAll
method.absolute
: This class will make the link items absolutely positioned.opacity-0
: This class will make the link items start with an opacity of 0.invisible
: This class will make the link items start with an opacity of 0 and also make them invisible.<nav
id="circularMenu"
class="absolute top-0 left-0 w-full h-full">
<a href="#" class="menu-item absolute opacity-0 invisible ">1</a>
<a href="#" class="menu-item absolute opacity-0 invisible ">2</a>
<a href="#" class="menu-item absolute opacity-0 invisible ">3</a>
</nav>
This is the full markup code for the circular menu with Tailwind CSS and JavaScript.Irrelevant classes have been omitted for brevity.
<div class="relative" id="menuContainer">
<button id="menuToggle" class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
Menu
</button>
<nav id="circularMenu" class="absolute top-0 left-0 w-full h-full">
<a href="#" class="menu-item absolute opacity-0 invisible ">1</a>
<a href="#" class="menu-item absolute opacity-0 invisible ">2</a>
<a href="#" class="menu-item absolute opacity-0 invisible ">3</a>
</nav>
</div>
const menuToggle = document.getElementById("menuToggle");
: This line of code will get the button element with the id of “menuToggle” and store it in a variable called menuToggle
.const menuItems = document.querySelectorAll(".menu-item");
: This line of code will get all the link items with the class of “menu-item” and store them in a variable called menuItems
.let isOpen = false;
: This line of code will define a variable called isOpen
and set its value to false
.const menuToggle = document.getElementById("menuToggle");
const menuItems = document.querySelectorAll(".menu-item");
let isOpen = false;
menuToggle.addEventListener("click", toggleMenu);
: This line of code will add an event listener to the button element with the id of “menuToggle” that will call the toggleMenu
function when the button is clicked.menuToggle.addEventListener("click", toggleMenu);
The toggleMenu
function will be used to toggle the visibility of the menu items.
function toggleMenu() {
: This line of code will define a function called toggleMenu
that will be called when the button is clicked.isOpen = !isOpen;
: This line of code will toggle the value of isOpen
from false
to true
and vice versa.menuItems.forEach((item, index) => {
: This line of code will iterate over each link item in the menuItems
array and pass the link item and its index to the anonymous function.const delay = index * 50;
: This line of code will define a variable called delay
and set its value to index * 50
.setTimeout(() => {
: This line of code will use the setTimeout
function to delay the execution of the following code by delay
milliseconds.if (isOpen) {
: This line of code will check if isOpen
is true
.const angle = (index / menuItems.length) * 2 * Math.PI;
: This line of code will define a variable called angle
and set its value to (index / menuItems.length) * 2 * Math.PI
.const radius = 50;
: This line of code will define a variable called radius
and set its value to 50
.const x = Math.cos(angle) * radius + 50;
: This line of code will define a variable called x
and set its value to Math.cos(angle) * radius + 50
.const y = Math.sin(angle) * radius + 50;
: This line of code will define a variable called y
and set its value to Math.sin(angle) * radius + 50
.item.style.left =
${x}%;
: This line of code will set the left
style of the link item to x
percent.item.style.top =
${y}%;
: This line of code will set the top
style of the link item to y
percent.item.classList.remove("opacity-0", "invisible");
: This line of code will remove the opacity-0
and invisible
classes from the link item.item.style.transform =
translate(-50%, -50%) scale(1);
: This line of code will set the transform
style of the link item to translate(-50%, -50%) scale(1)
.} else {
: This line of code will close the menu if isOpen
is false
.item.style.left = "50%";
: This line of code will set the left
style of the link item to 50%
.item.style.top = "50%";
: This line of code will set the top
style of the link item to 50%
.item.classList.add("opacity-0", "invisible");
: This line of code will add the opacity-0
and invisible
classes to the link item.item.style.transform =
translate(-50%, -50%) scale(0.5);
: This line of code will set the transform
style of the link item to translate(-50%, -50%) scale(0.5)
.}, delay);
: This line of code will close the menu if isOpen
is false
.menuToggle.textContent = isOpen ? "Close" : "Menu";
: This line of code will toggle the text of the button if isOpen
is true
or false
.function toggleMenu() {
isOpen = !isOpen;
menuItems.forEach((item, index) => {
const delay = index * 50; // Stagger the animation
setTimeout(() => {
if (isOpen) {
const angle = (index / menuItems.length) * 2 * Math.PI;
const radius = 50; // Reduced radius to bring items closer to the button
const x = Math.cos(angle) * radius + 50;
const y = Math.sin(angle) * radius + 50;
item.style.left = `${x}%`;
item.style.top = `${y}%`;
item.classList.remove("opacity-0", "invisible");
item.style.transform = `translate(-50%, -50%) scale(1)`;
} else {
item.style.left = "50%";
item.style.top = "50%";
item.classList.add("opacity-0", "invisible");
item.style.transform = `translate(-50%, -50%) scale(0.5)`;
}
}, delay);
});
// Toggle the menu button text
menuToggle.textContent = isOpen ? "Close" : "Menu";
}
const menuToggle = document.getElementById("menuToggle");
const menuItems = document.querySelectorAll(".menu-item");
let isOpen = false;
menuToggle.addEventListener("click", toggleMenu);
function toggleMenu() {
isOpen = !isOpen;
menuItems.forEach((item, index) => {
const delay = index * 50; // Stagger the animation
setTimeout(() => {
if (isOpen) {
const angle = (index / menuItems.length) * 2 * Math.PI;
const radius = 50; // Reduced radius to bring items closer to the button
const x = Math.cos(angle) * radius + 50;
const y = Math.sin(angle) * radius + 50;
item.style.left = `${x}%`;
item.style.top = `${y}%`;
item.classList.remove("opacity-0", "invisible");
item.style.transform = `translate(-50%, -50%) scale(1)`;
} else {
item.style.left = "50%";
item.style.top = "50%";
item.classList.add("opacity-0", "invisible");
item.style.transform = `translate(-50%, -50%) scale(0.5)`;
}
}, delay);
});
// Toggle the menu button text
menuToggle.textContent = isOpen ? "Close" : "Menu";
}
This is a simple circular menu that you can recreate with Tailwind CSS and JavaScript. You can customize the colors, number of menu items, and radius to your liking.
Hope you enjoyed this tutorial and have a good day!
/Michael Andreuzza
Own all themes forever for $199.
Includes new themes, updates, unlimited projects, and lifetime support. — No subscription required!