21 CSS Circular & Radial Menu Designs
Mission Hub
A 5-segment half-wheel command surface with curved SVG labels riding the outer rim, hairline wedge dividers, and a context-aware sub-toolbar that swaps icons based on the selected wedge. Pure CSS via :checked + :has(), teal-on-navy cockpit palette.
Mission Hub the 1st of 21 designs in the 21 CSS Circular & Radial Menu Designs collection. The design is implemented in pure CSS — no JavaScript required. Copy the HTML and CSS panels below into your project. Because the demo is pure CSS, it works in any framework or templating engine you happen to use. The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<div class="ccm-sun" role="toolbar" aria-label="Mission Hub">
<input type="radio" name="ccm-sun" id="ccm-sun-0" class="ccm-sun-r" hidden />
<input type="radio" name="ccm-sun" id="ccm-sun-1" class="ccm-sun-r" hidden />
<input type="radio" name="ccm-sun" id="ccm-sun-2" class="ccm-sun-r" hidden checked />
<input type="radio" name="ccm-sun" id="ccm-sun-3" class="ccm-sun-r" hidden />
<input type="radio" name="ccm-sun" id="ccm-sun-4" class="ccm-sun-r" hidden />
<div class="ccm-sun-wheel" aria-hidden="true"></div>
<svg class="ccm-sun-rim" viewBox="0 0 240 130" aria-hidden="true">
<defs>
<path id="ccm-sun-arc-path" d="M 30 130 A 90 90 0 0 1 210 130" fill="none" />
</defs>
<g class="ccm-sun-dividers">
<line x1="91.7" y1="109.4" x2="56.9" y2="84.1" />
<line x1="109.2" y1="96.7" x2="95.9" y2="55.8" />
<line x1="130.8" y1="96.7" x2="144.1" y2="55.8" />
<line x1="148.3" y1="109.4" x2="183.1" y2="84.1" />
</g>
<text class="ccm-sun-curve">
<textPath href="#ccm-sun-arc-path" startOffset="10%" text-anchor="middle">MUSIC</textPath>
<textPath href="#ccm-sun-arc-path" startOffset="30%" text-anchor="middle">MAPS</textPath>
<textPath href="#ccm-sun-arc-path" startOffset="50%" text-anchor="middle">COMPASS</textPath>
<textPath href="#ccm-sun-arc-path" startOffset="70%" text-anchor="middle">CAMERA</textPath>
<textPath href="#ccm-sun-arc-path" startOffset="90%" text-anchor="middle">SETTINGS</textPath>
</text>
</svg>
<div class="ccm-sun-pivot" aria-hidden="true"></div>
<label for="ccm-sun-0" class="ccm-sun-arc" style="--i: 0" aria-label="Music"
><span class="ccm-sun-ico">♪</span></label
>
<label for="ccm-sun-1" class="ccm-sun-arc" style="--i: 1" aria-label="Maps"
><span class="ccm-sun-ico">◈</span></label
>
<label for="ccm-sun-2" class="ccm-sun-arc" style="--i: 2" aria-label="Compass"
><span class="ccm-sun-ico">⌖</span></label
>
<label for="ccm-sun-3" class="ccm-sun-arc" style="--i: 3" aria-label="Camera"
><span class="ccm-sun-ico">◉</span></label
>
<label for="ccm-sun-4" class="ccm-sun-arc" style="--i: 4" aria-label="Settings"
><span class="ccm-sun-ico">⚙</span></label
>
<div class="ccm-sun-bar ccm-sun-bar-0" role="toolbar" aria-label="Music actions">
<a href="#" class="ccm-sun-sub" aria-label="Play">▶</a>
<a href="#" class="ccm-sun-sub" aria-label="Pause">❚❚</a>
<a href="#" class="ccm-sun-sub" aria-label="Skip">⏭</a>
</div>
<div class="ccm-sun-bar ccm-sun-bar-1" role="toolbar" aria-label="Maps actions">
<a href="#" class="ccm-sun-sub" aria-label="Search">⌕</a>
<a href="#" class="ccm-sun-sub" aria-label="Pin">◉</a>
<a href="#" class="ccm-sun-sub" aria-label="Route">➤</a>
</div>
<div class="ccm-sun-bar ccm-sun-bar-2" role="toolbar" aria-label="Compass actions">
<a href="#" class="ccm-sun-sub" aria-label="Calibrate">⊙</a>
<a href="#" class="ccm-sun-sub" aria-label="North">▲</a>
<a href="#" class="ccm-sun-sub" aria-label="Lock">⏻</a>
</div>
<div class="ccm-sun-bar ccm-sun-bar-3" role="toolbar" aria-label="Camera actions">
<a href="#" class="ccm-sun-sub" aria-label="Shutter">●</a>
<a href="#" class="ccm-sun-sub" aria-label="Flash">⚡</a>
<a href="#" class="ccm-sun-sub" aria-label="Flip">⤾</a>
</div>
<div class="ccm-sun-bar ccm-sun-bar-4" role="toolbar" aria-label="Settings actions">
<a href="#" class="ccm-sun-sub" aria-label="Profile">☺</a>
<a href="#" class="ccm-sun-sub" aria-label="Theme">◐</a>
<a href="#" class="ccm-sun-sub" aria-label="Help">?</a>
</div>
</div> .ccm-sun {
--n: 5;
--ba: calc(180deg / var(--n));
--r: 110px;
position: relative;
width: 240px;
height: 130px;
overflow: visible;
font-family: system-ui, sans-serif;
}
.ccm-sun-wheel {
position: absolute;
bottom: 0;
left: 50%;
width: calc(var(--r) * 2);
height: var(--r);
margin-left: calc(var(--r) * -1);
border-radius: var(--r) var(--r) 0 0;
background: radial-gradient(
farthest-side at 50% 100%,
#14b8a6 35%,
#1e293b 36%,
#1e293b calc(100% - 1px),
transparent 100%
);
filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.4));
}
.ccm-sun-rim {
position: absolute;
bottom: 0;
left: 50%;
width: 240px;
height: 130px;
margin-left: -120px;
pointer-events: none;
z-index: 1;
}
.ccm-sun-dividers line {
stroke: rgba(94, 234, 212, 0.25);
stroke-width: 1;
}
.ccm-sun-curve {
font:
700 9px/1 ui-monospace,
monospace;
letter-spacing: 0.18em;
fill: #cbd5e1;
}
.ccm-sun-pivot {
position: absolute;
bottom: 0;
left: 50%;
width: 70px;
height: 35px;
margin-left: -35px;
border-radius: 35px 35px 0 0;
background: radial-gradient(farthest-side at 50% 100%, #5eead4 0%, #14b8a6 70%, #0f766e 100%);
box-shadow: 0 -2px 8px rgba(94, 234, 212, 0.35);
z-index: 3;
}
.ccm-sun-arc {
position: absolute;
bottom: 0;
left: 50%;
width: 50px;
height: var(--r);
margin-left: -25px;
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 28px;
cursor: pointer;
transform-origin: 50% 100%;
transform: rotate(calc((var(--i) + 0.5) * var(--ba) - 90deg));
transition: color 0.25s;
color: #94a3b8;
z-index: 2;
}
.ccm-sun-ico {
display: inline-block;
font-size: 22px;
line-height: 1;
transform: rotate(calc((var(--i) + 0.5) * var(--ba) * -1 + 90deg));
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.ccm-sun-arc:hover,
.ccm-sun-arc:focus-visible {
color: #5eead4;
}
.ccm-sun-arc:hover .ccm-sun-ico,
.ccm-sun-arc:focus-visible .ccm-sun-ico {
transform: rotate(calc((var(--i) + 0.5) * var(--ba) * -1 + 90deg)) translateY(-3px) scale(1.1);
}
.ccm-sun:has(#ccm-sun-0:checked) [for="ccm-sun-0"],
.ccm-sun:has(#ccm-sun-1:checked) [for="ccm-sun-1"],
.ccm-sun:has(#ccm-sun-2:checked) [for="ccm-sun-2"],
.ccm-sun:has(#ccm-sun-3:checked) [for="ccm-sun-3"],
.ccm-sun:has(#ccm-sun-4:checked) [for="ccm-sun-4"] {
color: #5eead4;
}
.ccm-sun:has(#ccm-sun-0:checked) [for="ccm-sun-0"] .ccm-sun-ico,
.ccm-sun:has(#ccm-sun-1:checked) [for="ccm-sun-1"] .ccm-sun-ico,
.ccm-sun:has(#ccm-sun-2:checked) [for="ccm-sun-2"] .ccm-sun-ico,
.ccm-sun:has(#ccm-sun-3:checked) [for="ccm-sun-3"] .ccm-sun-ico,
.ccm-sun:has(#ccm-sun-4:checked) [for="ccm-sun-4"] .ccm-sun-ico {
filter: drop-shadow(0 0 6px rgba(94, 234, 212, 0.7));
}
.ccm-sun-bar {
position: absolute;
left: 50%;
bottom: calc(var(--r) + 14px);
display: flex;
gap: 6px;
padding: 8px 10px;
background: #1e293b;
border: 1px solid #334155;
border-radius: 12px;
transform: translateX(-50%) scale(0);
transform-origin: 50% calc(100% + 10px);
transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
z-index: 4;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
}
.ccm-sun-bar::after {
content: "";
position: absolute;
left: 50%;
bottom: -7px;
margin-left: -6px;
border: 6px solid transparent;
border-top-color: #1e293b;
}
.ccm-sun:has(#ccm-sun-0:checked) .ccm-sun-bar-0,
.ccm-sun:has(#ccm-sun-1:checked) .ccm-sun-bar-1,
.ccm-sun:has(#ccm-sun-2:checked) .ccm-sun-bar-2,
.ccm-sun:has(#ccm-sun-3:checked) .ccm-sun-bar-3,
.ccm-sun:has(#ccm-sun-4:checked) .ccm-sun-bar-4 {
transform: translateX(-50%) scale(1);
}
.ccm-sun-sub {
display: inline-flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 50%;
background: rgba(94, 234, 212, 0.12);
color: #5eead4;
font:
700 13px/1 ui-monospace,
monospace;
text-decoration: none;
border: 1px solid rgba(94, 234, 212, 0.3);
transition:
background 0.2s,
color 0.2s,
transform 0.2s;
}
.ccm-sun-sub:hover,
.ccm-sun-sub:focus-visible {
background: #5eead4;
color: #0f172a;
transform: scale(1.1);
}