CDP Menu Style Guide
The definitive reference for all navigation patterns on UX Design Warrior — selectors, rules, visual samples, and both deployment scenarios.
Two Deployment Scenarios
Every page on UXDW falls into one of two navigation scenarios. Understanding which applies determines which CSS selectors you need and how the menu loads.
Scenario 1
Global Header + Global Menu
Standard Divi pages — home, about, case studies landing, CEWQI, contact. The Divi Theme Builder header is assigned and the top nav loads automatically.
- Divi header template assigned
- Pill nav via Theme Options CSS
- Tablet (768px+) sees header nav
- Floating nav activates below 768px
- Divi hamburger hidden via CSS
Scenario 2
No Global Header — Menu Only
Full-width case study pages — Strategic Content Mapping, UX Systems Design. No header template assigned. Navigation injected via global footer code module.
- No Divi header template
- Floating nav handles all sizes
- Orange square trigger bottom-left
- Panel slides up on tap
- All CDP rules still apply
Core Menu Rules — Non-Negotiable
These rules apply to every navigation element on every page, in every scenario.
Typography — 16px minimum everywhere
Links, sub-items, mobile panel items — all 16px minimum. The only exception is all-caps + letter-spaced eyebrow labels at 14px. Never 15px, 13px, or 12px in any nav element. Font: Source Sans 3, weight 500 for links, 600 for active/current.
Contrast — WCAG AA minimum (4.5:1)
On dark backgrounds: use #F4E8D8 or #F9F0E1 at full opacity. Never reduce opacity below 4.5:1. On #3d1a00 (mobile panel): full cream only — reduced opacity cream is a CDP violation.
Active / Current Page — always scoped separately
Use .current-menu-item for the exact page. Use .current-menu-ancestor for parent items when a child page is active. These must be separate rules with separate visual weights.
Tap Targets — 44×44px minimum
Hamburger trigger, sub-menu arrow toggle, and all mobile panel links must meet 44×44px per WCAG 2.5.5.
No Bare Selectors
Never use bare ul, li, a, or element-only selectors in nav CSS. They bleed into Divi's header and break the site. Always scope to a nav-specific parent.
Global Header + Global Menu
Applied via Divi → Theme Options → Custom CSS. Selectors verified against peeayecreative.com and Ryan's Divi scoping rules.
Live Preview — Pill Nav
/* ── HEADER BACKGROUND ── */
#main-header {
background: #00080C;
}
/* ── PILL LINKS ── */
#et-top-navigation nav > ul > li > a {
font-family: 'Source Sans 3', sans-serif;
font-size: 15px;
font-weight: 500;
color: #F4E8D8;
padding: 8px 18px;
border: 1px solid rgba(244,232,216,.22);
border-radius: 999px;
margin: 0 4px;
background: transparent;
position: relative;
text-decoration: none;
transition: all .2s ease;
}
/* ── HOVER ── */
#et-top-navigation nav > ul > li > a:hover {
border-color: rgba(200,90,30,.7);
background: rgba(200,90,30,.1);
}
/* ── UNDERLINE SLIDE ON HOVER ── */
#et-top-navigation nav > ul > li > a::after {
content: "";
position: absolute;
left: 18px;
bottom: -4px;
width: 0;
height: 2px;
background-color: #c85a1e;
transition: width .25s ease;
}
#et-top-navigation nav > ul > li > a:hover::after {
width: calc(100% - 36px);
}
/* ── REMOVE DIVI DEFAULT ARROW ── */
#top-menu li.menu-item-has-children > a:first-child:after {
display: none !important;
}
/* ── CUSTOM SOLID TRIANGLE ARROW ── */
#top-menu li.menu-item-has-children > a:first-child {
padding-right: 18px;
}
#top-menu li.menu-item-has-children > a:first-child::before {
content: "▼";
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
font-size: 8px;
opacity: .6;
transition: transform .25s ease;
}
#top-menu li.menu-item-has-children > a:hover:first-child::before {
transform: translateY(-50%) rotate(180deg);
opacity: 1;
}
/* ── ACTIVE PAGE ── */
#top-menu li.current-menu-item > a,
#top-menu li.current_page_item > a {
color: #c85a1e !important;
border-color: rgba(200,90,30,.9) !important;
background: rgba(200,90,30,.15) !important;
font-weight: 600 !important;
}
/* ── ACTIVE ANCESTOR (parent when sub-page active) ── */
#top-menu li.current-menu-ancestor > a,
#top-menu li.current_page_ancestor > a {
color: #c85a1e !important;
border-color: rgba(200,90,30,.6) !important;
}
/* ── CTA PILL ── */
#et-top-navigation nav > ul > li.cta-menu > a {
background: #c85a1e !important;
color: #fff !important;
border-color: #c85a1e !important;
font-weight: 700 !important;
}
/* ── DROPDOWN PANEL ── */
#main-header .nav li ul {
background: #00080C !important;
border: 1px solid rgba(244,232,216,.18) !important;
border-radius: 14px !important;
padding: 8px !important;
}
/* ── DROPDOWN LINKS — 16px CDP minimum ── */
#main-header .nav li li a {
font-family: 'Source Sans 3', sans-serif !important;
font-size: 16px !important;
color: #F4E8D8 !important;
padding: 10px 14px !important;
border-radius: 10px !important;
}
#main-header .nav li li a:hover {
background: rgba(200,90,30,.12) !important;
}
/* ── ACTIVE DROPDOWN ITEM ── */
#top-menu li.current-menu-item > a {
color: #c85a1e !important;
font-weight: 600 !important;
}
/* ── HIDE DIVI HAMBURGER ON TABLET+ ── */
@media (min-width: 769px) {
.mobile_menu_bar { display: none !important; }
}
No Global Header — Floating Menu Only
Used on full-width case study pages where no Divi header template is assigned. The entire nav is a self-contained HTML/CSS/JS code module in the Divi Theme Builder global footer.
wp_nav_menu(), no Walker classes. All links are hardcoded HTML and updated manually when menu structure changes.
Live Preview — Floating Nav Trigger + Panel
/* Scenario 1 — standard pages with header
Floating nav: phones only */
@media (max-width: 768px) {
.uxdw-fnav { display: block; }
}
/* Scenario 2 — full-width pages, no header
Floating nav handles all screen sizes */
@media (max-width: 980px) {
.uxdw-fnav { display: block; }
}
/* If two menus appear simultaneously:
Page is NOT on a blank template.
Fix: assign blank/no-header template
in Divi → Theme Builder */
Master Selector Reference
Verified against peeayecreative.com and Ryan's Divi scoping rules. Use these exact selectors.
| Target | Selector | Notes |
|---|---|---|
| Main nav links | #et-top-navigation nav > ul > li > a | Pill styles, font, color |
| Main nav fixed scroll | .et-fixed-header #et-top-navigation nav > ul > li > a | Requires !important |
| Active page link | #top-menu li.current-menu-item > a | Exact current page only |
| Active ancestor | #top-menu li.current-menu-ancestor > a | Parent when sub-page active |
| Dropdown panel | #main-header .nav li ul | Background, border, radius |
| Dropdown links | #main-header .nav li li a | 16px min — CDP required |
| Menu module scope | .et-l--header .et_pb_menu | Ryan's rule — top-level scope |
| Mobile menu drawer | .et_mobile_menu | Divi default mobile only |
| Hamburger button | .mobile_menu_bar | Square, not pill |
| CTA menu item | #et-top-navigation nav > ul > li.cta-menu > a | Add class "cta-menu" in WP Menus |
Hover & Active States
All interactive states must be intentional. No browser defaults, no Divi blue.
Hover — underline slide
A 2px orange underline slides in using the ::after pseudo-element (width 0 to 100%). The ::before pseudo-element is reserved for the dropdown parent arrow. These must never be assigned to the same element.
Current page vs ancestor — different visual weights
Current page: orange text + bold + orange pill border. Ancestor: orange text only, lighter border. Using one combined rule causes every parent to appear as the active page.
#top-menu li.current-menu-item > a {
color: #c85a1e !important;
font-weight: 600 !important;
}
#top-menu li.current-menu-ancestor > a {
color: #c85a1e !important;
}
#top-menu .current-menu-item > a,
#top-menu .current-menu-ancestor > a {
color: #c85a1e !important;
font-weight: 600 !important;
}
Floating Mobile Nav — CDP Specs
The floating nav is a fully custom HTML component that bypasses Divi's mobile menu. All CDP rules apply inside it.
| Property | Value | Rule |
|---|---|---|
| Breakpoint — Scenario 1 | max-width: 768px | Phones only |
| Breakpoint — Scenario 2 | max-width: 980px | No-header pages |
| Trigger size | 52×52px | Min 44×44px — WCAG 2.5.5 |
| Trigger shape | border-radius: 6px | Square — not pill |
| Trigger color | #c85a1e | Brand orange |
| Panel width | 280px | Left-anchored |
| Panel background | #3d1a00 | Dark brown |
| Link font | Source Sans 3, 16px, 500 | CDP minimum |
| Link color | #F9F0E1 full opacity | WCAG AA on #3d1a00 |
| Active link | #c85a1e, weight 600 | Current page only |
| Sub-item default | Hidden — max-height: 0 | Tap arrow to reveal |
| Toggle arrow | ▼ solid, 18px | Rotates 180° open |
| Overlay | rgba(0,0,0,.45) | Dims page behind panel |
| Focus trap | Tab cycles within panel | WCAG 2.1 |
| Escape key | Closes, returns focus | WCAG 2.1 |
Do / Don't
Common violations that have caused repeated iterations. Check these before writing any nav CSS or HTML.
.uxdw-fnav-list a { font-size: 16px; }
.uxdw-fnav-children li a { font-size: 16px; }
.uxdw-fnav-children li a {
font-size: 14px; /* NEVER */
}
color: #F9F0E1;
/* 9.8:1 on #3d1a00 */
color: rgba(249,240,225,.72);
/* Fails WCAG AA */
#et-top-navigation nav > ul > li > a { }
#main-header .nav li ul { }
ul { list-style: none; }
a { color: #F4E8D8; }
Case Studies
'primary'
)); ?>