Your desktop navigation looks clean. Then you check the same Divi site on a phone and the menu turns into a compromise.
Some links wrap. Some get hidden behind a hamburger. Product categories become harder to browse. Section links on long landing pages become one more tap away than they need to be. That's usually the moment people start searching for a plugin, when the fix is often just better CSS.
A good scroll menu CSS setup keeps navigation visible, swipe-friendly, and predictable. It also fits the way many Divi builds function: WooCommerce category bars, service menus, one-page jump links, account-area tabs, and compact utility navigation inside headers or popups. You don't need a heavy script for that. In many cases, you need a horizontal overflow container, a few guardrails, and the discipline to test the result on real devices.
Why Your Divi Site Needs a Better Scroll Menu
Divi gives you plenty of ways to style menus, but styling isn't the same as solving navigation density. Once a site grows, the menu often becomes the first place where responsive design starts to feel patched together. A row that works perfectly on desktop can become cramped and awkward on smaller screens.
That's where scroll menu CSS earns its place. Instead of forcing items to wrap or disappear into a toggle too early, you let the menu remain a visible row of links and allow horizontal scrolling when space runs out. For category-heavy stores and long single-page layouts, that often feels more natural than hiding everything behind a mobile icon.
Practical rule: If users need to compare sections quickly, keeping links visible usually beats hiding them.
This approach works because it's simple. The browser already knows how to scroll a container. You're not faking movement with JavaScript or bolting on a custom component that becomes fragile later. You're letting standard layout behavior do the hard part.
In Divi projects, I reach for this pattern in a few recurring cases:
- Product category bars: Shoppers can swipe through categories without opening another panel.
- Landing page section menus: Anchor links stay visible as users move through a long page.
- Member or account navigation: Narrow layouts still preserve all destinations in one row.
- Header utility links: Smaller but important actions can stay accessible without crowding the primary nav.
The biggest win is control. You can start with a basic horizontal scroller, then add snap behavior, smooth anchor movement, sticky positioning, and clearer scroll cues only where they help. That's a better workflow than dropping in a one-size-fits-all plugin and fighting it later.
The Foundation A Simple Horizontal Scroll Menu
The core pattern is still the best place to start. If you can build a clean horizontal overflow menu, you can layer everything else on top of it without making the markup messy.

The HTML structure
Use a real navigation element and a simple list. Don't overcomplicate this.
<nav class="scroll-menu" aria-label="Section navigation">
<ul class="scroll-menu__list">
<li><a href="#overview">Overview</a></li>
<li><a href="#features">Features</a></li>
<li><a href="#pricing">Pricing</a></li>
<li><a href="#reviews">Reviews</a></li>
<li><a href="#faq">FAQ</a></li>
<li><a href="#support">Support</a></li>
</ul>
</nav>
The CSS that makes it scroll
The two key ideas are horizontal overflow and preventing wraps.
.scroll-menu {
overflow-x: auto;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
background: #fff;
border-bottom: 1px solid #e5e7eb;
}
.scroll-menu__list {
display: inline-flex;
flex-wrap: nowrap;
white-space: nowrap;
list-style: none;
margin: 0;
padding: 0;
min-width: max-content;
}
.scroll-menu__list li {
flex: 0 0 auto;
}
.scroll-menu__list a {
display: inline-block;
padding: 0.9rem 1rem;
text-decoration: none;
color: #222;
}
.scroll-menu__list a:hover {
background: #f5f5f5;
}
The browser behavior matters here. The container scrolls because it's allowed to overflow on the x-axis. The links stay in one row because the content doesn't wrap. That combination is the foundation.
A foundational historical milestone for CSS-based scroll menus is the standard horizontal overflow pattern: early practical guides show that a scrollable navigation bar can be created with just
overflow: autoandwhite-space: nowrap, allowing links to stay on one line while the container scrolls horizontally when space is constrained. This pattern remains globally relevant because it solves a core responsive-design problem on small screens and in narrow layouts, especially for content-heavy navigation such as product categories or section tabs, as shown in the W3Schools horizontal scroll menu example.
What usually goes wrong
Most broken versions fail for one of three reasons:
| Problem | Cause | Fix |
|---|---|---|
| Items wrap to a second line | Wrapping wasn't disabled | Add white-space: nowrap and flex-wrap: nowrap |
| Menu won't scroll | Overflow is applied to the wrong element | Put overflow-x: auto on the actual container |
| Links shrink too much | Flex items are allowed to compress | Use flex: 0 0 auto on list items |
For Divi users, this basic pattern is often enough. If your goal is a mobile-friendly category bar or tab-like link row, stop here first and test it before adding anything fancy.
Elevating the Experience with Advanced Scrolling Effects
A menu that merely scrolls is usable. A menu that scrolls with intention feels finished.

