Create a Scrolling Dropdown Menu in Divi & WordPress
Editorial Note We may earn a commission when you visit links from this website.

You're usually here because Divi's default dropdown behavior just broke something important.

A mobile menu runs below the fold. A WooCommerce variation list pushes off-screen. A location selector forces users to scroll inside a tiny box and guess whether more options exist. The quick fix is obvious: add max-height and overflow-y: auto. Sometimes that's enough. Often it isn't.

The core question isn't how to make a scrolling dropdown menu possible. It's how to make it usable.

In practice, I treat this as a three-level problem. First, the CSS-only fix when a menu needs to stop overflowing. Second, a searchable JavaScript dropdown when the list is long enough that scrolling becomes friction. Third, a builder-based mega menu when the content has outgrown the dropdown pattern entirely and needs structure, layout, and stronger interaction design.

Why Your Long Dropdown Menu is Hurting User Experience

A long dropdown usually fails at the moment the user is trying to act fast. They open the menu, see a wall of options, start scrolling, lose their place, and either tap the wrong item or give up. I see this most often in Divi builds with mobile headers, WooCommerce variation dropdowns, and location selectors that grew over time without being reorganized.

The problem is not just height. It is findability.

A scrollable list solves overflow, but it does not solve scanning, keyboard access, nested scrolling on touch devices, or the lack of visual cues that tell users more options exist. That is why the basic CSS fix works for some menus and falls apart on others. If a user already knows the item name, search can beat scrolling. If the list really contains grouped content, promos, icons, or too many top-level choices, a mega menu is often the cleaner pattern.

Long dropdowns usually break UX in a few predictable ways:

  • They slow down selection. Flat lists force users to read line by line instead of spotting a clear category or using search.
  • They hide available options. If the menu clips after a few items and gives no visual hint, people assume the visible list is complete.
  • They create touch conflicts on mobile. Scrolling inside a dropdown that sits inside a scrolling page is awkward, especially near the bottom of the viewport.
  • They fail keyboard users first. Many custom-styled dropdowns look fine with a mouse and immediately fall apart when you tab through them.
  • They expose weak information architecture. A bloated dropdown often points to a header that needs better grouping, fewer choices, or a different layout pattern.

That last point matters more than developers like to admit. Sometimes the right fix is a scrollable menu. Sometimes the menu is carrying too much weight because the header was never structured properly in the first place. If you are still working through that part, it helps to review Divi header structure and navigation patterns before you patch the symptom.

Before you ship any custom dropdown, test it with a tool like the website accessibility checker. It will not replace keyboard testing, screen reader checks, or real device testing, but it catches common accessibility issues early.

Three workable paths

The right fix depends on what the dropdown is doing.

Method Best for Main limitation
CSS scroll fix Standard Divi mobile menus and simple long lists Keeps the menu contained, but users still have to hunt through the list
JavaScript searchable dropdown Long option sets where users know the item name Faster selection, but only if keyboard support and focus handling are built correctly
Builder-based mega menu Complex navigation, grouped links, featured content, multi-column layouts More setup time, and it needs discipline to avoid turning the menu into a landing page

The Quick CSS Fix for Divi Menus

When the menu is already built and you just need it to stop overflowing on mobile, CSS is the fastest fix.

A computer screen showing CSS code for a navigation menu, positioned next to a coffee cup.

Drop this into Divi > Theme Options > Custom CSS or your child theme stylesheet:

