CDP Menu Style Guide — UX Design Warrior
Cara's Design Protocol · Menu Reference

CDP Menu Style Guide

The definitive reference for all navigation patterns on UX Design Warrior — selectors, rules, visual samples, and both deployment scenarios.

Overview

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
CDP Rules

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.

Scenario 1

Global Header + Global Menu

Applied via Divi → Theme Options → Custom CSS. Selectors verified against peeayecreative.com and Ryan's Divi scoping rules.

CSS — Scenario 1 · Divi → Theme Options → Custom CSS
/* ── 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; }
}
Scenario 2

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.

PHP does not execute in Divi Code Modules. No wp_nav_menu(), no Walker classes. All links are hardcoded HTML and updated manually when menu structure changes.
Breakpoint Rules
/* 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 */
Reference

Master Selector Reference

Verified against peeayecreative.com and Ryan's Divi scoping rules. Use these exact selectors.

TargetSelectorNotes
Main nav links#et-top-navigation nav > ul > li > aPill styles, font, color
Main nav fixed scroll.et-fixed-header #et-top-navigation nav > ul > li > aRequires !important
Active page link#top-menu li.current-menu-item > aExact current page only
Active ancestor#top-menu li.current-menu-ancestor > aParent when sub-page active
Dropdown panel#main-header .nav li ulBackground, border, radius
Dropdown links#main-header .nav li li a16px min — CDP required
Menu module scope.et-l--header .et_pb_menuRyan's rule — top-level scope
Mobile menu drawer.et_mobile_menuDivi default mobile only
Hamburger button.mobile_menu_barSquare, not pill
CTA menu item#et-top-navigation nav > ul > li.cta-menu > aAdd class "cta-menu" in WP Menus
States

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.

✓ Do — separate rules
Scope current page and ancestor separately. #top-menu li.current-menu-item > a { color: #c85a1e !important; font-weight: 600 !important; } #top-menu li.current-menu-ancestor > a { color: #c85a1e !important; }
✗ Don't — combined rule
Combining both gives ancestor same weight — causes "always highlighted" bug. #top-menu .current-menu-item > a, #top-menu .current-menu-ancestor > a { color: #c85a1e !important; font-weight: 600 !important; }
Mobile

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.

PropertyValueRule
Breakpoint — Scenario 1max-width: 768pxPhones only
Breakpoint — Scenario 2max-width: 980pxNo-header pages
Trigger size52×52pxMin 44×44px — WCAG 2.5.5
Trigger shapeborder-radius: 6pxSquare — not pill
Trigger color#c85a1eBrand orange
Panel width280pxLeft-anchored
Panel background#3d1a00Dark brown
Link fontSource Sans 3, 16px, 500CDP minimum
Link color#F9F0E1 full opacityWCAG AA on #3d1a00
Active link#c85a1e, weight 600Current page only
Sub-item defaultHidden — max-height: 0Tap arrow to reveal
Toggle arrow▼ solid, 18pxRotates 180° open
Overlayrgba(0,0,0,.45)Dims page behind panel
Focus trapTab cycles within panelWCAG 2.1
Escape keyCloses, returns focusWCAG 2.1
Rules in Practice

Do / Don't

Common violations that have caused repeated iterations. Check these before writing any nav CSS or HTML.

✓ Font size
16px everywhere — links, sub-items, mobile items. .uxdw-fnav-list a { font-size: 16px; } .uxdw-fnav-children li a { font-size: 16px; }
✗ Font size
Sub-items below 16px — ADA/WCAG and CDP violation. .uxdw-fnav-children li a { font-size: 14px; /* NEVER */ }
✓ Contrast
Full opacity cream on dark panel — WCAG AAA. color: #F9F0E1; /* 9.8:1 on #3d1a00 */
✗ Contrast
Reduced opacity below 4.5:1 — CDP violation. color: rgba(249,240,225,.72); /* Fails WCAG AA */
✓ Selectors
Scoped to nav parent — no bleed. #et-top-navigation nav > ul > li > a { } #main-header .nav li ul { }
✗ Selectors
Bare selectors — break entire site. ul { list-style: none; } a { color: #F4E8D8; }
✓ Code Module links
Hardcoded HTML — works in Code Modules. Case Studies
✗ Code Module links
PHP — does not execute in Code Modules. 'primary' )); ?>