A CSS circular menu is a navigation pattern where items are arranged around a circle, ring, dome, or orbit instead of a flat list — useful for radial action menus, compass-style nav, and skeumorphic widgets. These 21 hand-coded designs are 100% pure CSS with custom-property trigonometry. Continuous animations honour prefers-reduced-motion.
.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); } <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-svc { --n: 6; --ba: calc(360deg / var(--n)); --r: 105px; --pa: 0deg; position: relative; width: 260px; height: 260px; display: flex; align-items: center; justify-content: center; font-family: system-ui, sans-serif; }
.ccm-svc-orbit { position: absolute; width: calc(var(--r) * 2); height: calc(var(--r) * 2); border-radius: 50%; border: 1px dashed rgba(124,108,255,0.18); background: radial-gradient(circle at center, rgba(124,108,255,0.08), transparent 70%); }
.ccm-svc-disc { position: relative; width: 110px; height: 110px; border-radius: 50%; background: linear-gradient(135deg, #7c6cff, #a78bfa); color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: 0 8px 24px rgba(124,108,255,0.4), inset 0 1px 0 rgba(255,255,255,0.2); z-index: 2; }
.ccm-svc-title { display: none; font: 700 14px/1.2 system-ui, sans-serif; text-align: center; padding: 0 12px; }
.ccm-svc-cta { display: block; margin-top: 8px; padding: 4px 10px; font: 600 10px/1 ui-monospace, monospace; letter-spacing: 0.06em; color: rgba(255,255,255,0.85); border: 1px solid rgba(255,255,255,0.4); border-radius: 999px; cursor: pointer; transition: background 0.2s, color 0.2s; }
.ccm-svc-cta:hover { background: #fff; color: #7c6cff; }
.ccm-svc:has(#ccm-svc-0:checked) .ccm-svc-t-0,
.ccm-svc:has(#ccm-svc-1:checked) .ccm-svc-t-1,
.ccm-svc:has(#ccm-svc-2:checked) .ccm-svc-t-2,
.ccm-svc:has(#ccm-svc-3:checked) .ccm-svc-t-3,
.ccm-svc:has(#ccm-svc-4:checked) .ccm-svc-t-4,
.ccm-svc:has(#ccm-svc-5:checked) .ccm-svc-t-5 { display: block; }
.ccm-svc-pointer { position: absolute; width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 2px solid #7c6cff; box-shadow: 0 0 0 4px rgba(124,108,255,0.18); transform: rotate(var(--pa)) translateY(calc(var(--r) * -0.55)); transform-origin: 50% 50%; transition: transform 0.5s cubic-bezier(0.34,1.56,0.64,1); z-index: 3; }
.ccm-svc:has(#ccm-svc-0:checked) { --pa: 0deg; }
.ccm-svc:has(#ccm-svc-1:checked) { --pa: 60deg; }
.ccm-svc:has(#ccm-svc-2:checked) { --pa: 120deg; }
.ccm-svc:has(#ccm-svc-3:checked) { --pa: 180deg; }
.ccm-svc:has(#ccm-svc-4:checked) { --pa: 240deg; }
.ccm-svc:has(#ccm-svc-5:checked) { --pa: 300deg; }
.ccm-svc-sat { position: absolute; width: 44px; height: 44px; border-radius: 50%; background: #1f1f2e; border: 1px solid rgba(124,108,255,0.4); color: #c4b5fd; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transform: rotate(calc(var(--i) * var(--ba))) translateY(calc(var(--r) * -1)) rotate(calc(var(--i) * var(--ba) * -1)); transition: background 0.25s, color 0.25s, transform 0.3s cubic-bezier(0.34,1.56,0.64,1), box-shadow 0.25s; z-index: 4; }
.ccm-svc-sat span { font-size: 18px; line-height: 1; }
.ccm-svc-sat:hover, .ccm-svc-sat:focus-visible { background: #2a2a3e; color: #fff; transform: rotate(calc(var(--i) * var(--ba))) translateY(calc(var(--r) * -1)) rotate(calc(var(--i) * var(--ba) * -1)) scale(1.15); }
.ccm-svc:has(#ccm-svc-0:checked) [for="ccm-svc-0"],
.ccm-svc:has(#ccm-svc-1:checked) [for="ccm-svc-1"],
.ccm-svc:has(#ccm-svc-2:checked) [for="ccm-svc-2"],
.ccm-svc:has(#ccm-svc-3:checked) [for="ccm-svc-3"],
.ccm-svc:has(#ccm-svc-4:checked) [for="ccm-svc-4"],
.ccm-svc:has(#ccm-svc-5:checked) [for="ccm-svc-5"] { background: #7c6cff; color: #fff; border-color: #fff; box-shadow: 0 0 0 4px rgba(124,108,255,0.3); transform: rotate(calc(var(--i) * var(--ba))) translateY(calc(var(--r) * -1)) rotate(calc(var(--i) * var(--ba) * -1)) scale(1.15); } <div class="ccm-svc">
<input type="radio" name="ccm-svc" id="ccm-svc-0" class="ccm-svc-r" hidden checked>
<input type="radio" name="ccm-svc" id="ccm-svc-1" class="ccm-svc-r" hidden>
<input type="radio" name="ccm-svc" id="ccm-svc-2" class="ccm-svc-r" hidden>
<input type="radio" name="ccm-svc" id="ccm-svc-3" class="ccm-svc-r" hidden>
<input type="radio" name="ccm-svc" id="ccm-svc-4" class="ccm-svc-r" hidden>
<input type="radio" name="ccm-svc" id="ccm-svc-5" class="ccm-svc-r" hidden>
<div class="ccm-svc-orbit" aria-hidden="true"></div>
<div class="ccm-svc-disc">
<span class="ccm-svc-title ccm-svc-t-0">Industries</span>
<span class="ccm-svc-title ccm-svc-t-1">Validation</span>
<span class="ccm-svc-title ccm-svc-t-2">Engineering</span>
<span class="ccm-svc-title ccm-svc-t-3">Project Mgmt</span>
<span class="ccm-svc-title ccm-svc-t-4">Manufacturing</span>
<span class="ccm-svc-title ccm-svc-t-5">Automation</span>
<span class="ccm-svc-cta">Learn more →</span>
</div>
<div class="ccm-svc-pointer" aria-hidden="true"></div>
<label for="ccm-svc-0" class="ccm-svc-sat" style="--i:0" aria-label="Industries"><span>♨</span></label>
<label for="ccm-svc-1" class="ccm-svc-sat" style="--i:1" aria-label="Validation"><span>✓</span></label>
<label for="ccm-svc-2" class="ccm-svc-sat" style="--i:2" aria-label="Engineering"><span>⚙</span></label>
<label for="ccm-svc-3" class="ccm-svc-sat" style="--i:3" aria-label="Project Management"><span>◈</span></label>
<label for="ccm-svc-4" class="ccm-svc-sat" style="--i:4" aria-label="Manufacturing"><span>⛭</span></label>
<label for="ccm-svc-5" class="ccm-svc-sat" style="--i:5" aria-label="Automation"><span>⌬</span></label>
</div> .ccm-tac { --rot: 0deg; position: relative; width: 280px; height: 240px; display: flex; align-items: flex-end; justify-content: center; font-family: system-ui, sans-serif; }
.ccm-tac-dial { position: absolute; bottom: 20px; left: 50%; width: 130px; height: 130px; margin-left: -65px; border-radius: 50%; background: repeating-conic-gradient(from 0deg, #c9cfd7 0deg, #8b929c 1deg, #c9cfd7 2deg), linear-gradient(180deg, #c9cfd7 0%, #2b2f3e 46%, #2b2f3e 54%, #b0b7c1 100%); background-blend-mode: overlay, normal; box-shadow: 0 12px 24px rgba(0,0,0,0.4), 0 4px 8px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.3), inset 0 -2px 4px rgba(0,0,0,0.4); transform: rotate(var(--rot)); transform-origin: center; transition: transform 0.7s cubic-bezier(0.65,0,0.35,1); z-index: 2; }
.ccm-tac-bevel { position: absolute; inset: 12px; border-radius: 50%; background: radial-gradient(circle at 30% 30%, #e8ecf0, #6b7280 70%, #2b2f3e); box-shadow: inset 0 1px 2px rgba(255,255,255,0.4), inset 0 -2px 4px rgba(0,0,0,0.5); }
.ccm-tac-mark { position: absolute; top: 8px; left: 50%; width: 4px; height: 16px; margin-left: -2px; background: linear-gradient(180deg, #fff, #94a3b8); border-radius: 2px; box-shadow: 0 1px 2px rgba(0,0,0,0.6); z-index: 3; }
.ccm-tac:has(#ccm-tac-0:checked) { --rot: -50deg; }
.ccm-tac:has(#ccm-tac-1:checked) { --rot: -25deg; }
.ccm-tac:has(#ccm-tac-2:checked) { --rot: 0deg; }
.ccm-tac:has(#ccm-tac-3:checked) { --rot: 25deg; }
.ccm-tac:has(#ccm-tac-4:checked) { --rot: 50deg; }
.ccm-tac-arc { position: absolute; bottom: -40px; left: 50%; width: 250px; height: 250px; margin-left: -125px; border-radius: 50%; border: 1px dashed rgba(255,255,255,0.08); pointer-events: none; -webkit-mask: linear-gradient(180deg, #000 0%, #000 50%, transparent 50%); mask: linear-gradient(180deg, #000 0%, #000 50%, transparent 50%); }
.ccm-tac-i { position: absolute; bottom: calc(20px + 65px); left: 50%; width: 38px; height: 38px; margin: -19px; border-radius: 50%; background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.1); color: #94a3b8; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transform: rotate(calc((var(--p) - 2) * 25deg)) translateY(-125px); transform-origin: 50% 50%; transition: background 0.25s, color 0.25s, box-shadow 0.3s, border-color 0.25s, transform 0.25s; z-index: 4; }
.ccm-tac-i span { font-size: 17px; line-height: 1; display: inline-block; transform: rotate(calc((var(--p) - 2) * -25deg)); }
.ccm-tac-i:hover, .ccm-tac-i:focus-visible { background: rgba(255,255,255,0.08); color: #fff; border-color: rgba(255,255,255,0.25); transform: rotate(calc((var(--p) - 2) * 25deg)) translateY(-130px); }
.ccm-tac:has(#ccm-tac-0:checked) [for="ccm-tac-0"],
.ccm-tac:has(#ccm-tac-1:checked) [for="ccm-tac-1"],
.ccm-tac:has(#ccm-tac-2:checked) [for="ccm-tac-2"],
.ccm-tac:has(#ccm-tac-3:checked) [for="ccm-tac-3"],
.ccm-tac:has(#ccm-tac-4:checked) [for="ccm-tac-4"] { background: rgba(255,255,255,0.16); color: #fff; border-color: rgba(255,255,255,0.5); box-shadow: 0 0 24px 6px rgba(255,255,255,0.18); transform: rotate(calc((var(--p) - 2) * 25deg)) translateY(-132px); } <div class="ccm-tac" role="toolbar" aria-label="Tactile Dial">
<input type="radio" name="ccm-tac" id="ccm-tac-0" class="ccm-tac-r" hidden>
<input type="radio" name="ccm-tac" id="ccm-tac-1" class="ccm-tac-r" hidden>
<input type="radio" name="ccm-tac" id="ccm-tac-2" class="ccm-tac-r" hidden checked>
<input type="radio" name="ccm-tac" id="ccm-tac-3" class="ccm-tac-r" hidden>
<input type="radio" name="ccm-tac" id="ccm-tac-4" class="ccm-tac-r" hidden>
<div class="ccm-tac-dial" aria-hidden="true">
<div class="ccm-tac-mark"></div>
<div class="ccm-tac-bevel"></div>
</div>
<div class="ccm-tac-arc" aria-hidden="true"></div>
<label for="ccm-tac-0" class="ccm-tac-i" style="--p:0" aria-label="Email"><span>✉</span></label>
<label for="ccm-tac-1" class="ccm-tac-i" style="--p:1" aria-label="Photos"><span>◇</span></label>
<label for="ccm-tac-2" class="ccm-tac-i" style="--p:2" aria-label="Cloud"><span>☁</span></label>
<label for="ccm-tac-3" class="ccm-tac-i" style="--p:3" aria-label="Portfolio"><span>⊞</span></label>
<label for="ccm-tac-4" class="ccm-tac-i" style="--p:4" aria-label="Settings"><span>⚙</span></label>
</div> .ccm-fan { position: relative; width: 220px; height: 220px; display: flex; align-items: center; justify-content: center; font-family: 'Lato', system-ui, sans-serif; filter: drop-shadow(0 0 18px rgba(255,255,255,0.08)); }
.ccm-fan-w { position: absolute; inset: 0; background: radial-gradient(circle at 50% 5%, rgba(255,255,255,0.35), transparent 55%), radial-gradient(circle at 50% 30%, var(--c) 0%, color-mix(in srgb, var(--c), #000 35%) 100%); cursor: pointer; clip-path: polygon(50% 50%, 25% 6.7%, 37.06% 1.92%, 50% 0%, 62.94% 1.92%, 75% 6.7%); transform-origin: 50% 50%; transform: rotate(0deg); animation: ccm-fan-deal 0.9s cubic-bezier(0.49,0.24,0.32,0.96) forwards; animation-delay: calc(var(--i) * 0.08s); transition: filter 0.3s, transform 0.3s; }
.ccm-fan-w span { position: absolute; top: 24px; left: 50%; display: inline-block; color: #fff; font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; transform: translateX(-50%); pointer-events: none; text-shadow: 0 1px 2px rgba(0,0,0,0.6), 0 0 8px rgba(255,255,255,0.25); white-space: nowrap; }
.ccm-fan-w:hover, .ccm-fan-w:focus-visible { filter: brightness(1.18) saturate(1.2) drop-shadow(0 0 12px color-mix(in srgb, var(--c), white 20%)); z-index: 2; }
.ccm-fan:has(#ccm-fan-0:checked) [for="ccm-fan-0"],
.ccm-fan:has(#ccm-fan-1:checked) [for="ccm-fan-1"],
.ccm-fan:has(#ccm-fan-2:checked) [for="ccm-fan-2"],
.ccm-fan:has(#ccm-fan-3:checked) [for="ccm-fan-3"],
.ccm-fan:has(#ccm-fan-4:checked) [for="ccm-fan-4"],
.ccm-fan:has(#ccm-fan-5:checked) [for="ccm-fan-5"] { filter: brightness(1.45) saturate(1.5) drop-shadow(0 0 22px color-mix(in srgb, var(--c), white 40%)) drop-shadow(0 0 6px color-mix(in srgb, var(--c), white 60%)); z-index: 3; transform: rotate(calc(var(--i) * 60deg)) scale(1.06); }
.ccm-fan:has(#ccm-fan-0:checked) [for="ccm-fan-0"] span,
.ccm-fan:has(#ccm-fan-1:checked) [for="ccm-fan-1"] span,
.ccm-fan:has(#ccm-fan-2:checked) [for="ccm-fan-2"] span,
.ccm-fan:has(#ccm-fan-3:checked) [for="ccm-fan-3"] span,
.ccm-fan:has(#ccm-fan-4:checked) [for="ccm-fan-4"] span,
.ccm-fan:has(#ccm-fan-5:checked) [for="ccm-fan-5"] span { font-size: 13px; letter-spacing: 0.1em; text-shadow: 0 1px 2px rgba(0,0,0,0.7), 0 0 12px rgba(255,255,255,0.6); }
.ccm-fan-hub { position: absolute; width: 60px; height: 60px; border-radius: 50%; background: radial-gradient(circle at 35% 30%, rgba(255,255,255,0.18), transparent 55%), radial-gradient(circle at center, #1f1f2e 0%, #0a0a14 100%); border: 1px solid rgba(255,255,255,0.08); box-shadow: inset 0 1px 0 rgba(255,255,255,0.12), inset 0 -2px 6px rgba(0,0,0,0.5), 0 0 24px rgba(124,108,255,0.25), 0 4px 12px rgba(0,0,0,0.5); z-index: 4; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
.ccm-fan-w { animation: none; transform: rotate(calc(var(--i) * 60deg)); }
} <div class="ccm-fan" role="toolbar" aria-label="Fan Reveal"> <input type="radio" name="ccm-fan" id="ccm-fan-0" class="ccm-fan-r" hidden> <input type="radio" name="ccm-fan" id="ccm-fan-1" class="ccm-fan-r" hidden> <input type="radio" name="ccm-fan" id="ccm-fan-2" class="ccm-fan-r" hidden> <input type="radio" name="ccm-fan" id="ccm-fan-3" class="ccm-fan-r" hidden> <input type="radio" name="ccm-fan" id="ccm-fan-4" class="ccm-fan-r" hidden> <input type="radio" name="ccm-fan" id="ccm-fan-5" class="ccm-fan-r" hidden> <label for="ccm-fan-0" class="ccm-fan-w" style="--i:0; --c:#255D74" aria-label="Home"><span>home</span></label> <label for="ccm-fan-1" class="ccm-fan-w" style="--i:1; --c:#DA353B" aria-label="About"><span>about</span></label> <label for="ccm-fan-2" class="ccm-fan-w" style="--i:2; --c:#F89F44" aria-label="Contact"><span>contact</span></label> <label for="ccm-fan-3" class="ccm-fan-w" style="--i:3; --c:#78302C" aria-label="Links"><span>links</span></label> <label for="ccm-fan-4" class="ccm-fan-w" style="--i:4; --c:#002B55" aria-label="Bio"><span>bio</span></label> <label for="ccm-fan-5" class="ccm-fan-w" style="--i:5; --c:#207C6B" aria-label="Store"><span>store</span></label> <span class="ccm-fan-hub" aria-hidden="true"></span> </div>
.ccm-petal { position: relative; width: 220px; height: 140px; }
.ccm-petal-fab { position: absolute; left: 50%; bottom: 0; width: 52px; height: 52px; border-radius: 50%; background: linear-gradient(135deg, #7c6cff, #a78bfa); color: #fff; font-size: 26px; line-height: 52px; text-align: center; cursor: pointer; transform: translateX(-50%); transition: transform 0.4s; box-shadow: 0 6px 18px rgba(124,108,255,0.4); z-index: 2; }
.ccm-petal-i { position: absolute; left: 50%; bottom: 12px; width: 36px; height: 36px; border-radius: 50%; background: #1f1f2e; color: #c4b5fd; font-size: 14px; display: flex; align-items: center; justify-content: center; text-decoration: none; border: 1px solid rgba(255,255,255,0.08); transform: translate(-50%, 0) rotate(0) translateY(0) rotate(0); opacity: 0; transition: transform 0.45s cubic-bezier(0.34,1.56,0.64,1), opacity 0.3s; }
.ccm-petal:hover .ccm-petal-fab, .ccm-petal-t:checked + .ccm-petal-fab { transform: translateX(-50%) rotate(45deg); }
.ccm-petal:hover .ccm-petal-i, .ccm-petal-t:checked ~ .ccm-petal-i { transform: translate(-50%, 0) rotate(var(--a)) translateY(-72px) rotate(calc(var(--a) * -1)); opacity: 1; }
.ccm-petal-i:nth-of-type(1) { transition-delay: 0.05s; }
.ccm-petal-i:nth-of-type(2) { transition-delay: 0.10s; }
.ccm-petal-i:nth-of-type(3) { transition-delay: 0.15s; }
.ccm-petal-i:nth-of-type(4) { transition-delay: 0.20s; }
.ccm-petal-i:nth-of-type(5) { transition-delay: 0.25s; }
.ccm-petal-i:nth-of-type(6) { transition-delay: 0.30s; } <div class="ccm-petal"> <input type="checkbox" id="ccm-petal-t" class="ccm-petal-t" hidden> <label for="ccm-petal-t" class="ccm-petal-fab" aria-label="Open menu">+</label> <a href="#" class="ccm-petal-i" style="--a:-90deg" aria-label="Home">⌂</a> <a href="#" class="ccm-petal-i" style="--a:-126deg" aria-label="Search">⌕</a> <a href="#" class="ccm-petal-i" style="--a:-162deg" aria-label="Star">★</a> <a href="#" class="ccm-petal-i" style="--a:-54deg" aria-label="Like">♥</a> <a href="#" class="ccm-petal-i" style="--a:-18deg" aria-label="Mail">✉</a> <a href="#" class="ccm-petal-i" style="--a:-198deg" aria-label="Settings">⚙</a> </div>
.ccm-wheel { position: relative; width: 200px; height: 200px; display: flex; align-items: center; justify-content: center; }
.ccm-wheel-c { width: 44px; height: 44px; border-radius: 50%; background: linear-gradient(135deg, #7c6cff, #ff6c8a); color: #fff; font-size: 18px; display: inline-flex; align-items: center; justify-content: center; box-shadow: 0 0 0 4px rgba(124,108,255,0.18); }
.ccm-wheel-i { position: absolute; top: 50%; left: 50%; width: 32px; height: 32px; margin: -16px; border-radius: 50%; background: #1f1f2e; color: #c4b5fd; font: 700 12px/32px ui-monospace, monospace; text-align: center; text-decoration: none; border: 1px solid rgba(124,108,255,0.3); transform: rotate(var(--a)) translate(78px) rotate(calc(var(--a) * -1)); transition: transform 0.25s, background 0.2s, color 0.2s; }
.ccm-wheel-i:hover, .ccm-wheel-i:focus-visible { background: #7c6cff; color: #fff; transform: rotate(var(--a)) translate(78px) rotate(calc(var(--a) * -1)) scale(1.4); z-index: 2; } <div class="ccm-wheel"> <span class="ccm-wheel-c" aria-hidden="true">◉</span> <a href="#" class="ccm-wheel-i" style="--a:0deg">A</a> <a href="#" class="ccm-wheel-i" style="--a:45deg">B</a> <a href="#" class="ccm-wheel-i" style="--a:90deg">C</a> <a href="#" class="ccm-wheel-i" style="--a:135deg">D</a> <a href="#" class="ccm-wheel-i" style="--a:180deg">E</a> <a href="#" class="ccm-wheel-i" style="--a:225deg">F</a> <a href="#" class="ccm-wheel-i" style="--a:270deg">G</a> <a href="#" class="ccm-wheel-i" style="--a:315deg">H</a> </div>
.ccm-pie { position: relative; width: 170px; height: 170px; }
.ccm-pie-s { position: absolute; width: 50%; height: 50%; background: var(--c); text-decoration: none; cursor: pointer; transition: filter 0.2s, transform 0.2s; display: flex; }
.ccm-pie-tr { top: 0; right: 0; border-top-right-radius: 100% 100%; transform-origin: 0% 100%; }
.ccm-pie-br { bottom: 0; right: 0; border-bottom-right-radius: 100% 100%; transform-origin: 0% 0%; }
.ccm-pie-bl { bottom: 0; left: 0; border-bottom-left-radius: 100% 100%; transform-origin: 100% 0%; }
.ccm-pie-tl { top: 0; left: 0; border-top-left-radius: 100% 100%; transform-origin: 100% 100%; }
.ccm-pie-s span { margin: auto; padding: 8px 18px; font: 700 12px/1 system-ui, sans-serif; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.3); }
.ccm-pie-s:hover, .ccm-pie-s:focus-visible { filter: brightness(1.18) saturate(1.15); transform: scale(1.04); z-index: 2; }
.ccm-pie-h { position: absolute; top: 50%; left: 50%; width: 56px; height: 56px; margin: -28px; border-radius: 50%; background: #15151d; border: 3px solid #17171f; pointer-events: none; z-index: 3; } <div class="ccm-pie"> <a href="#" class="ccm-pie-s ccm-pie-tr" style="--c:#7c6cff" aria-label="Plan"><span>Plan</span></a> <a href="#" class="ccm-pie-s ccm-pie-br" style="--c:#ff6c8a" aria-label="Build"><span>Build</span></a> <a href="#" class="ccm-pie-s ccm-pie-bl" style="--c:#2ecc8a" aria-label="Test"><span>Test</span></a> <a href="#" class="ccm-pie-s ccm-pie-tl" style="--c:#f5a84a" aria-label="Ship"><span>Ship</span></a> <span class="ccm-pie-h" aria-hidden="true"></span> </div>
.ccm-donut { width: 200px; height: 200px; display: block; overflow: visible; font-family: ui-monospace, 'SF Mono', monospace; }
.ccm-donut-s { cursor: pointer; transform-origin: 100px 100px; transform: scale(1) translate(0, 0); transition: transform 0.35s cubic-bezier(0.34,1.56,0.64,1), filter 0.2s; text-decoration: none; animation: ccm-donut-pop 0.5s cubic-bezier(0.34,1.56,0.64,1) backwards; }
.ccm-donut-s path { stroke: #17171f; stroke-width: 2; transition: filter 0.2s; }
.ccm-donut-l { font: 700 10px/1 ui-monospace, monospace; fill: #fff; letter-spacing: 0.18em; pointer-events: none; opacity: 0.92; text-shadow: 0 1px 2px rgba(0,0,0,0.4); }
.ccm-donut-c { font: 700 9px/1 ui-monospace, monospace; fill: #c4b5fd; letter-spacing: 0.16em; pointer-events: none; }
.ccm-donut-s:nth-of-type(1):hover, .ccm-donut-s:nth-of-type(1):focus-visible { transform: translate(4px, -4px); }
.ccm-donut-s:nth-of-type(2):hover, .ccm-donut-s:nth-of-type(2):focus-visible { transform: translate(6px, 0px); }
.ccm-donut-s:nth-of-type(3):hover, .ccm-donut-s:nth-of-type(3):focus-visible { transform: translate(4px, 4px); }
.ccm-donut-s:nth-of-type(4):hover, .ccm-donut-s:nth-of-type(4):focus-visible { transform: translate(-4px, 4px); }
.ccm-donut-s:nth-of-type(5):hover, .ccm-donut-s:nth-of-type(5):focus-visible { transform: translate(-6px, 0px); }
.ccm-donut-s:nth-of-type(6):hover, .ccm-donut-s:nth-of-type(6):focus-visible { transform: translate(-4px, -4px); }
.ccm-donut-s:hover path, .ccm-donut-s:focus-visible path { filter: brightness(1.18) saturate(1.1); }
.ccm-donut-s:nth-of-type(1) { animation-delay: 0.05s; }
.ccm-donut-s:nth-of-type(2) { animation-delay: 0.10s; }
.ccm-donut-s:nth-of-type(3) { animation-delay: 0.15s; }
.ccm-donut-s:nth-of-type(4) { animation-delay: 0.20s; }
.ccm-donut-s:nth-of-type(5) { animation-delay: 0.25s; }
.ccm-donut-s:nth-of-type(6) { animation-delay: 0.30s; } <svg class="ccm-donut" viewBox="0 0 200 200" role="navigation" aria-label="Donut menu">
<defs>
<path id="ccm-donut-arc-1" d="M 100 25 A 75 75 0 0 1 164.95 62.5"/>
<path id="ccm-donut-arc-2" d="M 164.95 62.5 A 75 75 0 0 1 164.95 137.5"/>
<path id="ccm-donut-arc-3" d="M 164.95 137.5 A 75 75 0 0 1 100 175"/>
<path id="ccm-donut-arc-4" d="M 35.05 137.5 A 75 75 0 0 1 35.05 62.5"/>
<path id="ccm-donut-arc-5" d="M 100 175 A 75 75 0 0 1 35.05 137.5"/>
<path id="ccm-donut-arc-6" d="M 35.05 62.5 A 75 75 0 0 1 100 25"/>
</defs>
<a href="#" class="ccm-donut-s" style="--c:#7c6cff" aria-label="Plan">
<path d="M 100 100 L 100 10 A 90 90 0 0 1 177.94 55 Z" fill="var(--c)"/>
<text class="ccm-donut-l"><textPath href="#ccm-donut-arc-1" startOffset="50%" text-anchor="middle">PLAN</textPath></text>
</a>
<a href="#" class="ccm-donut-s" style="--c:#a78bfa" aria-label="Design">
<path d="M 100 100 L 177.94 55 A 90 90 0 0 1 177.94 145 Z" fill="var(--c)"/>
<text class="ccm-donut-l"><textPath href="#ccm-donut-arc-2" startOffset="50%" text-anchor="middle">DESIGN</textPath></text>
</a>
<a href="#" class="ccm-donut-s" style="--c:#ff6c8a" aria-label="Build">
<path d="M 100 100 L 177.94 145 A 90 90 0 0 1 100 190 Z" fill="var(--c)"/>
<text class="ccm-donut-l"><textPath href="#ccm-donut-arc-3" startOffset="50%" text-anchor="middle">BUILD</textPath></text>
</a>
<a href="#" class="ccm-donut-s" style="--c:#f5a84a" aria-label="Test">
<path d="M 100 100 L 100 190 A 90 90 0 0 1 22.06 145 Z" fill="var(--c)"/>
<text class="ccm-donut-l"><textPath href="#ccm-donut-arc-5" startOffset="50%" text-anchor="middle">TEST</textPath></text>
</a>
<a href="#" class="ccm-donut-s" style="--c:#2ecc8a" aria-label="Ship">
<path d="M 100 100 L 22.06 145 A 90 90 0 0 1 22.06 55 Z" fill="var(--c)"/>
<text class="ccm-donut-l"><textPath href="#ccm-donut-arc-4" startOffset="50%" text-anchor="middle">SHIP</textPath></text>
</a>
<a href="#" class="ccm-donut-s" style="--c:#00e5ff" aria-label="Learn">
<path d="M 100 100 L 22.06 55 A 90 90 0 0 1 100 10 Z" fill="var(--c)"/>
<text class="ccm-donut-l"><textPath href="#ccm-donut-arc-6" startOffset="50%" text-anchor="middle">LEARN</textPath></text>
</a>
<circle cx="100" cy="100" r="32" fill="#15151d" stroke="#17171f" stroke-width="3"/>
<text x="100" y="104" class="ccm-donut-c" text-anchor="middle">MENU</text>
</svg> .ccm-half { position: relative; width: 220px; height: 130px; display: flex; align-items: flex-end; justify-content: center; }
.ccm-half-fab { width: 56px; height: 56px; border-radius: 50%; background: linear-gradient(135deg, #2ecc8a, #00e5ff); color: #0a0f0c; font-weight: 700; font-size: 24px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: transform 0.4s; z-index: 2; box-shadow: 0 6px 22px rgba(46,204,138,0.4); }
.ccm-half input:checked + .ccm-half-fab { transform: rotate(180deg); }
.ccm-half-i { position: absolute; bottom: 28px; left: 50%; width: 36px; height: 36px; margin: -18px; border-radius: 50%; background: #1f1f2e; border: 1.5px solid #2ecc8a; color: #2ecc8a; font: 700 12px/36px ui-monospace, monospace; text-align: center; text-decoration: none; transform: translate(0, 0) rotate(var(--a)) translate(0) rotate(calc(var(--a) * -1)); opacity: 0; transition: transform 0.5s cubic-bezier(0.34,1.56,0.64,1), opacity 0.3s; }
.ccm-half input:checked ~ .ccm-half-i { transform: translate(0, 0) rotate(var(--a)) translate(80px) rotate(calc(var(--a) * -1)); opacity: 1; }
.ccm-half-i:nth-of-type(1) { transition-delay: 0.05s; }
.ccm-half-i:nth-of-type(2) { transition-delay: 0.10s; }
.ccm-half-i:nth-of-type(3) { transition-delay: 0.15s; }
.ccm-half-i:nth-of-type(4) { transition-delay: 0.20s; }
.ccm-half-i:nth-of-type(5) { transition-delay: 0.25s; } <div class="ccm-half"> <input type="checkbox" id="ccm-half-t" hidden> <label for="ccm-half-t" class="ccm-half-fab" aria-label="Toggle">⊕</label> <a href="#" class="ccm-half-i" style="--a:180deg">A</a> <a href="#" class="ccm-half-i" style="--a:225deg">B</a> <a href="#" class="ccm-half-i" style="--a:270deg">C</a> <a href="#" class="ccm-half-i" style="--a:315deg">D</a> <a href="#" class="ccm-half-i" style="--a:0deg">E</a> </div>
.ccm-glass-bg { padding: 30px; border-radius: 14px; background: linear-gradient(135deg, #7c6cff 0%, #ff6c8a 100%); }
.ccm-glass { position: relative; width: 200px; height: 110px; }
.ccm-glass-dome { position: absolute; bottom: 0; left: 0; right: 0; height: 110px; border-radius: 100px 100px 0 0; background: rgba(255,255,255,0.18); border: 1px solid rgba(255,255,255,0.45); border-bottom: none; backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); box-shadow: inset 0 1px 0 rgba(255,255,255,0.6), inset 0 -10px 30px rgba(255,255,255,0.1); }
.ccm-glass-dome::before { content: ''; position: absolute; top: 8px; left: 20%; right: 50%; height: 24px; border-radius: 50%; background: linear-gradient(180deg, rgba(255,255,255,0.55), transparent); filter: blur(2px); }
.ccm-glass-i { position: absolute; bottom: 0; left: 50%; width: 32px; height: 32px; margin-left: -16px; border-radius: 50%; background: rgba(255,255,255,0.25); border: 1px solid rgba(255,255,255,0.5); color: #fff; display: flex; align-items: center; justify-content: center; text-decoration: none; transform: rotate(var(--a)) translate(95px) rotate(calc(var(--a) * -1)); transition: transform 0.3s, background 0.2s; backdrop-filter: blur(6px); }
.ccm-glass-i:hover { background: rgba(255,255,255,0.45); transform: rotate(var(--a)) translate(95px) rotate(calc(var(--a) * -1)) scale(1.18) translateY(-6px); } <div class="ccm-glass-bg">
<div class="ccm-glass">
<div class="ccm-glass-dome"></div>
<a href="#" class="ccm-glass-i" style="--a:-150deg">⌂</a>
<a href="#" class="ccm-glass-i" style="--a:-120deg">⌕</a>
<a href="#" class="ccm-glass-i" style="--a:-90deg">★</a>
<a href="#" class="ccm-glass-i" style="--a:-60deg">♥</a>
<a href="#" class="ccm-glass-i" style="--a:-30deg">⚙</a>
</div>
</div> .ccm-holo { position: relative; width: 200px; height: 110px; }
.ccm-holo-rim { position: absolute; bottom: -2px; left: -2px; right: -2px; height: 114px; border-radius: 100px 100px 0 0; background: conic-gradient(from var(--ccm-holo-a), #7c6cff, #ff6c8a, #2ecc8a, #00e5ff, #7c6cff); animation: ccm-holo-spin 4s linear infinite; filter: blur(0.5px); }
.ccm-holo-dome { position: absolute; bottom: 0; left: 0; right: 0; height: 110px; border-radius: 100px 100px 0 0; background: rgba(15,15,25,0.7); backdrop-filter: blur(8px); border-bottom: none; }
.ccm-holo-i { position: absolute; bottom: 0; left: 50%; width: 32px; height: 32px; margin-left: -16px; border-radius: 50%; background: #15151d; border: 1px solid rgba(255,255,255,0.18); color: #c4b5fd; display: flex; align-items: center; justify-content: center; text-decoration: none; transform: rotate(var(--a)) translate(95px) rotate(calc(var(--a) * -1)); transition: transform 0.3s, color 0.2s; }
.ccm-holo-i:hover { color: #fff; transform: rotate(var(--a)) translate(95px) rotate(calc(var(--a) * -1)) scale(1.2); }
@media (prefers-reduced-motion: reduce) {
.ccm-holo-rim,
.ccm-snow-flakes,
.ccm-orbit-sat, .ccm-orbit-i,
.ccm-solar-o, .ccm-solar-o a,
.ccm-tri-grp,
.ccm-vinyl-disc,
.ccm-bh-disk,
.ccm-neb-cloud, .ccm-neb-i { animation: none !important; }
} <div class="ccm-holo"> <div class="ccm-holo-rim"></div> <div class="ccm-holo-dome"></div> <a href="#" class="ccm-holo-i" style="--a:-150deg">⌂</a> <a href="#" class="ccm-holo-i" style="--a:-120deg">⌕</a> <a href="#" class="ccm-holo-i" style="--a:-90deg">★</a> <a href="#" class="ccm-holo-i" style="--a:-60deg">♥</a> <a href="#" class="ccm-holo-i" style="--a:-30deg">⚙</a> </div>
.ccm-orbit { position: relative; width: 180px; height: 180px; display: flex; align-items: center; justify-content: center; }
.ccm-orbit-track { position: absolute; inset: 20px; border-radius: 50%; border: 1px dashed rgba(124,108,255,0.3); }
.ccm-orbit-c { width: 48px; height: 48px; border-radius: 50%; background: linear-gradient(135deg, #7c6cff, #a78bfa); color: #fff; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; font-size: 18px; z-index: 2; box-shadow: 0 0 0 4px rgba(124,108,255,0.18); }
.ccm-orbit-sat { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; animation: ccm-orbit-spin 5s linear infinite; }
.ccm-orbit-i { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; border-radius: 50%; background: #1f1f2e; color: #c4b5fd; text-decoration: none; border: 1px solid rgba(124,108,255,0.4); transform: translate(70px); animation: ccm-orbit-counter 5s linear infinite; }
.ccm-orbit:hover .ccm-orbit-sat, .ccm-orbit:hover .ccm-orbit-i { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
.ccm-holo-rim,
.ccm-snow-flakes,
.ccm-orbit-sat, .ccm-orbit-i,
.ccm-solar-o, .ccm-solar-o a,
.ccm-tri-grp,
.ccm-vinyl-disc,
.ccm-bh-disk,
.ccm-neb-cloud, .ccm-neb-i { animation: none !important; }
} <div class="ccm-orbit"> <div class="ccm-orbit-track"></div> <div class="ccm-orbit-sat"><a href="#" class="ccm-orbit-i" aria-label="Item">◆</a></div> <a href="#" class="ccm-orbit-c" aria-label="Center">◉</a> </div>
.ccm-solar { position: relative; width: 240px; height: 240px; display: flex; align-items: center; justify-content: center; }
.ccm-solar-c { width: 36px; height: 36px; border-radius: 50%; background: radial-gradient(circle at 30% 30%, #ffd479, #f5a84a); display: inline-flex; align-items: center; justify-content: center; color: rgba(255,255,255,0.85); font-size: 20px; text-decoration: none; box-shadow: 0 0 24px #f5a84a; z-index: 5; }
.ccm-solar-o { position: absolute; border-radius: 50%; border: 1px dashed rgba(255,255,255,0.08); animation: ccm-solar-spin linear infinite; }
.ccm-solar-o1 { inset: 20px; animation-duration: 11s; }
.ccm-solar-o2 { inset: 50px; animation-duration: 8s; }
.ccm-solar-o3 { inset: 80px; animation-duration: 6s; }
.ccm-solar-o4 { inset: 105px; animation-duration: 4s; }
.ccm-solar-pos { position: absolute; top: 0; left: 50%; width: 0; height: 0; }
.ccm-solar-p { position: absolute; top: 0; left: 0; width: 24px; height: 24px; margin: -12px; border-radius: 50%; background: #1f1f2e; color: #c4b5fd; font-size: 13px; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; border: 1px solid rgba(124,108,255,0.4); animation: ccm-solar-counter linear infinite; z-index: 6; }
.ccm-solar-o1 .ccm-solar-p { animation-duration: 11s; }
.ccm-solar-o2 .ccm-solar-p { animation-duration: 8s; }
.ccm-solar-o3 .ccm-solar-p { animation-duration: 6s; }
.ccm-solar-o4 .ccm-solar-p { animation-duration: 4s; }
.ccm-solar-p:hover { background: #7c6cff; color: #fff; }
.ccm-solar:hover .ccm-solar-o, .ccm-solar:hover .ccm-solar-p { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
.ccm-holo-rim,
.ccm-snow-flakes,
.ccm-orbit-sat, .ccm-orbit-i,
.ccm-solar-o, .ccm-solar-o a,
.ccm-tri-grp,
.ccm-vinyl-disc,
.ccm-bh-disk,
.ccm-neb-cloud, .ccm-neb-i { animation: none !important; }
} <div class="ccm-solar"> <a href="#" class="ccm-solar-c" aria-label="Sun">☀</a> <div class="ccm-solar-o ccm-solar-o1"><span class="ccm-solar-pos"><a href="#" class="ccm-solar-p" aria-label="Mercury">☿</a></span></div> <div class="ccm-solar-o ccm-solar-o2"><span class="ccm-solar-pos"><a href="#" class="ccm-solar-p" aria-label="Venus">♀</a></span></div> <div class="ccm-solar-o ccm-solar-o3"><span class="ccm-solar-pos"><a href="#" class="ccm-solar-p" aria-label="Earth">♁</a></span></div> <div class="ccm-solar-o ccm-solar-o4"><span class="ccm-solar-pos"><a href="#" class="ccm-solar-p" aria-label="Mars">♂</a></span></div> </div>
.ccm-hex { position: relative; width: 200px; height: 200px; display: flex; align-items: center; justify-content: center; }
.ccm-hex-c, .ccm-hex-i { width: 50px; height: 58px; clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%); display: inline-flex; align-items: center; justify-content: center; font: 700 11px/1 system-ui, sans-serif; text-decoration: none; transition: transform 0.2s, background 0.2s; }
.ccm-hex-c { background: linear-gradient(135deg, #7c6cff, #a78bfa); color: #fff; position: relative; z-index: 2; }
.ccm-hex-i { position: absolute; top: 50%; left: 50%; margin: -29px -25px; background: #1f1f2e; color: #c4b5fd; transform: rotate(var(--a)) translate(64px) rotate(calc(var(--a) * -1)); }
.ccm-hex-i:hover, .ccm-hex-i:focus-visible { background: #2a2a3e; color: #fff; transform: rotate(var(--a)) translate(64px) rotate(calc(var(--a) * -1)) scale(1.1); } <div class="ccm-hex"> <a href="#" class="ccm-hex-c" aria-label="Center">◆</a> <a href="#" class="ccm-hex-i" style="--a:-90deg" aria-label="N">N</a> <a href="#" class="ccm-hex-i" style="--a:-30deg" aria-label="NE">NE</a> <a href="#" class="ccm-hex-i" style="--a:30deg" aria-label="SE">SE</a> <a href="#" class="ccm-hex-i" style="--a:90deg" aria-label="S">S</a> <a href="#" class="ccm-hex-i" style="--a:150deg" aria-label="SW">SW</a> <a href="#" class="ccm-hex-i" style="--a:210deg" aria-label="NW">NW</a> </div>
.ccm-tri { position: relative; width: 180px; height: 180px; display: flex; align-items: center; justify-content: center; }
.ccm-tri-grp { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; animation: ccm-tri-spin 16s linear infinite; }
.ccm-tri-i { position: absolute; width: 48px; height: 48px; display: inline-flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #ff6c8a, #f5a84a); color: #fff; font: 700 14px/1 system-ui, sans-serif; text-decoration: none; clip-path: polygon(50% 5%, 95% 95%, 5% 95%); transform: rotate(var(--a)) translate(60px); transition: transform 0.3s; }
.ccm-tri-i:hover { transform: rotate(var(--a)) translate(60px) scale(1.2); filter: drop-shadow(0 4px 12px rgba(255,108,138,0.5)); z-index: 2; }
.ccm-tri-c { width: 14px; height: 14px; border-radius: 50%; background: #1f1f2e; border: 2px solid #7c6cff; position: relative; z-index: 1; }
@media (prefers-reduced-motion: reduce) {
.ccm-holo-rim,
.ccm-snow-flakes,
.ccm-orbit-sat, .ccm-orbit-i,
.ccm-solar-o, .ccm-solar-o a,
.ccm-tri-grp,
.ccm-vinyl-disc,
.ccm-bh-disk,
.ccm-neb-cloud, .ccm-neb-i { animation: none !important; }
} <div class="ccm-tri">
<div class="ccm-tri-grp">
<a href="#" class="ccm-tri-i" style="--a:-90deg">A</a>
<a href="#" class="ccm-tri-i" style="--a:30deg">B</a>
<a href="#" class="ccm-tri-i" style="--a:150deg">C</a>
</div>
<span class="ccm-tri-c" aria-hidden="true">◯</span>
</div> .ccm-vinyl { position: relative; width: 200px; height: 200px; display: flex; align-items: center; justify-content: center; }
.ccm-vinyl-disc { width: 200px; height: 200px; border-radius: 50%; background: radial-gradient(circle at center, #1a1a1a 30%, transparent 31%), repeating-radial-gradient(circle at center, #0a0a0a 0, #0a0a0a 1px, #1a1a1a 1px, #1a1a1a 3px); position: relative; animation: ccm-vinyl-spin 8s linear infinite; box-shadow: 0 0 0 1px rgba(255,255,255,0.05), 0 8px 24px rgba(0,0,0,0.5); }
.ccm-vinyl-disc::after { content: ''; position: absolute; top: 50%; left: 50%; width: 8px; height: 8px; margin: -4px; border-radius: 50%; background: #f5a84a; }
.ccm-vinyl-label { position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; margin: -50px; border-radius: 50%; background: linear-gradient(135deg, #ff6c8a, #f5a84a); }
.ccm-vinyl-i { position: absolute; top: 50%; left: 50%; width: 22px; height: 22px; margin: -11px; border-radius: 50%; background: rgba(0,0,0,0.45); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 11px; text-decoration: none; transform: rotate(var(--a)) translate(28px) rotate(calc(var(--a) * -1)); }
.ccm-vinyl-i:hover { background: rgba(0,0,0,0.7); }
.ccm-vinyl:hover .ccm-vinyl-disc { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
.ccm-holo-rim,
.ccm-snow-flakes,
.ccm-orbit-sat, .ccm-orbit-i,
.ccm-solar-o, .ccm-solar-o a,
.ccm-tri-grp,
.ccm-vinyl-disc,
.ccm-bh-disk,
.ccm-neb-cloud, .ccm-neb-i { animation: none !important; }
} <div class="ccm-vinyl">
<div class="ccm-vinyl-disc">
<div class="ccm-vinyl-label">
<a href="#" class="ccm-vinyl-i" style="--a:-90deg">▶</a>
<a href="#" class="ccm-vinyl-i" style="--a:0deg">♫</a>
<a href="#" class="ccm-vinyl-i" style="--a:90deg">♪</a>
<a href="#" class="ccm-vinyl-i" style="--a:180deg">⏏</a>
</div>
</div>
</div> .ccm-compass { position: relative; width: 190px; height: 190px; display: flex; align-items: center; justify-content: center; }
.ccm-compass-face { width: 160px; height: 160px; border-radius: 50%; background: radial-gradient(circle at center, #2a2a3e, #15151d); border: 2px solid rgba(212,175,55,0.5); box-shadow: inset 0 0 24px rgba(212,175,55,0.2), 0 4px 16px rgba(0,0,0,0.4); }
.ccm-compass-needle { position: absolute; top: 50%; left: 50%; width: 4px; height: 70px; margin: -35px -2px; background: linear-gradient(180deg, #ff3d6e 0 50%, #d4af37 50% 100%); transform-origin: center; transform: rotate(0deg); transition: transform 0.6s cubic-bezier(0.34,1.56,0.64,1); border-radius: 2px; }
.ccm-compass:has(#ccm-compass-n:checked) .ccm-compass-needle { transform: rotate(0deg); }
.ccm-compass:has(#ccm-compass-e:checked) .ccm-compass-needle { transform: rotate(90deg); }
.ccm-compass:has(#ccm-compass-s:checked) .ccm-compass-needle { transform: rotate(180deg); }
.ccm-compass:has(#ccm-compass-w:checked) .ccm-compass-needle { transform: rotate(270deg); }
.ccm-compass-i { position: absolute; top: 50%; left: 50%; width: 28px; height: 28px; margin: -14px; border-radius: 50%; background: rgba(212,175,55,0.18); color: #ffd479; font: 700 12px/28px ui-monospace, monospace; text-align: center; cursor: pointer; border: 1px solid rgba(212,175,55,0.4); transform: rotate(var(--a)) translate(80px) rotate(calc(var(--a) * -1)); transition: background 0.2s, color 0.2s, transform 0.2s; }
.ccm-compass-i:hover { background: rgba(212,175,55,0.4); color: #fff; } <div class="ccm-compass"> <input type="radio" name="ccm-compass" id="ccm-compass-n" hidden checked> <input type="radio" name="ccm-compass" id="ccm-compass-e" hidden> <input type="radio" name="ccm-compass" id="ccm-compass-s" hidden> <input type="radio" name="ccm-compass" id="ccm-compass-w" hidden> <div class="ccm-compass-face"></div> <div class="ccm-compass-needle" aria-hidden="true"></div> <label for="ccm-compass-n" class="ccm-compass-i" style="--a:0deg">N</label> <label for="ccm-compass-e" class="ccm-compass-i" style="--a:90deg">E</label> <label for="ccm-compass-s" class="ccm-compass-i" style="--a:180deg">S</label> <label for="ccm-compass-w" class="ccm-compass-i" style="--a:270deg">W</label> </div>
.ccm-iris { position: relative; width: 200px; height: 200px; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: radial-gradient(circle at center, #0a0a14 30%, #15151d); border: 4px solid #2a2a3e; }
.ccm-iris-blade { position: absolute; top: 50%; left: 50%; width: 100px; height: 100px; margin: -50px; background: linear-gradient(135deg, #2a2a3e, #15151d); clip-path: polygon(50% 0%, 100% 50%, 50% 50%); transform: rotate(var(--a)) translateY(-30px); transform-origin: center; transition: transform 0.5s cubic-bezier(0.65,0,0.35,1); }
.ccm-iris:hover .ccm-iris-blade { transform: rotate(calc(var(--a) + 30deg)) translateY(-50px); }
.ccm-iris-i { position: absolute; top: 50%; left: 50%; width: 28px; height: 28px; margin: -14px; border-radius: 50%; background: #1f1f2e; color: #00e5ff; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; border: 1px solid rgba(0,229,255,0.4); transform: rotate(var(--a)) translate(70px) rotate(calc(var(--a) * -1)); opacity: 0; transition: opacity 0.4s ease 0.25s; z-index: 2; }
.ccm-iris:hover .ccm-iris-i { opacity: 1; }
.ccm-iris-i:hover { background: #00e5ff; color: #0a0a14; } <div class="ccm-iris"> <div class="ccm-iris-blade" style="--a:0deg"></div> <div class="ccm-iris-blade" style="--a:60deg"></div> <div class="ccm-iris-blade" style="--a:120deg"></div> <div class="ccm-iris-blade" style="--a:180deg"></div> <div class="ccm-iris-blade" style="--a:240deg"></div> <div class="ccm-iris-blade" style="--a:300deg"></div> <a href="#" class="ccm-iris-i" style="--a:-90deg">◐</a> <a href="#" class="ccm-iris-i" style="--a:-30deg">◑</a> <a href="#" class="ccm-iris-i" style="--a:30deg">◒</a> <a href="#" class="ccm-iris-i" style="--a:90deg">◓</a> <a href="#" class="ccm-iris-i" style="--a:150deg">◉</a> <a href="#" class="ccm-iris-i" style="--a:210deg">○</a> </div>
.ccm-bh { position: relative; width: 200px; height: 200px; display: flex; align-items: center; justify-content: center; }
.ccm-bh-disk { position: absolute; top: 50%; left: 50%; width: 110px; height: 110px; margin: -55px; border-radius: 50%; background: conic-gradient(from 0deg, #d4af37, #ff6c8a, #7c6cff, #d4af37); filter: blur(6px); animation: ccm-bh-spin 8s linear infinite; transition: filter 0.4s; z-index: 1; }
.ccm-bh:hover .ccm-bh-disk { filter: blur(4px) brightness(1.3); }
.ccm-bh-core { position: absolute; top: 50%; left: 50%; width: 56px; height: 56px; margin: -28px; border-radius: 50%; background: #000; box-shadow: 0 0 30px 8px rgba(0,0,0,0.7); z-index: 2; }
.ccm-bh-i { position: absolute; top: 50%; left: 50%; width: 30px; height: 30px; margin: -15px; border-radius: 50%; background: #1f1f2e; color: #ffd479; display: inline-flex; align-items: center; justify-content: center; font: 700 12px/1 ui-monospace, monospace; text-decoration: none; border: 1px solid rgba(212,175,55,0.5); transform: rotate(var(--a)) translate(80px) rotate(calc(var(--a) * -1)); transition: transform 0.5s cubic-bezier(0.34,1.56,0.64,1), background 0.2s, color 0.2s, box-shadow 0.3s; z-index: 3; }
.ccm-bh:hover .ccm-bh-i { transform: rotate(var(--a)) translate(92px) rotate(calc(var(--a) * -1)); box-shadow: 0 0 12px rgba(212,175,55,0.45); }
.ccm-bh-i:hover, .ccm-bh-i:focus-visible { background: #ffd479; color: #0a0a14; transform: rotate(var(--a)) translate(96px) rotate(calc(var(--a) * -1)) scale(1.2); z-index: 4; }
@media (prefers-reduced-motion: reduce) {
.ccm-holo-rim,
.ccm-snow-flakes,
.ccm-orbit-sat, .ccm-orbit-i,
.ccm-solar-o, .ccm-solar-o a,
.ccm-tri-grp,
.ccm-vinyl-disc,
.ccm-bh-disk,
.ccm-neb-cloud, .ccm-neb-i { animation: none !important; }
} <div class="ccm-bh"> <div class="ccm-bh-disk" aria-hidden="true"></div> <div class="ccm-bh-core" aria-hidden="true"></div> <a href="#" class="ccm-bh-i" style="--a:-90deg" aria-label="Item A">A</a> <a href="#" class="ccm-bh-i" style="--a:-30deg" aria-label="Item B">B</a> <a href="#" class="ccm-bh-i" style="--a:30deg" aria-label="Item C">C</a> <a href="#" class="ccm-bh-i" style="--a:90deg" aria-label="Item D">D</a> <a href="#" class="ccm-bh-i" style="--a:150deg" aria-label="Item E">E</a> <a href="#" class="ccm-bh-i" style="--a:210deg" aria-label="Item F">F</a> </div>
.ccm-chrono { position: relative; width: 190px; height: 190px; display: flex; align-items: center; justify-content: center; --hand: 90deg; }
.ccm-chrono-face { width: 170px; height: 170px; border-radius: 50%; background: radial-gradient(circle at 30% 30%, #f5f5f5, #d8d8d8); border: 3px solid #2a2a3e; box-shadow: inset 0 2px 4px rgba(0,0,0,0.15), 0 4px 12px rgba(0,0,0,0.4); }
.ccm-chrono-hand { position: absolute; top: 50%; left: 50%; width: 3px; height: 60px; margin-left: -1.5px; background: #2a2a3e; border-radius: 1.5px; transform-origin: top center; transform: rotate(var(--hand)); transition: transform 0.6s cubic-bezier(0.34,1.56,0.64,1); }
.ccm-chrono-hand::after { content: ''; position: absolute; bottom: -3px; left: -2px; width: 7px; height: 7px; border-radius: 50%; background: #ff3d6e; }
.ccm-chrono:has(#ccm-chrono-3:checked) { --hand: -90deg; }
.ccm-chrono:has(#ccm-chrono-6:checked) { --hand: 0deg; }
.ccm-chrono:has(#ccm-chrono-9:checked) { --hand: 90deg; }
.ccm-chrono:has(#ccm-chrono-12:checked) { --hand: 180deg; }
.ccm-chrono-i { position: absolute; top: 50%; left: 50%; width: 28px; height: 28px; margin: -14px; border-radius: 50%; background: rgba(0,0,0,0.05); color: #2a2a3e; font: 700 13px/28px Georgia, serif; text-align: center; cursor: pointer; transform: rotate(var(--a)) translate(70px) rotate(calc(var(--a) * -1)); transition: background 0.2s, color 0.2s; }
.ccm-chrono-i:hover { background: rgba(255,61,110,0.15); color: #ff3d6e; } <div class="ccm-chrono"> <input type="radio" name="ccm-chrono" id="ccm-chrono-3" hidden checked> <input type="radio" name="ccm-chrono" id="ccm-chrono-6" hidden> <input type="radio" name="ccm-chrono" id="ccm-chrono-9" hidden> <input type="radio" name="ccm-chrono" id="ccm-chrono-12" hidden> <div class="ccm-chrono-face"></div> <div class="ccm-chrono-hand" aria-hidden="true"></div> <label for="ccm-chrono-12" class="ccm-chrono-i" style="--a:0deg" aria-label="12">12</label> <label for="ccm-chrono-3" class="ccm-chrono-i" style="--a:90deg" aria-label="3">3</label> <label for="ccm-chrono-6" class="ccm-chrono-i" style="--a:180deg" aria-label="6">6</label> <label for="ccm-chrono-9" class="ccm-chrono-i" style="--a:270deg" aria-label="9">9</label> </div>
.ccm-neb { position: relative; width: 220px; height: 180px; display: flex; align-items: center; justify-content: center; }
.ccm-neb-cloud { position: absolute; inset: 0; background: radial-gradient(60% 50% at 30% 40%, rgba(124,108,255,0.45), transparent 70%), radial-gradient(50% 40% at 70% 60%, rgba(255,108,138,0.4), transparent 70%), radial-gradient(45% 35% at 50% 30%, rgba(46,184,138,0.3), transparent 70%); filter: blur(10px); animation: ccm-neb-drift 10s ease-in-out infinite alternate; }
.ccm-neb-i { position: absolute; top: 50%; left: 50%; width: 36px; height: 36px; margin: -18px; border-radius: 50%; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.18); color: #fff; font-size: 14px; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; transform: translate(var(--x), var(--y)); animation: ccm-neb-float 4s ease-in-out var(--d) infinite alternate; transition: transform 0.3s, background 0.2s, box-shadow 0.3s; z-index: 2; }
.ccm-neb-i:hover { background: rgba(255,255,255,0.25); box-shadow: 0 0 20px rgba(255,255,255,0.4); transform: translate(var(--x), var(--y)) scale(1.3); animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
.ccm-holo-rim,
.ccm-snow-flakes,
.ccm-orbit-sat, .ccm-orbit-i,
.ccm-solar-o, .ccm-solar-o a,
.ccm-tri-grp,
.ccm-vinyl-disc,
.ccm-bh-disk,
.ccm-neb-cloud, .ccm-neb-i { animation: none !important; }
} <div class="ccm-neb"> <div class="ccm-neb-cloud"></div> <a href="#" class="ccm-neb-i" style="--x:-50px;--y:-30px;--d:0s">★</a> <a href="#" class="ccm-neb-i" style="--x:30px;--y:-40px;--d:1s">✦</a> <a href="#" class="ccm-neb-i" style="--x:60px;--y:10px;--d:2s">✧</a> <a href="#" class="ccm-neb-i" style="--x:0px;--y:30px;--d:1.5s">◆</a> <a href="#" class="ccm-neb-i" style="--x:-60px;--y:20px;--d:0.5s">⬢</a> </div>
Build your own
Tweak the exact look in our visual generators — no signup, instant copy-paste.
Frequently asked questions
What is a CSS circular menu?
How do you position items in a circle with pure CSS?
How do you add curved text along a donut sector?
Are these circular menus accessible?
Do circular menus work on touch devices?
Can I use these circular menus in any framework?
Related collections
26 CSS Accordions — Vertical & Horizontal
26 free CSS accordions — 17 vertical and 9 horizontal layouts with copy-paste HTML and CSS.
22 CSS Breadcrumbs
22 original CSS breadcrumb designs — underline grow, pill, diagonal slash, neon trail, brutalist, frosted glass, vertical stacked, progress track, holographic shimmer and more.
20 CSS Tabs
20 original CSS tab designs — ink slider, aurora pill, frosted crystal, brutalist press, iOS segmented, bento grid, CRT terminal and more. Copy-paste ready.