/* Make the Divi mobile menu scrollable */
.et_mobile_menu {
  max-height: 70vh;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

/* Keep submenus usable inside the scroll area */
.et_mobile_menu .sub-menu {
  max-height: none;
  overflow: visible;
}

/* Optional: improve tap targets */
.et_mobile_menu li a {
  padding: 12px 20px;
}

/* Optional: prevent the menu from sitting behind other elements */
.et_mobile_menu {
  z-index: 9999;
}

What each line is doing

max-height: 70vh; limits the menu to a percentage of the viewport height, so it won't run off-screen.

overflow-y: auto; adds vertical scrolling only when the content exceeds that height.

-webkit-overflow-scrolling: touch; improves momentum scrolling on iPhones and iPads.

The padding tweak isn't mandatory, but it helps on touch devices. Small tap targets are a common source of accidental clicks.

If you're still refining your header structure, Divi's own layout decisions matter as much as the CSS. This guide to building website headers with Divi is worth reviewing before you start stacking fixes on top of a shaky header setup.

Good enough, but only in the right cases

This method works well when:

  • The menu content is mostly standard navigation and the only problem is height.
  • You need a quick production-safe patch without rewriting markup.
  • The number of items is moderate, and users can still scan visually.

It starts to break down when the menu becomes a data selector instead of navigation.

A scrollable box solves overflow. It doesn't solve choice overload.

Where the CSS-only approach falls short

The biggest limitation is that this pattern only changes the container, not the interaction model. Users still have to manually scroll and visually scan every option. That's fine for a short navigation menu. It's weak for long product filters, large region lists, or dense selectors.

It also carries technical trade-offs. Using max-height with a viewport unit like 65vh is a common fix, but it doesn't account for accessibility issues on small viewports or in horizontal orientation, and it fails to address the performance impact of rendering a potentially massive list of DOM elements, even if they aren't visible (analysis of scrollable mobile menu height fixes).

My default recommendation

Use CSS first when the problem is layout overflow, not selection complexity.

If the user needs to find one item from a long list, don't stop here. A scrolling dropdown menu with no filtering still asks too much from the user.

Building a Searchable Dropdown with JavaScript

When the list of options grows long, scrolling becomes tedious. A searchable dropdown outperforms a basic scrollable list significantly.

A person using a tablet with a searchable dropdown menu displayed on the touchscreen interface.

Usability research shows that dropdown menus with over 20 options cause significant user friction due to excessive scrolling. For these lists, implementing a type-ahead or auto-suggest filter is the best practice to reduce selection time and error rates (research on reducing dropdown friction in forms and filters).

I don't reach for a framework here. A lightweight vanilla JavaScript pattern is usually enough, and it's easier to maintain inside WordPress.

Markup that stays understandable

Start with simple HTML:

<div class="searchable-dropdown" data-dropdown>
  <button class="dropdown-toggle" type="button" aria-expanded="false">
    Select a location
  </button>

  <div class="dropdown-panel" hidden>
    <input
      type="text"
      class="dropdown-search"
      placeholder="Type to filter..."
      aria-label="Filter locations"
    />

    <ul class="dropdown-list" role="listbox">
      <li><button type="button" class="dropdown-option">Amsterdam</button></li>
      <li><button type="button" class="dropdown-option">Berlin</button></li>
      <li><button type="button" class="dropdown-option">Chicago</button></li>
      <li><button type="button" class="dropdown-option">Lisbon</button></li>
      <li><button type="button" class="dropdown-option">Sydney</button></li>
    </ul>
  </div>
</div>

This structure is easy to place inside a Code module, popup, or custom template part.

CSS for containment and clarity

.searchable-dropdown {
  position: relative;
  max-width: 320px;
}

.dropdown-toggle {
  width: 100%;
  text-align: left;
  padding: 12px 16px;
  cursor: pointer;
}

.dropdown-panel {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid #ddd;
  z-index: 9999;
  max-height: 320px;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
}

.dropdown-search {
  width: 100%;
  padding: 12px 16px;
  border: 0;
  border-bottom: 1px solid #eee;
  box-sizing: border-box;
}

.dropdown-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 260px;
  overflow-y: auto;
}