Add scroll snap for cleaner swiping
On touch devices, scroll-snap can make horizontal movement feel more controlled. It's useful when your links behave more like tabs or cards than tiny text items.
.scroll-menu {
overflow-x: auto;
scroll-snap-type: x proximity;
}
.scroll-menu__list a {
scroll-snap-align: start;
}
I prefer proximity over mandatory for most menus. It gives users guidance without making the interaction feel rigid. If snapping is too aggressive, the menu starts feeling like it's fighting the swipe.
Smooth the jump for anchor navigation
If those links point to sections on the same page, smooth scrolling removes the abrupt jump. This is one of the easiest wins for one-page Divi layouts.
html {
scroll-behavior: smooth;
}
That's all you need for browsers that support the property. Keep in mind that smooth scrolling improves feel, not structure. If anchor targets sit under a sticky header, you still need to manage offset separately.
A lot of small interaction details matter more than people think. If you're refining the feel of a menu, the same thinking applies across buttons, hovers, and state changes. This guide on implementing magical micro interactions is worth reading because it focuses on subtle behavior instead of decorative effects.
Style the scrollbar instead of hiding it blindly
Some developers remove the scrollbar immediately because they want a cleaner look. I usually don't. A visible scrollbar is still a useful cue, especially on desktop.
For WebKit browsers:
.scroll-menu::-webkit-scrollbar {
height: 8px;
}
.scroll-menu::-webkit-scrollbar-track {
background: #ececec;
}
.scroll-menu::-webkit-scrollbar-thumb {
background: #6200ea;
border-radius: 999px;
}
For Firefox:
.scroll-menu {
scrollbar-width: thin;
scrollbar-color: #6200ea #ececec;
}
The best enhancement is the one that clarifies behavior. If an effect looks polished but makes the menu harder to understand, remove it.
A practical stacking order
When I build these in production, I add effects in this order:
- Start with overflow only: Confirm the menu scrolls and every item remains reachable.
- Then test smooth anchors: This matters only if links move the user around the page.
- Add snap last: It's the most opinionated behavior, so it should be opt-in.
That order saves time. It also keeps you from debugging three moving parts when the core problem is just the wrong element handling overflow.
Creating a Sticky Scrolling Navigation Bar
A horizontal menu becomes more useful when it stays available while the user moves down the page. That's where position: sticky fits. It gives you a persistent navigation row without forcing the heavy-handed behavior of a permanently fixed header.

