Hovering a top-level nav item reveals a panel of subpages. Lets you fit more navigation without cluttering the bar.
↑ Hover "Services" or "Projects."
.dropdown { position: relative; }
.dropdown .menu {
position: absolute;
top: 100%;
left: -16px;
margin-top: 6px;
opacity: 0;
visibility: hidden;
transform: translateY(-8px);
/* visibility transitions delay-on-out so the menu stays clickable during fade */
transition:
opacity 0.3s,
transform 0.3s,
visibility 0s 0.3s;
}
.dropdown:hover .menu {
opacity: 1;
visibility: visible;
transform: translateY(0);
transition:
opacity 0.3s,
transform 0.3s,
visibility 0s;
}
When the menu is hidden, we set visibility: hidden, but we delay the transition so the menu remains clickable while it fades out. On hover-in, no delay (it appears immediately). On hover-out, delay matches the opacity transition.
Hover-only menus are inaccessible to keyboard users. Add :focus-within alongside :hover so tabbing into the dropdown reveals the menu:
.dropdown:hover .menu,
.dropdown:focus-within .menu {
opacity: 1; visibility: visible; transform: translateY(0);
}
Hover doesn't exist on touch. On mobile, switch to a tap-to-expand pattern using <details> or a click handler that toggles a class.
Source: Jono Catliff masterclass, 2026-05-19. See masterclass notes.