.dropdown-option {
  display: block;
  width: 100%;
  text-align: left;
  padding: 12px 16px;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.dropdown-option:hover,
.dropdown-option:focus {
  background: #f5f5f5;
  outline: none;
}

JavaScript that does the useful part

document.querySelectorAll('[data-dropdown]').forEach(dropdown => {
  const toggle = dropdown.querySelector('.dropdown-toggle');
  const panel = dropdown.querySelector('.dropdown-panel');
  const search = dropdown.querySelector('.dropdown-search');
  const options = dropdown.querySelectorAll('.dropdown-option');

  toggle.addEventListener('click', () => {
    const expanded = toggle.getAttribute('aria-expanded') === 'true';
    toggle.setAttribute('aria-expanded', String(!expanded));
    panel.hidden = expanded;

    if (!expanded) {
      search.focus();
    }
  });

  search.addEventListener('input', () => {
    const query = search.value.toLowerCase().trim();

    options.forEach(option => {
      const match = option.textContent.toLowerCase().includes(query);
      option.parentElement.style.display = match ? '' : 'none';
    });
  });

  options.forEach(option => {
    option.addEventListener('click', () => {
      toggle.textContent = option.textContent;
      toggle.setAttribute('aria-expanded', 'false');
      panel.hidden = true;
      search.value = '';

      options.forEach(item => {
        item.parentElement.style.display = '';
      });
    });
  });

  document.addEventListener('click', event => {
    if (!dropdown.contains(event.target)) {
      toggle.setAttribute('aria-expanded', 'false');
      panel.hidden = true;
    }
  });
});

Where this fits best

This pattern is ideal when users already know the term they're looking for. Think city selectors, staff directories, product attribute labels, or long service-area lists.

For Divi developers who want to control behavior more systematically, the Divi JS API documentation is useful background, especially when you need cleaner event handling inside dynamic layouts.

If users can type the first few letters of the option they want, let them. Don't force scrolling when recall is faster than scanning.

What to watch before shipping

This solution is stronger than CSS alone, but it needs discipline:

  • Keep native button behavior where possible. Don't build every part from div elements.
  • Add keyboard support deliberately. Arrow-key navigation and escape-to-close are worth implementing if the dropdown is central to the flow.
  • Test inside scrollable containers. Absolute-positioned panels can get clipped by parent elements with overflow: hidden.

If that starts to sound like a lot of engineering for what's supposed to be a navigation or category menu, that's your sign to stop building a dropdown and switch to a different pattern.

Creating the Ultimate Mega Menu with Divi Areas Pro

Sometimes the right answer is to stop treating the problem as a dropdown problem.

A long category list, store department menu, or service directory doesn't always need a better scrolling dropdown menu. It often needs grouping, layout, visual hierarchy, and breathing room. That's where a mega menu wins.

Screenshot from https://docs.divimode.com/divi-areas-pro/tutorials/create-mega-menu/

I prefer a mega menu when the user's choice benefits from context. Instead of dumping thirty links into one vertical list, you can separate product families, featured collections, support links, promo blocks, and search into a layout people can easily understand.

Why the mega menu pattern is different

The main advantage isn't decoration. It's structure.

A standard dropdown is one-dimensional. It stacks options and asks the user to scan line by line. A mega menu lets you use columns, headings, icons, images, and spacing to turn a messy list into a navigable layout.

That matters more in Divi than in many builders because you can design the panel in the Visual Builder instead of fighting hard-coded menu markup. If you've seen sites where the navigation feels like an extension of the page design, this is usually why.

For implementation details, this walkthrough on creating a mega menu in Divi shows the core approach.

What works well in practice

The strongest mega menus usually include a mix of elements:

  • Category groups with short headings and compact links
  • A featured path such as “New arrivals” or “Start here”
  • Visual anchors like icons or small product images
  • A search field when the content set is broad
  • Promotional or support blocks kept secondary, not dominant

This layout gives users multiple ways to orient themselves. Some scan headings. Some look for a familiar icon. Some head straight to search.

Why a plugin-based build often beats custom code

You can code a mega menu from scratch, but maintenance becomes the hidden cost. Every custom script, hover state, focus trap, and responsive breakpoint becomes your responsibility. In client work, that's usually the wrong trade.

A plugin-based mega menu keeps the layout editable in Divi Builder. That means content teams can update categories, swap modules, and test alternative layouts without opening a code editor. For agencies, that's a big quality-of-life win.

There's also a UX argument for this approach. For Divi's 2 million+ sites, advanced solutions like Divi Areas Pro, which can use scroll-triggered popups containing custom-designed dropdowns or mega menus, have been shown in A/B tests to cut bounce rates by up to 18% by improving user engagement (comparison of Divi popup plugins and engagement results).

A mega menu is the right tool when the user doesn't need a longer list. They need better organization.

When not to use this approach

It's easy to overbuild.

If the menu only contains a handful of links, a mega menu adds unnecessary visual weight. If the content hierarchy is weak, a larger panel just makes the confusion wider. And if mobile behavior isn't planned early, a beautiful desktop mega menu can collapse into a clumsy stack on small screens.

Here's the simplest way I decide:

Situation Better choice
Mobile menu overflows CSS scroll fix
Long selector with known item names Searchable JS dropdown
Large navigation with groups and featured content Mega menu
Simple menu with fewer choices Keep the default dropdown

The professional advantage

The biggest benefit of the builder-based route is separation of concerns. Design stays in the builder. Interaction settings stay in the plugin. Content editors aren't trapped in code. Developers don't waste time patching edge cases that already have a tested interface.

For WooCommerce-heavy builds, that's often the cleanest line between “works today” and “stays manageable six months from now.”

Ensuring Accessibility and a Fluid Responsive Experience

A long dropdown usually fails in the last 10 percent of the build.

It opens fine on desktop. Then you test with a keyboard, rotate a phone, or try to scroll inside the menu on a smaller screen, and the weak spots show up fast. That is why the method matters. The CSS max-height approach is quick, but it does very little for keyboard behavior on its own. A JavaScript-driven searchable dropdown can improve findability, but only if focus management and ARIA states are handled properly. A builder-based menu with Divi Areas Pro gives you more layout control, but it also gives you more ways to create hidden traps if you do not test the interaction carefully.

A five-point infographic detailing essential features for creating an accessible and responsive universal website menu experience.

What each approach needs to get right

The baseline is the same whether the menu scrolls, filters, or expands into a mega panel.

  • Keyboard access. Users need to Tab to the trigger, open it, move through options, and close it without getting stuck.
  • Visible focus styles. Focus has to be obvious against every menu background and at every breakpoint.
  • Accurate state labels. If a toggle opens content, aria-expanded should update with the actual state.
  • Predictable reading order. Screen readers should encounter items in the same order a sighted user would expect.

If you remove the default browser outline, replace it with something stronger, not something fainter.

CSS, JavaScript, and plugin trade-offs

A CSS-only scrolling dropdown is still the fastest fix for a Divi menu that runs past the viewport. I use it often. But CSS cannot add the behavior users expect from an advanced control. It will not manage arrow-key movement, active descendant patterns, or search interactions.

A custom JavaScript dropdown can do all of that. It can also fail in all of those places if the script only handles clicks. The common mistake is building a control that looks like a native select but behaves worse than a plain list of links.

A Divi Areas Pro mega menu sits in a different category. It is not just solving overflow. It is reorganizing the navigation. That often improves usability more than adding scrollbars or search, especially when the primary issue is poor grouping. The trade-off is testing time. More columns, modules, toggles, and hidden states mean more combinations to verify across devices.

Responsive behavior is mostly a height problem

Width gets the attention. Height causes the bugs.

A dropdown that feels comfortable on a full desktop viewport can become cramped once mobile browser chrome, the admin bar, or a sticky header cuts into the available space. Fixed pixel heights start causing trouble in these scenarios. max-height: 80vh; is usually safer than a hardcoded value, but even that needs testing on touch devices because nested scrolling can fight the page scroll.

These are the view states I check before launch:

  1. Portrait phone
  2. Horizontal phone
  3. Tablet with touch input
  4. Desktop with keyboard only
  5. Zoomed desktop at 200%

That last one catches more menu bugs than people expect.

Practical checks that prevent common failures

Check What to verify
Trigger element Use a real button for toggles, not a clickable div or text wrapper
Focus path Tabbing reaches every interactive item and returns cleanly after close
Escape key Open panels close consistently
Touch behavior Inner scroll areas do not trap the page or jitter during swipe
Overflow chain No parent container clips the dropdown at any breakpoint
Tap targets Links have enough spacing for thumbs, especially in dense mobile menus

Fixes I keep coming back to

Some problems repeat across almost every Divi build.

  • Use button elements for expandable triggers. That gives you better semantics and fewer event-handling hacks.
  • Avoid hover-only navigation. Touch users need click or tap support, and keyboard users need focus-triggered access.
  • Be careful with overflow: hidden on parent rows and sections. It is one of the main reasons dropdowns get clipped.
  • Keep focus inside complex overlays only when needed. A full-screen mobile menu may need a focus trap. A simple dropdown usually does not.
  • Do not stack too many behaviors into one control. A menu that scrolls, filters, expands submenus, and opens on hover becomes expensive to maintain and much harder to test.

My rule is simple. If the interaction needs a short explanation, it probably needs to be simplified.

Performance Optimization and Troubleshooting Common Issues

The UI can be usable and still be expensive.

A CSS-based scrolling dropdown menu is usually the lightest option, but it still renders the full menu markup. A JavaScript filter adds event handling and DOM updates. A mega menu introduces more layout complexity, more modules, and often more images. None of that is necessarily bad. It just needs restraint.

Performance trade-offs by approach

Here's the practical comparison:

Method Main performance strength Main performance risk
CSS-only Minimal logic and low overhead Large hidden lists still render
Vanilla JS searchable dropdown Better findability without a heavy framework Poorly scoped listeners and DOM updates
Builder-based mega menu Flexible and maintainable content structure Large layouts, images, and animation overhead

The fastest gains usually come from reducing what the browser has to paint and recalculate, not from clever code tricks.

What I optimize first

When a dropdown or mega menu feels sluggish, I look at these in order:

  • Trim the option set. If a list is too long, grouping or filtering helps both speed and usability.
  • Limit media inside menus. A mega menu doesn't need oversized images.
  • Scope JavaScript carefully. Attach logic to specific components, not the whole document when you can avoid it.
  • Watch hidden overflow chains. They often create layout bugs and force messy workarounds.

For custom JavaScript, keep the code narrow. A small script tied to one component is easier to debug than a global behavior trying to detect every dropdown on the page.

Keep the interaction light. Menus should appear instantly and disappear cleanly. Anything that feels animated for its own sake gets old fast.

Problem, cause, solution

Menu appears behind other content

This is usually a stacking context issue. A parent container with positioning or transform rules can trap the menu below nearby elements.

Fix: raise the menu's z-index, then check parent elements for their own stacking contexts. In Divi, transformed sections and sticky headers are common suspects.

Dropdown gets cut off

The usual cause is overflow: hidden on a parent row, column, or module wrapper.

Fix: remove or override that overflow rule, or move the menu panel outside the clipped container.

Touch scrolling feels jerky on mobile

Nested scroll areas can compete with page scrolling, especially in long mobile menus.

Fix: keep the scrollable area as simple as possible, use touch-friendly spacing, and avoid unnecessary nested containers.

Search filter feels laggy

That often means the script is looping over too many nodes too often, or the menu contains far more markup than it needs.

Fix: simplify each option row, reduce extra wrappers, and only update what changes.

Keyboard focus disappears inside custom dropdowns

This is usually a styling issue, not a JavaScript issue. The browser is moving focus correctly, but your CSS hides the visual cue.

Fix: restore a visible focus state on toggles, search inputs, and options.

A practical rule for choosing the method

If the issue is only height, use CSS.

If users need to locate one item in a long list, build search into the interaction.

If the “dropdown” is really a small information architecture problem, stop pretending it's a dropdown and build a proper mega menu instead.


If you build Divi sites regularly, Divimode is worth keeping in your toolbox. It's a practical resource for advanced Divi interactions, with plugins, tutorials, and documentation that help you build popups, mega menus, and more without turning every UI problem into a custom-code maintenance project.