Back to CSS Circular Menus Tactile Dial Pure CSS
Share
.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>
Live preview Edit any tab — preview updates live Ready