CSS Advanced Dropdowns
In this page:
Nesting a Submenu Inside a Dropdown
A multi-level dropdown is built by placing another absolutely positioned list inside a dropdown item, hidden by default and shown when that specific item is hovered. Each nesting level needs its own position: relative parent so the inner submenu positions relative to the correct item, not the outer menu.
Example: Nesting a Submenu Inside a Dropdown
<style>
.item {
position: relative;
background: #eee;
padding: 8px;
}
.submenu {
display: none;
position: absolute;
background: lightyellow;
border: 1px solid #ccc;
padding: 8px;
}
.item:hover .submenu {
display: block;
}
</style>
<div class="item">
Tools
<div class="submenu">Sub Item</div>
</div>
Click-Triggered Dropdowns Without JavaScript
Hover does not exist on touch devices, so click-triggered dropdowns are needed for mobile support. A pure-CSS trick uses a hidden checkbox paired with a label: clicking the label toggles the checkbox, and a sibling selector shows the menu when the checkbox is checked.
Example: Click-Triggered Dropdowns Without JavaScript
<style>
.menu {
display: none;
background: lightyellow;
border: 1px solid #ccc;
padding: 8px;
}
#toggle:checked ~ .menu {
display: block;
}
</style>
<input type="checkbox" id="toggle" hidden>
<label for="toggle">Menu</label>
<div class="menu">Shown when the checkbox is checked</div>
Positioning Submenus That Overflow the Viewport
A submenu that always opens to the right can run off the edge of the screen on narrow viewports. A common fix is a modifier class, applied via a media query or JavaScript detection, that flips the submenu's position to open leftward instead.
Example: Positioning Submenus That Overflow the Viewport
<style>
.submenu {
position: absolute;
left: 100%;
background: lightyellow;
border: 1px solid #ccc;
padding: 8px;
}
.submenu.flip {
left: auto;
right: 100%;
}
</style>
<div class="submenu flip">Opens leftward instead of running off-screen</div>
Animating the Submenu Reveal
Instead of an instant display: none to display: block toggle, animating opacity and a small translateY transform on the submenu creates a smoother, more polished fade-and-slide-down reveal, common in production navigation menus.
Example: Animating the Submenu Reveal
<style>
.item {
position: relative;
background: #eee;
padding: 8px;
}
.submenu {
background: lightyellow;
border: 1px solid #ccc;
padding: 8px;
opacity: 0;
transform: translateY(-10px);
transition: opacity 0.2s, transform 0.2s;
}
.item:hover .submenu {
opacity: 1;
transform: translateY(0);
}
</style>
<div class="item">
Menu
<div class="submenu">Fades and slides down</div>
</div>
Keyboard and Screen Reader Considerations for Nested Menus
Multi-level dropdowns built purely with :hover are unreachable by keyboard users, since Tab does not trigger hover states. Combining :focus-within with :hover on every nesting level, and using aria-haspopup/aria-expanded attributes maintained via JavaScript, makes nested menus properly accessible.
Example: Keyboard and Screen Reader Considerations for Nested Menus
<style>
.item {
background: #eee;
padding: 8px;
}
.submenu {
display: none;
background: lightyellow;
border: 1px solid #ccc;
padding: 8px;
}
.item:hover .submenu,
.item:focus-within .submenu {
display: block;
}
</style>
<div class="item">
<a href="#" aria-haspopup="true" aria-expanded="false">Menu</a>
<div class="submenu"><a href="#">Item</a></div>
</div>
Chapter Quiz — Complete all 22 topics to unlock
0/22 topics done
Complete these topics first:
- CSS Combinators
- CSS Pseudo-classes
- CSS Pseudo-elements
- CSS Opacity
- CSS Navigation Bar
- CSS Vertical Navbar
- CSS Horizontal Navbar
- CSS Dropdowns
- CSS Advanced Dropdowns
- CSS Image Gallery
- CSS Image Sprites
- CSS Attribute Selectors
- CSS Forms
- CSS Counters
- CSS Specificity
- CSS Specificity Hierarchy
- CSS Variables
- CSS !important
- CSS Box Sizing
- CSS Media Queries
- CSS Pointer Events
- CSS Outline