Learn how to create a dropdown menu using HTML, CSS, and JavaScript. Follow our step-by-step guide to create a functional and stylish dropdown menu.

Table of Contents
Accessibility is all about making your website as accessible, easy to use, and engaging for all users you might have. In order to make your website more accessible, you can work on improving the overall experience on your site by adding a drop-down menu.
A drop-down menu is a popular navigation feature for websites. It allows users to access multiple options from a single menu item. In this tutorial, we will use HTML, CSS, and JavaScript to create a basic drop-down menu that can be customized to fit your website's design and functionality.
Let's start making an amazing drop-down menu using HTML, CSS, and JavaScript step by step.
Prerequisites:
Before starting this tutorial, you should have a basic understanding of HTML, CSS, and JavaScript. Additionally, you will need a code editor such as Visual Studio Code or Sublime Text to write and save your code.
Source Code
Step 1 (HTML Code):
To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our drop-down menu.
In this code snippet, we can see the markup for a drop-down menu in HTML. The code starts with the doctype declaration and the HTML tag. The lang
attribute is set to en
to specify that the content is in English.
The head section contains a title element to specify the title of the webpage, a meta element to set the character encoding to UTF-8, and another meta element to set the viewport width to the width of the device.
The link element is used to link the HTML file to an external stylesheet named styles.css
. This stylesheet contains the styling rules for the drop-down menu.
In the body section, a container div with the class dropdown-container
is created, which contains a button element with the class dropdown-button main-button
. The button element represents the main part of the dropdown menu, and it contains a span element with the class dropdown-title-icon
that displays an icon, a span element with the class dropdown-title text-truncate
that displays the title of the dropdown menu, and another span element with the class dropdown-arrow
that displays an arrow icon to indicate that the button can be clicked to show the dropdown list.
The dropdown list is contained in a div element with the class dropdown-list-container
. Inside this div, there is another div element with the class dropdown-list-wrapper
that contains a ul element with the class dropdown-list
. This ul element contains the list of items that will be displayed when the dropdown button is clicked.
Lastly, the script tag is used to link the HTML file to an external JavaScript file named script.js
. This script file contains the JavaScript code that enables the drop-down menu to function properly.
After creating the files, paste the following codes below into your file. Make sure to save your HTML document with a .html extension so that it can be properly viewed in a web browser.
This is the basic structure of our dropdown menu using HTML, and now we can move on to styling it using CSS.
Step 2 (CSS Code):
Once the basic HTML structure of the dropdown menu is in place, the next step is to add styling to the dropdown menu using CSS.
Next, we will create our CSS file. In this file, we will use some basic CSS rules to create our drop-down menu.
The @import
rule is used to import the Roboto font from Google Fonts, which is then used to style the font of the dropdown menu.
The *
selector with the ::before
and ::after
pseudo-elements sets the margin and padding of all elements to 0 and uses the border-box box-sizing model.
The :root
selector defines variables using the --
notation to set values for various CSS properties, including background colors, text colors, border radius, and transition times.
The html
and body
selectors set the height of the page to 100% and use flexbox to align the elements vertically.
The button
selector sets the style for all buttons, including the dropdown button, and sets their borders to none, cursors to pointers, background colors to transparent, and outlines to none.
The .text-truncate
class sets the style for text truncation, where the text is cut off if it is too long for the container.
The .dropdown-container
class sets the style for the container of the dropdown menu, including its margin, width, and maximum width.
The .dropdown-title-icon
and .dropdown-arrow
classes set the style for the icon and arrow that appear next to the dropdown title.
The .dropdown-button
class sets the style for the dropdown button, including the font, font size, and padding, and uses the Roboto font.
The .main-button class
sets the style for the main button, including its height, border radius, background color, and transition times.
The .list-button class
sets the style for the list items in the dropdown menu, including their height and transition times.
The .dropdown-list-container
class sets the style for the container of the dropdown list, including its overflow and maximum height.
The .dropdown-list-wrapper
class sets the style for the wrapper of the dropdown list, including its margin, padding, background color, and border radius.
The .dropdown-list
class sets the style for the dropdown list itself, including its position and list style type.
The ul.dropdown-list::before
pseudo-element sets the style for the hover effect of the dropdown list, including its opacity, height, background color, and transition time.
The .floating-icon
class sets the style for the floating icon that appears on the right side of the dropdown list when it is open, including its height, width, position, background color, and transition time.
Finally, several other selectors set the style for various elements within the dropdown menu, such as the dropdown title, list items, and their hover effects.
This will give our dropdown menu an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.
@import url("https://fonts.googleapis.com/css2?family=Roboto&display=swap");
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--bg-color: #222429;
--primary-bg-color: #333740;
--primary-color: #2c62f6;
--text-color: #b1b8ca;
--text-active: #ffffff;
--button-hover-bg-color: #2b2e34;
--border-color: #494d59;
--dropdown-height: 0;
--rotate-arrow: 0;
--translate-value: 0;
--list-opacity: 0;
--transition-time: 0.4s;
--transition-timing: cubic-bezier(0.25, 0.46, 0.45, 0.94);
--border-radius: 1.4rem;
--list-button-height: 4.6rem;
--floating-icon-size: 26;
--floating-icon-top: 0;
--floating-icon-left: 0;
}
html {
font-size: 62.5%;
}
html,
body {
height: 100%;
}
body {
display: flex;
flex-direction: column;
align-items: center;
background-color: var(--bg-color);
padding: 1.5rem;
line-height: 1.4;
}
button {
border: none;
cursor: pointer;
background-color: transparent;
outline: none;
}
svg {
height: 1.6rem;
width: 1.6rem;
}
.text-truncate {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.dropdown-container {
margin-top: 30vh;
display: flex;
flex-direction: column;
width: 100%;
max-width: 34rem;
}
.dropdown-title-icon,
.dropdown-arrow {
display: inline-flex;
}
.dropdown-title {
margin: 0 auto 0 1.8rem;
text-transform: capitalize;
}
.dropdown-button {
font-family: "Roboto", sans-serif;
font-weight: 400;
font-size: 1.7rem;
display: flex;
align-items: center;
padding: 0 1.8rem;
}
.dropdown-button svg {
transition: all var(--transition-time) var(--transition-timing);
fill: var(--text-color);
}
.dropdown-button svg,
.dropdown-button span {
pointer-events: none;
}
.dropdown-button:hover,
.dropdown-button:focus {
color: var(--text-active);
}
.dropdown-button:hover svg,
.dropdown-button:focus svg {
fill: var(--text-active);
}
.main-button {
height: 5.2rem;
border-radius: var(--border-radius);
color: var(--text-color);
background-color: var(--primary-bg-color);
border: 0.1rem solid var(--border-color);
transition: all var(--transition-time) var(--transition-timing);
}
.main-button:focus {
border: 0.1rem solid var(--primary-color);
box-shadow: 0 0 0 0.2rem rgba(44, 98, 246, 0.4);
}
.main-button .dropdown-arrow {
transition: transform var(--transition-time) var(--transition-timing);
transform: rotate(var(--rotate-arrow));
margin-left: 1.8rem;
}
.list-button {
height: var(--list-button-height);
transition: color var(--transition-time) var(--transition-timing);
color: var(--text-color);
overflow: hidden;
cursor: none;
}
.dropdown-list-container {
overflow: hidden;
max-height: var(--dropdown-height);
transition: max-height var(--transition-time) var(--transition-timing);
}
.dropdown-list-wrapper {
margin-top: 1rem;
padding: 1rem;
background-color: var(--primary-bg-color);
border-radius: var(--border-radius);
border: 0.1rem solid var(--border-color);
position: relative;
}
ul.dropdown-list {
position: relative;
list-style-type: none;
}
ul.dropdown-list::before {
content: "";
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 0;
opacity: 0;
height: var(--list-button-height);
background-color: var(--button-hover-bg-color);
transition: all var(--transition-time) linear;
transform: translateY(var(--translate-value));
border-radius: var(--border-radius);
pointer-events: none;
}
ul.dropdown-list:hover::before,
ul.dropdown-list:hover ~ .floating-icon {
opacity: 1;
}
li.dropdown-list-item {
display: flex;
flex-direction: column;
position: relative;
z-index: 1;
opacity: var(--list-opacity);
transition: opacity 0.8s var(--transition-timing);
}
.floating-icon {
height: calc(var(--floating-icon-size) * 1px);
width: calc(var(--floating-icon-size) * 1px);
position: absolute;
top: var(--floating-icon-top);
left: var(--floating-icon-left);
background-color: var(--border-color);
border-radius: 1rem;
pointer-events: none;
opacity: 0;
transition: opacity var(--transition-time) var(--transition-timing);
z-index: 2;
display: inline-flex;
align-items: center;
justify-content: center;
}
.floating-icon svg {
fill: var(--text-active);
}
Step 3 (JavaScript Code):
Finally, we need to create a function to dynamically create menu items and icons in JavaScript. Create a JavaScript file with the name of script.js
and paste the given codes into your JavaScript file. Remember, you’ve to create a file with .js extension.
Created by: Flávio Amaral
const root = document.documentElement;
const dropdownTitleIcon = document.querySelector(".dropdown-title-icon");
const dropdownTitle = document.querySelector(".dropdown-title");
const dropdownList = document.querySelector(".dropdown-list");
const mainButton = document.querySelector(".main-button");
const floatingIcon = document.querySelector(".floating-icon");
const icons = {
linkedin:
"M0 1.146C0 .513.526 0 1.175 0h13.65C15.474 0 16 .513 16 1.146v13.708c0 .633-.526 1.146-1.175 1.146H1.175C.526 16 0 15.487 0 14.854V1.146zm4.943 12.248V6.169H2.542v7.225h2.401zm-1.2-8.212c.837 0 1.358-.554 1.358-1.248-.015-.709-.52-1.248-1.342-1.248-.822 0-1.359.54-1.359 1.248 0 .694.521 1.248 1.327 1.248h.016zm4.908 8.212V9.359c0-.216.016-.432.08-.586.173-.431.568-.878 1.232-.878.869 0 1.216.662 1.216 1.634v3.865h2.401V9.25c0-2.22-1.184-3.252-2.764-3.252-1.274 0-1.845.7-2.165 1.193v.025h-.016a5.54 5.54 0 0 1 .016-.025V6.169h-2.4c.03.678 0 7.225 0 7.225h2.4z",
instagram:
"M8 0C5.829 0 5.556.01 4.703.048 3.85.088 3.269.222 2.76.42a3.917 3.917 0 0 0-1.417.923A3.927 3.927 0 0 0 .42 2.76C.222 3.268.087 3.85.048 4.7.01 5.555 0 5.827 0 8.001c0 2.172.01 2.444.048 3.297.04.852.174 1.433.372 1.942.205.526.478.972.923 1.417.444.445.89.719 1.416.923.51.198 1.09.333 1.942.372C5.555 15.99 5.827 16 8 16s2.444-.01 3.298-.048c.851-.04 1.434-.174 1.943-.372a3.916 3.916 0 0 0 1.416-.923c.445-.445.718-.891.923-1.417.197-.509.332-1.09.372-1.942C15.99 10.445 16 10.173 16 8s-.01-2.445-.048-3.299c-.04-.851-.175-1.433-.372-1.941a3.926 3.926 0 0 0-.923-1.417A3.911 3.911 0 0 0 13.24.42c-.51-.198-1.092-.333-1.943-.372C10.443.01 10.172 0 7.998 0h.003zm-.717 1.442h.718c2.136 0 2.389.007 3.232.046.78.035 1.204.166 1.486.275.373.145.64.319.92.599.28.28.453.546.598.92.11.281.24.705.275 1.485.039.843.047 1.096.047 3.231s-.008 2.389-.047 3.232c-.035.78-.166 1.203-.275 1.485a2.47 2.47 0 0 1-.599.919c-.28.28-.546.453-.92.598-.28.11-.704.24-1.485.276-.843.038-1.096.047-3.232.047s-2.39-.009-3.233-.047c-.78-.036-1.203-.166-1.485-.276a2.478 2.478 0 0 1-.92-.598 2.48 2.48 0 0 1-.6-.92c-.109-.281-.24-.705-.275-1.485-.038-.843-.046-1.096-.046-3.233 0-2.136.008-2.388.046-3.231.036-.78.166-1.204.276-1.486.145-.373.319-.64.599-.92.28-.28.546-.453.92-.598.282-.11.705-.24 1.485-.276.738-.034 1.024-.044 2.515-.045v.002zm4.988 1.328a.96.96 0 1 0 0 1.92.96.96 0 0 0 0-1.92zm-4.27 1.122a4.109 4.109 0 1 0 0 8.217 4.109 4.109 0 0 0 0-8.217zm0 1.441a2.667 2.667 0 1 1 0 5.334 2.667 2.667 0 0 1 0-5.334z",
facebook:
"M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951z",
twitter:
"M5.026 15c6.038 0 9.341-5.003 9.341-9.334 0-.14 0-.282-.006-.422A6.685 6.685 0 0 0 16 3.542a6.658 6.658 0 0 1-1.889.518 3.301 3.301 0 0 0 1.447-1.817 6.533 6.533 0 0 1-2.087.793A3.286 3.286 0 0 0 7.875 6.03a9.325 9.325 0 0 1-6.767-3.429 3.289 3.289 0 0 0 1.018 4.382A3.323 3.323 0 0 1 .64 6.575v.045a3.288 3.288 0 0 0 2.632 3.218 3.203 3.203 0 0 1-.865.115 3.23 3.23 0 0 1-.614-.057 3.283 3.283 0 0 0 3.067 2.277A6.588 6.588 0 0 1 .78 13.58a6.32 6.32 0 0 1-.78-.045A9.344 9.344 0 0 0 5.026 15z",
youtube:
"M8.051 1.999h.089c.822.003 4.987.033 6.11.335a2.01 2.01 0 0 1 1.415 1.42c.101.38.172.883.22 1.402l.01.104.022.26.008.104c.065.914.073 1.77.074 1.957v.075c-.001.194-.01 1.108-.082 2.06l-.008.105-.009.104c-.05.572-.124 1.14-.235 1.558a2.007 2.007 0 0 1-1.415 1.42c-1.16.312-5.569.334-6.18.335h-.142c-.309 0-1.587-.006-2.927-.052l-.17-.006-.087-.004-.171-.007-.171-.007c-1.11-.049-2.167-.128-2.654-.26a2.007 2.007 0 0 1-1.415-1.419c-.111-.417-.185-.986-.235-1.558L.09 9.82l-.008-.104A31.4 31.4 0 0 1 0 7.68v-.123c.002-.215.01-.958.064-1.778l.007-.103.003-.052.008-.104.022-.26.01-.104c.048-.519.119-1.023.22-1.402a2.007 2.007 0 0 1 1.415-1.42c.487-.13 1.544-.21 2.654-.26l.17-.007.172-.006.086-.003.171-.007A99.788 99.788 0 0 1 7.858 2h.193zM6.4 5.209v4.818l4.157-2.408L6.4 5.209z"
};
const listItems = ["Linkedin", "Instagram", "Facebook", "Twitter", "Youtube"];
const iconTemplate = (path) => {
return `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path d="${path}" />
</svg>
`;
};
const listItemTemplate = (text, translateValue) => {
return `
<li class="dropdown-list-item">
<button class="dropdown-button list-button" data-translate-value="${translateValue}%">
<span class="text-truncate">${text}</span>
</button>
</li>
`;
};
const renderListItems = () => {
dropdownList.innerHTML += listItems
.map((item, index) => {
return listItemTemplate(item, 100 * index);
})
.join("");
};
window.addEventListener("load", () => {
renderListItems();
});
const setDropdownProps = (deg, ht, opacity) => {
root.style.setProperty("--rotate-arrow", deg !== 0 ? deg + "deg" : 0);
root.style.setProperty("--dropdown-height", ht !== 0 ? ht + "rem" : 0);
root.style.setProperty("--list-opacity", opacity);
};
mainButton.addEventListener("click", () => {
const listWrapperSizes = 3.5; // margins, paddings & borders
const dropdownOpenHeight = 4.6 * listItems.length + listWrapperSizes;
const currDropdownHeight =
root.style.getPropertyValue("--dropdown-height") || "0";
currDropdownHeight === "0"
? setDropdownProps(180, dropdownOpenHeight, 1)
: setDropdownProps(0, 0, 0);
});
dropdownList.addEventListener("mouseover", (e) => {
const translateValue = e.target.dataset.translateValue;
root.style.setProperty("--translate-value", translateValue);
});
dropdownList.addEventListener("click", (e) => {
const clickedItemText = e.target.innerText.toLowerCase().trim();
const clickedItemIcon = icons[clickedItemText];
dropdownTitleIcon.innerHTML = iconTemplate(clickedItemIcon);
dropdownTitle.innerHTML = clickedItemText;
setDropdownProps(0, 0, 0);
});
dropdownList.addEventListener("mousemove", (e) => {
const iconSize = root.style.getPropertyValue("--floating-icon-size") || 0;
const x = e.clientX - dropdownList.getBoundingClientRect().x;
const y = e.clientY - dropdownList.getBoundingClientRect().y;
const targetText = e.target.innerText.toLowerCase().trim();
const hoverItemText = icons[targetText];
floatingIcon.innerHTML = iconTemplate(hoverItemText);
root.style.setProperty("--floating-icon-left", x - iconSize / 2 + "px");
root.style.setProperty("--floating-icon-top", y - iconSize / 2 + "px");
});
Final Output:

Conclusion:
In this tutorial, we have shown you how to create a basic drop-down menu for your website using HTML, CSS, and JavaScript. We started by creating the HTML structure for the drop-down menu using the select and option elements. Then, we used CSS to style the dropdown menu and make it visually appealing. Finally, we added functionality to the dropdown menu using JavaScript.
By following this tutorial, you should now have a basic understanding of how to create a dropdown menu for your website. You can customize the menu by adding more styling and functionality to fit your website's needs. We encourage you to experiment with different features and design elements to create a unique and functional drop-down menu.
That’s a wrap!
I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.
Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee
And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!
Thanks!
Faraz 😊