Dropdown Component #
Description #
The Dropdown component is a versatile UI element that displays a list of options when triggered. It supports various styles, directions, and can include nested submenus. The component can be triggered by click or hover events.
Examples and Classes #
Trigger Types
Click Dropdown
Hover Dropdown
<!-- Click Trigger -->
<div class="dropdown">
<div class="dropdown-box">
Click Dropdown
<i class="fa-solid fa-chevron-down"></i>
</div>
<ul class="dropdown-menu dropdown-bottom">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
</ul>
</div>
<!-- Hover Trigger -->
<div class="dropdown dropdown-bottom dropdown-hover">
<div class="dropdown-box">
Hover Dropdown
<i class="fa-solid fa-chevron-down"></i>
</div>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
</ul>
</div>
Direction Combinations
Right Multi-level
Mixed Directions
<!-- Right Direction with Nested -->
<div class="dropdown">
<div class="dropdown-box">
Right Multi-level
<i class="fa-solid fa-chevron-right"></i>
</div>
<ul class="dropdown-menu dropdown-right">
<li><a href="#">Action</a></li>
<li class="dropdown-submenu">
<a href="#" class="dropdown-submenu-toggle">
Submenu
<i class="fa-solid fa-chevron-right"></i>
</a>
<ul class="dropdown-menu">
<li><a href="#">Submenu Item 1</a></li>
<li><a href="#">Submenu Item 2</a></li>
</ul>
</li>
</ul>
</div>
<!-- Mixed Directions -->
<div class="dropdown">
<div class="dropdown-box">
Mixed Directions
<i class="fa-solid fa-chevron-down"></i>
</div>
<ul class="dropdown-menu dropdown-bottom">
<li><a href="#">Item 1</a></li>
<li class="dropdown-submenu">
<a href="#" class="dropdown-submenu-toggle">
Right Submenu
<i class="fa-solid fa-chevron-right"></i>
</a>
<ul class="dropdown-menu dropdown-right">
<li><a href="#">Submenu Item 1</a></li>
<li class="dropdown-submenu">
<a href="#" class="dropdown-submenu-toggle">
Bottom Submenu
<i class="fa-solid fa-chevron-down"></i>
</a>
<ul class="dropdown-menu dropdown-bottom">
<li><a href="#">Nested Item 1</a></li>
<li><a href="#">Nested Item 2</a></li>
</ul>
</li>
</ul>
</li>
<li class="dropdown-submenu">
<a href="#" class="dropdown-submenu-toggle">
Left Submenu
<i class="fa-solid fa-chevron-left"></i>
</a>
<ul class="dropdown-menu dropdown-left">
<li><a href="#">Submenu Item 1</a></li>
<li class="dropdown-submenu">
<a href="#" class="dropdown-submenu-toggle">
Bottom Submenu
<i class="fa-solid fa-chevron-down"></i>
</a>
<ul class="dropdown-menu dropdown-bottom">
<li><a href="#">Nested Item 1</a></li>
<li><a href="#">Nested Item 2</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Interactive Dropdown Example
Form Dropdown
Filter Options
Sort Options
<!-- Dropdown with Form -->
<div class="dropdown">
<div class="dropdown-box">
Form Dropdown
<i class="fa-solid fa-chevron-down"></i>
</div>
<div class="dropdown-menu dropdown-bottom p-2">
<form class="d-flex flex-column gap-1">
<input type="text" class="form-control" placeholder="Username">
<input type="password" class="form-control" placeholder="Password">
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
</div>
<!-- Dropdown with Checkboxes -->
<div class="dropdown">
<div class="dropdown-box">
Filter Options
<i class="fa-solid fa-chevron-down"></i>
</div>
<ul class="dropdown-menu dropdown-bottom">
<li>
<label class="d-flex align-items-center gap-1">
<input type="checkbox"> Option 1
</label>
</li>
<li>
<label class="d-flex align-items-center gap-1">
<input type="checkbox"> Option 2
</label>
</li>
<li>
<label class="d-flex align-items-center gap-1">
<input type="checkbox"> Option 3
</label>
</li>
</ul>
</div>
<!-- Dropdown with Radio Buttons -->
<div class="dropdown">
<div class="dropdown-box">
Sort Options
<i class="fa-solid fa-chevron-down"></i>
</div>
<ul class="dropdown-menu dropdown-bottom">
<li>
<label class="d-flex align-items-center gap-1">
<input type="radio" name="sort"> Name (A-Z)
</label>
</li>
<li>
<label class="d-flex align-items-center gap-1">
<input type="radio" name="sort"> Name (Z-A)
</label>
</li>
<li>
<label class="d-flex align-items-center gap-1">
<input type="radio" name="sort"> Date (Newest)
</label>
</li>
</ul>
</div>
Multi-level Dropdown Example
Multi-level Dropdown
<div class="dropdown">
<div class="dropdown-box">
Multi-level Dropdown
<i class="fa-solid fa-chevron-down"></i>
</div>
<ul class="dropdown-menu dropdown-bottom">
<li><a href="#">Action</a></li>
<li class="dropdown-submenu">
<a href="#" class="dropdown-submenu-toggle">
Submenu 1
<i class="fa-solid fa-chevron-right"></i>
</a>
<ul class="dropdown-menu dropdown-right">
<li><a href="#">Submenu Item 1</a></li>
<li><a href="#">Submenu Item 2</a></li>
<li class="dropdown-submenu">
<a href="#" class="dropdown-submenu-toggle">
Submenu 1.1
<i class="fa-solid fa-chevron-right"></i>
</a>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
<a class="dropdown-submenu-toggle">
Submenu Item 1.1.1
<i class="fa-solid fa-chevron-right"></i>
</a>
<ul class="dropdown-menu">
<li><a href="#">Submenu Item 1.1.1</a></li>
<li><a href="#">Submenu Item 1.1.2</a></li>
</ul>
</li>
<li><a href="#">Submenu Item 1.1.2</a></li>
</ul>
</li>
</ul>
</li>
<li class="dropdown-submenu">
<a href="#" class="dropdown-submenu-toggle">
Submenu 2
<i class="fa-solid fa-chevron-right"></i>
</a>
<ul class="dropdown-menu">
<li><a href="#">Submenu Item 3</a></li>
<li><a href="#">Submenu Item 4</a></li>
</ul>
</li>
</ul>
</div>
Available Classes
| Class | Description |
|---|---|
| .dropdown | Base class for the dropdown component |
| .dropdown-box | The trigger element that opens the dropdown |
| .dropdown-menu | Container for dropdown items |
| .dropdown-bottom | Opens dropdown below the trigger |
| .dropdown-top | Opens dropdown above the trigger |
| .dropdown-right | Opens dropdown to the right of the trigger |
| .dropdown-left | Opens dropdown to the left of the trigger |
| .dropdown-hover | Enables hover trigger instead of click |
| .dropdown-submenu | Creates a nested dropdown menu |
| .dropdown-submenu-toggle | The trigger element for submenu items |
Layout Variations
The dropdown component supports different layout variations:
- Direction Variations: Bottom, top, right, and left positioning
- Trigger Types: Click or hover activation
- Nested Menus: Multi-level dropdown menus with submenus
- Size Options: Small and large variants available
- Custom Styling: Support for custom colors and borders
File Locations #
| Type | Path |
|---|---|
| SCSS | miz/themes/mizoon/components/dropdown/_index.scss |
| HTML Example | miz/themes/mizoon/components/dropdown/index.html |
| JavaScript | miz/themes/mizoon/components/dropdown/script.js |
SCSS Variables #
$dropdown-box-transition: 0.2s linear;
$dropdown-menu-transition: 1s linear;
$item-dropdown-menu-transition: 0.2s linear;
$icon-submenu-toggle-rotate: 90deg;
$dropdown-box-custom-classes: ".bg-secondary-color, .on-secondary-color, .radius-all-small, .txt-normal, .border-style-solid, .border-primary-color, .bw-1";
$dropdown-menu-custom-classes: ".bg-secondary-color, .on-secondary-color, .radius-all-small, .txt-normal, .bw-1, .border-style-solid, .border-primary-color";
$item-dropdown-menu-custom-classes: ".py-1, .px-2, .on-secondary-color, .txt-normal";
JavaScript Implementation #
The dropdown component includes JavaScript functionality for handling interactions:
- Click and hover event handling
- Submenu support with nested dropdowns
- Keyboard navigation (Escape key to close)
- Click outside to close
- Mobile-friendly interactions
Class Structure
| Method/Property | Type | Description |
|---|---|---|
| constructor(element) | Method | Initializes the dropdown component |
| init() | Method | Sets up event listeners and initial state |
| toggle() | Method | Toggles the dropdown's visibility |
| open() | Method | Opens the dropdown |
| close() | Method | Closes the dropdown |
| toggleSubmenu(submenu) | Method | Toggles a submenu's visibility |
Below is an example of initializing and managing modal behavior using JavaScript.
JavaScript
class Dropdown {
constructor() {
this.init();
}
init() {
document.querySelectorAll('.dropdown').forEach(dropdown => {
this.setupDropdown(dropdown);
});
}
setupDropdown(dropdown) {
const box = dropdown.querySelector('.dropdown-box');
const menu = dropdown.querySelector('.dropdown-menu');
const submenus = dropdown.querySelectorAll('.dropdown-submenu');
const isHoverEnabled = dropdown.classList.contains('dropdown-hover') ||
(menu && menu.classList.contains('dropdown-hover'));
if (!isHoverEnabled) {
box.addEventListener('click', (e) => {
e.stopPropagation();
this.toggle(dropdown);
});
}
submenus.forEach(submenu => {
const toggle = submenu.querySelector('.dropdown-submenu-toggle');
if (!isHoverEnabled && toggle) {
toggle.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
this.toggleSubmenu(submenu);
});
}
submenu.addEventListener('mouseenter', () => {
if (window.innerWidth > 768 && isHoverEnabled) {
this.openSubmenu(submenu);
}
});
submenu.addEventListener('mouseleave', () => {
if (window.innerWidth > 768 && isHoverEnabled) {
this.closeSubmenu(submenu);
}
});
});
if (!isHoverEnabled) {
document.addEventListener('click', (e) => {
if (!dropdown.contains(e.target)) {
this.close(dropdown);
}
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
this.close(dropdown);
}
});
}
}
toggle(dropdown) {
if (dropdown.classList.contains('active')) {
this.close(dropdown);
} else {
this.open(dropdown);
}
}
open(dropdown) {
document.querySelectorAll('.dropdown.active').forEach(d => {
if (d !== dropdown) d.classList.remove('active');
});
dropdown.classList.add('active');
}
close(dropdown) {
dropdown.classList.remove('active');
dropdown.querySelectorAll('.dropdown-submenu').forEach(sub => {
this.closeSubmenu(sub);
});
}
toggleSubmenu(submenu) {
if (submenu.classList.contains('active')) {
this.closeSubmenu(submenu);
} else {
this.openSubmenu(submenu);
}
}
openSubmenu(submenu) {
const siblings = Array.from(submenu.parentElement.children)
.filter(child => child !== submenu && child.classList.contains('dropdown-submenu'));
siblings.forEach(sib => this.closeSubmenu(sib));
submenu.classList.add('active');
}
closeSubmenu(submenu) {
submenu.classList.remove('active');
submenu.querySelectorAll('.dropdown-submenu').forEach(child => {
this.closeSubmenu(child);
});
}
}
new Dropdown();
To use this component, you need to:
Include the MIZCHIN JavaScript file in your page.