The basic sticky pattern
.sticky-scroll-menu {
position: sticky;
top: 0;
z-index: 1000;
background: #fff;
border-bottom: 1px solid #ddd;
overflow-x: auto;
}
.sticky-scroll-menu ul {
display: inline-flex;
flex-wrap: nowrap;
white-space: nowrap;
list-style: none;
margin: 0;
padding: 0;
}
That looks easy, and it is, until the layout gets in the way. Sticky elements depend on their surrounding context. If a parent has the wrong overflow behavior, limited height, or a transform that changes stacking and positioning behavior, the menu may stop sticking when you expect it to.
Why sticky fails in real layouts
In Divi, the issue often isn't the sticky rule itself. It's the row, section, or theme header around it.
Check these first:
- Parent overflow: If an ancestor uses
overflow: hidden, sticky can stop behaving as expected. - Insufficient scrolling context: Sticky needs room to scroll within its container.
- Layer conflicts: If the menu sticks but appears under other elements, raise
z-indexand confirm backgrounds are opaque enough.
Sticky navigation should feel present, not intrusive. If users lose content space to a header they didn't ask for, the menu is doing too much.
A quick visual walkthrough helps if you want to compare sticky behavior against a more standard implementation:
Handle mobile differently
This is the part many tutorials skip. A sticky horizontal menu can work well on tablets and desktops, but on phones it can become a screen-space tax. Guidance discussed in the SitePoint forum thread on fixed headers and scrolling behavior notes that fixed or persistent header elements often need media-query exceptions on smaller screens because they can consume too much viewport height and obscure content.
A simple approach:
@media (max-width: 767px) {
.sticky-scroll-menu {
position: static;
}
}
That's often the right call for long mobile pages. Let the menu scroll away naturally and reappear where it belongs.
Using this in a Divi header
If you're building a custom header, put the sticky behavior on the actual menu wrapper, not on every nested row and module. Keep the sticky layer focused and keep its background explicit. If you need the menu inside a broader custom header setup, this walkthrough on creating a global header with Divi is a practical starting point.
The best sticky menu is the one that stays useful without crowding the page. When in doubt, make it less persistent, not more.
Ensuring Your Scroll Menu is Accessible and Responsive
A horizontal menu that scrolls cleanly on your screen can still fail real users fast. Keyboard users need a visible path through the links. Touch users need enough spacing to tap without hitting the wrong item. Divi builders also need to account for the extra wrappers that can hide overflow cues or clip focus styles if the CSS lands on the wrong layer.

