Navigation and Menus

Project Space Group Mega Menu

Complete the grouped mega menu for a project space scenario: includes real content, actionable controls, clear state feedback, and responsive layouts across sizes.

Navigation and MenusGrouped mega menuHTMLCSSJavaScript
With JavaScript enabled, you can edit, run, and save this example. The fixed source is as follows:
<!doctype html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Project Space Group Mega Menu</title>
  <style>
    :root { --ink:#30231f; --paper:#f9efe5; --accent:#8b6fb0; --secondary:#d7a971; --line:color-mix(in srgb, var(--ink) 18%, transparent); --shadow:0 24px 60px color-mix(in srgb, var(--ink) 16%, transparent); color-scheme:light; }
    * { box-sizing:border-box; }
    html { min-width:320px; background:var(--paper); }
    body { min-height:100vh; margin:0; overflow-x:hidden; color:var(--ink); font-family:Didot,"Songti SC",serif; background:linear-gradient(30deg,transparent 48%,color-mix(in srgb,var(--accent) 9%,transparent) 49% 51%,transparent 52%),var(--paper);background-size:52px 90px; }
    button,input,select,textarea { color:inherit; font:inherit; }
    button,[role="button"],input,select,textarea { accent-color:var(--accent); }
    button { cursor:pointer; }
    button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
    [hidden] { display:none !important; }
    @media (max-width:700px) { .mast h1 { line-height:1.08 !important; letter-spacing:-.035em !important; overflow-wrap:anywhere; } }
    @media (prefers-reduced-motion:reduce) { *,*::before,*::after { scroll-behavior:auto !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } }
    .page{width:min(1040px,calc(100% - 36px));margin:auto;padding:64px 0}.mast{display:grid;justify-items:center;text-align:center;border-block:3px double var(--accent);padding:26px;gap:20px;margin-bottom:32px}.mast h1{font-family:Didot,"Songti SC",serif;font-weight:700;font-size:clamp(38px,8vw,86px);letter-spacing:.035em;margin:0;line-height:1}.eyebrow{display:block;color:var(--accent);font:800 11px/1 ui-monospace,monospace;letter-spacing:.3em}.intro{max-width:600px;margin-inline:auto;line-height:1.8}.scenario{padding:8px 26px;border-inline:1px solid var(--accent);letter-spacing:.16em}.demo{border:4px double var(--accent);border-radius:0;clip-path:polygon(24px 0,calc(100% - 24px) 0,100% 24px,100% calc(100% - 24px),calc(100% - 24px) 100%,24px 100%,0 calc(100% - 24px),0 24px);position:relative;min-height:440px;overflow:hidden;padding:clamp(28px,5vw,60px);background:var(--paper)}@media(max-width:700px){.page{width:calc(100% - 20px);padding:24px 0}.mast{padding:18px}.demo{padding:18px}}
    .panel{padding:18px;border:3px solid var(--ink);background:var(--paper);box-shadow:8px 8px 0 var(--ink)}.stack{display:grid;gap:12px}.row{display:flex;flex-wrap:wrap;gap:8px}.action{min-height:42px;padding:8px 13px;border:3px solid var(--ink);background:var(--paper);font-weight:900}.action.primary,.action.is-active{color:var(--paper);background:var(--ink)}.status{min-height:24px;padding:8px;color:var(--paper);background:var(--ink);font-weight:900}.metric{font-size:clamp(34px,8vw,76px);font-weight:900;letter-spacing:-.08em}.muted{font-weight:600}.chip{padding:5px 8px;border:2px solid var(--ink);font-weight:900}.meter{height:14px;border:3px solid var(--ink)}.meter>i{display:block;height:100%;background:var(--ink)}
    .composition-split{display:grid;grid-template-columns:150px minmax(0,1fr);gap:18px;align-items:start}.split-note{position:sticky;top:20px;display:grid;gap:14px;padding:18px 12px;border-block:3px double var(--accent);font-size:13px;line-height:1.65}.split-note b{font:900 12px/1 ui-monospace,monospace;letter-spacing:.12em}.split-note span{writing-mode:vertical-rl;min-height:120px;color:color-mix(in srgb,var(--ink) 60%,transparent)}.composition-split .demo{min-width:0}@media(max-width:900px){.composition-split{grid-template-columns:1fr}.split-note{position:static;grid-template-columns:auto 1fr}.split-note span{writing-mode:horizontal-tb;min-height:0}}
    .mega-shell{position:relative;min-height:430px;border:1px solid var(--line);border-radius:22px;background:var(--paper)}.mega-nav{display:flex;justify-content:space-between;gap:18px;align-items:center;padding:16px 20px;border-bottom:1px solid var(--line)}.mega-brand{color:inherit;font-size:20px;font-weight:900;text-decoration:none}.mega-nav button{padding:11px 15px;border:1px solid var(--line);border-radius:10px;background:transparent}.mega-panel{position:absolute;z-index:5;inset:70px 14px auto;display:grid;grid-template-columns:repeat(3,1fr) .8fr;gap:18px;padding:22px;border:1px solid var(--line);border-radius:18px;background:var(--paper);box-shadow:var(--shadow)}.mega-panel section{display:grid;align-content:start;gap:5px}.mega-panel h2{font-size:15px}.mega-panel a{display:grid;gap:3px;padding:9px;border-radius:8px;color:inherit;text-decoration:none}.mega-panel a:hover{background:color-mix(in srgb,var(--secondary) 22%,transparent)}.mega-panel small{opacity:.6}.mega-panel aside{padding:18px;border-radius:14px;background:var(--ink);color:var(--paper)}.mega-preview{display:grid;min-height:340px;place-content:center;padding:30px;text-align:center}@media(max-width:720px){.mega-panel{grid-template-columns:1fr 1fr;max-height:330px;overflow:auto}.mega-panel aside{grid-column:1/-1}}.workflow-compare{display:grid;grid-template-columns:minmax(230px,.55fr) minmax(0,1.45fr);gap:18px}.compare-stage{display:grid;gap:12px;min-width:0}.compare-stage>header{display:flex;justify-content:space-between;gap:16px;align-items:end}.compare-stage h2{margin:.2em 0}.compare-core{--compare-split:50%;min-width:0;padding:14px;clip-path:inset(0 calc(100% - var(--compare-split)) 0 0);outline:1px dashed var(--accent);outline-offset:-8px;transition:clip-path .25s,filter .25s}.compare-core[data-compare-channel="B"]{filter:hue-rotate(32deg) saturate(1.15)}.compare-controls{display:grid;align-content:start;gap:16px;padding:20px;border:1px solid var(--line);border-radius:24px 4px 24px 4px;background:var(--paper)}.compare-controls fieldset,.compare-controls>label{display:grid;gap:8px}.compare-controls input[type="range"]{width:100%}#workflowCompareShelf{display:grid;gap:6px;padding:0;margin:0;list-style:none}#workflowCompareShelf li{display:grid;grid-template-columns:auto 1fr auto;gap:8px;padding:9px;border-top:1px solid var(--line);font-size:12px}@media(max-width:900px){.workflow-compare{grid-template-columns:1fr}.compare-stage{order:-1}.compare-core{clip-path:none;border-left:8px solid var(--accent)}}
  </style>
</head>
<body data-aesthetic="art-deco" data-composition="split-note">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">art-deco / grouped mega menu / BEGINNER</span><h1>Project Space Group Mega Menu</h1><p class="intro">Complete the grouped mega menu for a project space scenario: includes real content, actionable controls, clear state feedback, and responsive layouts across sizes.</p></div><span class="scenario">Project Space</span></header>
    <div class="composition-split"><aside class="split-note"><b>CASE 02</b><span>Master the semantic structure, responsive arrangement, keyboard interaction, and state synchronization of grouped mega menus.</span></aside><section class="demo" aria-label="Project Space Grouped Mega Menu Interaction Area"><div class="workflow-compare"><form id="workflowCompareControls" class="compare-controls"><fieldset><legend>Reference Channel</legend><label><input type="radio" name="workflowChannel" value="A" checked>A · To-Do Space</label><label><input type="radio" name="workflowChannel" value="B">B · File Space</label></fieldset><label>Member scope weight<input id="workflowCompareWeight" type="range" min="10" max="90" value="50"><output id="workflowCompareWeightValue">50 Person</output></label><label><input id="workflowCompareFreeze" type="checkbox">Freeze current version</label><button id="workflowCompareCapture" class="action primary" type="button">Sample and switch spaces</button><ol id="workflowCompareShelf" aria-label="Version Sampling Record"></ol></form><section class="compare-stage"><header><span class="eyebrow">Project Space COMPARE</span><h2>Project View Dual-Version Comparison</h2><output id="workflowCompareLive">Version A waiting for sampling</output></header><section id="workflowCore" class="workflow-core compare-core" data-compare-channel="A" style="--compare-split:50%"><!-- 11DZ_CORE_START:navigation-menus-mega-menu --><div class="mega-shell"><nav class="mega-nav" aria-label="Project space grouped menu"><a href="#mega-home" class="mega-brand">Project Space</a><button id="megaTrigger" type="button" aria-expanded="false" aria-controls="megaPanel" data-core-bridge="navigation-menus-mega-menu">View all content <span aria-hidden="true">⌄</span></button></nav><div id="megaPanel" class="mega-panel" hidden><section><h2>Project space reminders</h2><a href="#mega-0-1">Project space reminder 1<small>View guide</small></a><a href="#mega-0-2">Project Space Reminder 2<small>Open tools</small></a><a href="#mega-0-3">Project Space Reminder 3<small>View guide</small></a></section><section><h2>Project Space Favorites</h2><a href="#mega-1-1">Project space favorites 1<small>View guide</small></a><a href="#mega-1-2">Project Space Favorites 2<small>Open tools</small></a><a href="#mega-1-3">Project Space Favorites 3<small>View guide</small></a></section><section><h2>Project Space Overview</h2><a href="#mega-2-1">Project Space Overview 1<small>View guide</small></a><a href="#mega-2-2">Project Space Overview 2<small>Open tools</small></a><a href="#mega-2-3">Project Space Overview 3<small>View guide</small></a></section><aside><span class="eyebrow">FEATURED</span><strong>Grouped mega menu</strong><p>Help users anticipate their goal with titles and descriptions.</p></aside></div><section class="mega-preview"><span class="eyebrow">MEGA MENU</span><h2 id="megaSelection">Please choose a destination</h2></section></div><!-- 11DZ_CORE_END --></section></section></div><p id="status" class="status" role="status" aria-live="polite"></p></section></div>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:navigation-menus-mega-menu */
const megaTrigger=document.querySelector('#megaTrigger');const megaPanel=document.querySelector('#megaPanel');function setMega(open){megaTrigger.setAttribute('aria-expanded',String(open));megaPanel.hidden=!open;announce(open?'Grouped mega menu expanded':'Grouped mega menu collapsed');}megaTrigger.addEventListener('click',()=>setMega(megaTrigger.getAttribute('aria-expanded')!=='true'));document.querySelector('.mega-brand').addEventListener('click',event=>event.preventDefault());megaPanel.querySelectorAll('a').forEach(link=>link.addEventListener('click',event=>{event.preventDefault();document.querySelector('#megaSelection').textContent=link.firstChild.textContent.trim();setMega(false);}));document.addEventListener('keydown',event=>{if(event.key==='Escape'&&!megaPanel.hidden){setMega(false);megaTrigger.focus();}});
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"navigation-menus-mega-menu","selector":"[data-core-bridge=\"navigation-menus-mega-menu\"]","mode":"click","key":"Enter"};const workflowBridgeCore=document.querySelector('#workflowCore');const workflowBridgeControl=workflowBridgeCore.querySelector(workflowBridgeSpec.selector);if(!workflowBridgeControl)throw new Error('Missing core bridge: '+workflowBridgeSpec.name);const workflowBridgeControlledId=workflowBridgeControl.getAttribute('aria-controls');const workflowBridgeControlled=workflowBridgeControlledId?document.getElementById(workflowBridgeControlledId):null;workflowBridgeCore.dataset.workflowBridge=workflowBridgeSpec.name;workflowBridgeCore.dataset.workflowVersion='0';function workflowBridgeSerialize(){const visualNode=workflowBridgeCore.firstElementChild||workflowBridgeCore;const visual=getComputedStyle(visualNode);const outputs=[...workflowBridgeCore.querySelectorAll('output,[role="status"],[aria-live],meter,progress')].map(node=>node.textContent.trim()+'|'+node.getAttribute('aria-valuenow')+'|'+node.getAttribute('value'));const canvas=[...workflowBridgeCore.querySelectorAll('canvas')].map(node=>{try{return node.toDataURL().slice(-160);}catch{return 'canvas-unavailable';}});return JSON.stringify({html:workflowBridgeCore.innerHTML,status:statusOutput.textContent,outputs,canvas,visual:[visual.display,visual.visibility,visual.opacity,visual.transform,visual.filter,visual.backgroundColor,visual.width,visual.height],scroll:workflowBridgeSpec.mode==='scroll'?workflowBridgeControl.scrollTop:null});}let workflowBridgeLastEffect=workflowBridgeSerialize();function workflowBridgeSummary(){const label=(workflowBridgeControl.getAttribute('aria-label')||workflowBridgeControl.textContent||workflowBridgeControl.value||workflowBridgeSpec.name).trim().replace(/\s+/g,' ').slice(0,72);return label+' · Core Version '+workflowBridgeCore.dataset.workflowVersion;}function workflowBridgeCommit(){const effect=workflowBridgeSerialize();if(effect===workflowBridgeLastEffect)return {changed:false,summary:workflowBridgeSummary()};workflowBridgeLastEffect=effect;workflowBridgeCore.dataset.workflowVersion=String(Number(workflowBridgeCore.dataset.workflowVersion||0)+1);return {changed:true,summary:workflowBridgeSummary()};}function workflowBridgeScheduleCommit(){queueMicrotask(workflowBridgeCommit);setTimeout(workflowBridgeCommit,0);}workflowBridgeControl.addEventListener("click",workflowBridgeScheduleCommit);const workflowBridgeStateTargets=new Set(workflowBridgeCore.querySelectorAll('dialog'));if(workflowBridgeControlled&&workflowBridgeCore.contains(workflowBridgeControlled))workflowBridgeStateTargets.add(workflowBridgeControlled);workflowBridgeStateTargets.forEach(target=>['close','cancel','toggle'].forEach(eventName=>target.addEventListener(eventName,workflowBridgeScheduleCommit)));function workflowBridgeActivate(){workflowBridgeControl.focus();workflowBridgeControl.click();const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowCompareCore=document.querySelector('#workflowCore');const workflowCompareWeight=document.querySelector('#workflowCompareWeight');const workflowCompareState={channel:'A',weight:50,frozen:false,snapshots:[]};function workflowCompareFingerprint(){const controls=[...workflowCompareCore.querySelectorAll('input,select,textarea')];const outputs=[...workflowCompareCore.querySelectorAll('output,[role="status"],strong')].map(node=>node.textContent.trim()).filter(Boolean);return {controlValues:controls.map(control=>control.type==='checkbox'||control.type==='radio'?control.checked:control.value),summary:outputs.slice(0,4).join(' / '),nodes:workflowCompareCore.querySelectorAll('*').length};}function workflowCompareDrive(){workflowCompareCore.dataset.compareChannel=workflowCompareState.channel;workflowCompareCore.style.setProperty('--compare-split',workflowCompareState.weight+'%');document.querySelector('#workflowCompareWeightValue').textContent=workflowCompareState.weight+' person';document.querySelector('#workflowCompareLive').textContent=workflowCompareState.channel+' Version · '+workflowCompareState.weight+' person'+(workflowCompareState.frozen?' · Frozen':'');announce('Project view is being viewed '+workflowCompareState.channel+' Version');}function workflowCompareCapture(source){const bridge=workflowBridgeActivate();const snapshot={...workflowCompareFingerprint(),channel:workflowCompareState.channel,weight:workflowCompareState.weight,source,bridge:bridge.summary};workflowCompareState.snapshots.push(snapshot);const item=document.createElement('li');item.innerHTML='<b>'+snapshot.channel+'</b><span>'+(snapshot.summary||snapshot.bridge)+'</span><small>'+snapshot.weight+' person · '+snapshot.bridge+'</small>';document.querySelector('#workflowCompareShelf').prepend(item);announce('sampled '+snapshot.channel+' Version and switch spaces · '+bridge.summary);}document.querySelectorAll('[name="workflowChannel"]').forEach(input=>input.addEventListener('change',()=>{workflowCompareState.channel=input.value;workflowCompareDrive();}));workflowCompareWeight.addEventListener('input',()=>{workflowCompareState.weight=Number(workflowCompareWeight.value);workflowCompareDrive();});document.querySelector('#workflowCompareFreeze').addEventListener('change',event=>{workflowCompareState.frozen=event.currentTarget.checked;workflowCompareDrive();});document.querySelector('#workflowCompareCapture').addEventListener('click',()=>workflowCompareCapture('Button Sampling'));workflowCompareCore.addEventListener('dblclick',()=>workflowCompareCapture('Main view double-click'));workflowCompareDrive();
workflowBridgeReset();
  </script>
</body>
</html>
Page feedbackFound an issue or have suggestions for improvement?
Feedback features need to be used in the online version

Please enable JavaScript in the online version before submitting; local features of the current tool or example are not affected.

Go to the online version for feedback