Make focus visible
A plain nav with real links already gives you solid keyboard behavior. The failure usually comes from custom styling. I see this often in Divi builds where the default outline gets removed to match the design, then nothing replaces it.
.scroll-menu a:focus-visible {
outline: 3px solid #6200ea;
outline-offset: 3px;
border-radius: 4px;
}
Keep the focus color high-contrast against the menu background. If your header uses blur, transparency, or a dark image, test focus states on the live design, not on a white mockup. In Divi, also check whether any parent container has overflow: hidden;, because that can clip the outline and make a perfectly good focus style look broken.
Show that the menu scrolls
Users miss horizontal overflow all the time, especially when scrollbars are hidden or barely visible on mobile. A small visual cue at the right edge solves a real usability problem. It tells people there is more content off-screen.
One strong pattern comes from Dan Salvatore's article on a CSS-only scrollable navigation bar with a dynamic more arrow. His approach uses a pseudo-element and masking so the cue fades away at the end of the scroll area. If you want a simpler production-friendly version for Divi, start with a gradient fade:
.scroll-menu-wrap {
position: relative;
}
.scroll-menu-wrap::after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 2.5rem;
height: 100%;
pointer-events: none;
background: linear-gradient(to right, rgba(255,255,255,0), #fff);
}
That cue is simple, but effective. On client sites, I pair it with slightly padded link text so the final visible item does not disappear under the fade.
Clear affordances beat minimal styling. If users cannot tell a menu scrolls, the design is hiding a control they need.
Build from the phone width first
Scrollable menus are one of the few cases where mobile-first thinking is not just a philosophy choice. It changes the CSS you write. Circle Monkeys mobile-first approach aligns with the same workflow I use in Divi. Set the smallest layout first, confirm the menu is tappable and readable, then expand spacing and alignment for larger breakpoints.
If you need a refresher on the CSS side of that process, this guide to responsive web design with CSS covers the breakpoint mindset well.
For Divi scroll menus, the practical checks are straightforward:
- Use real navigation markup. Keep the links inside a proper
nav, and add anaria-labelif the menu purpose is not obvious. - Protect tap targets. Short labels help, but spacing matters more. Tight menus create accidental taps and make horizontal swiping harder.
- Keep text readable. Active states, focus styles, and default link colors need enough contrast against the header background.
- Test zoom and keyboard use. Scroll the menu, tab through every item, and confirm the focused link stays visible.
That last point matters in Divi and Divi Areas Pro setups where a menu may live inside a custom header area, a theme builder template, or a conditional popup-style layout. The CSS can be correct while the wrapper still interferes with focus visibility or horizontal overflow. Test the finished implementation where it runs, not just in an isolated code pen.
Troubleshooting and Divi Integration Tips
Most real-world friction stems from this. The CSS is usually straightforward. The hard part is knowing which Divi wrapper is controlling layout.
Fix the common failures first
If your items wrap instead of scrolling, check whether the no-wrap rule is applied to the actual list of links. In many Divi builds, developers put white-space: nowrap on the outer module, but the inner list still uses flex behavior that allows wrapping.
If the menu doesn't scroll, the overflow property is probably on the wrong element. In Divi, the wrapper that needs overflow-x: auto is often not the one you first expect.
If sticky behavior fails, inspect parent sections and rows. Overflow settings on ancestors are frequent culprits, and so are transparent headers that make the stuck menu unreadable against underlying content.
Target the right Divi selectors
For a Divi Menu module, you'll usually work with classes like these:
.et_pb_menu__wraphandles the visible wrapping area.et_pb_menu__menucontains the desktop menu structureul.et-menuis where no-wrap behavior often belongs
A practical pattern looks like this:
.my-scroll-menu .et_pb_menu__wrap {
overflow-x: auto;
overflow-y: hidden;
}
.my-scroll-menu .et_pb_menu__menu {
display: block !important;
}
.my-scroll-menu ul.et-menu {
display: flex;
flex-wrap: nowrap !important;
white-space: nowrap !important;
}
.my-scroll-menu ul.et-menu > li {
flex: 0 0 auto;
}
Add my-scroll-menu as a custom CSS class in the module's Advanced tab so you don't accidentally affect every menu on the site.
Where to place the CSS
For site-wide use, I usually place the final rules in Theme Customizer > Additional CSS or in a child theme stylesheet. For one-off tests, a Code Module can work, but it gets harder to maintain if the pattern spreads across templates.
If your scroll menu links to anchors on the same page and those anchors disappear beneath a sticky header, fix the target offset rather than hacking extra spacing into the menu. This guide on anchor links hidden behind Divi's sticky menu addresses that exact issue.
Using custom menus inside overlays and mega menus
The same rules work inside custom headers, fly-ins, and popup-based navigation. One option is Divimode, which provides tools for building popups, fly-ins, mega menus, and injected content within Divi. In that setup, a horizontal scroll menu can live inside a custom area instead of the theme header, which is useful when you want category navigation in a controlled overlay rather than permanently visible on the page.
That's also where Divi Areas Pro becomes practical. You can build the markup in the builder, assign a custom class, and apply the same overflow and no-wrap rules without changing the whole site header.
Conclusion The Power of Pure CSS Navigation
Pure CSS gets you a lot further than many Divi users expect. For scroll menus, the core pieces are straightforward: reliable markup, controlled overflow, and spacing that still works on touch devices. Build those well, and you can solve a wide range of navigation problems without adding another script that needs maintenance.
That flexibility matters in Divi because these patterns rarely live in one place. The same approach can support product category menus, anchor navigation on long-form pages, account-area tabs, mobile header variations, and custom overlay menus. Most tutorials stop at a single code snippet. The better approach is to understand the pattern, then adapt it inside the Divi modules, templates, and custom areas you already use.
Keep the implementation practical. Start with the simplest horizontal scroller. Add snap points if touch accuracy needs work. Add sticky behavior only when the menu needs to stay in view. Add focus states and visual overflow cues so the menu remains clear for keyboard and touch users.
That is usually the difference between a menu that looks good in the builder and one that holds up on a live site.
If you want to build these navigation patterns inside popups, fly-ins, mega menus, or injected template areas, Divi Areas Pro gives you a clean way to place custom menu layouts in Divi and apply the same CSS-first techniques without rebuilding your header structure.