Advertisement

Radial Dial Control Menu

| by Vladimir | 2 min read | code by LukyVJ
Advanced

Tech & Dependencies

HTML SCSS JavaScript

Features

  • CSS @property
  • Radial Layout
  • Dynamic Color
  • CSS :has()

Browser Support

Chrome 115+ Edge 115+ Safari 16.4+ Firefox 128+

Core

This is a Radial Dial Control Menu. It replaces traditional linear dropdowns with a rotary, hardware-inspired interface. Its function is to provide rapid, omnidirectional access to secondary actions, utilizing the user’s spatial memory and reducing cursor travel distance.

Specs

  • Weight: ~7 KB (SCSS). Zero external dependencies.
  • Performance: High, but relies heavily on experimental CSS features.
  • Theming / Customization: Controlled via CSS custom properties. It natively supports a data-theme="dark" attribute for instant theme switching.
  • Responsiveness: Scales dynamically using a calculated --radius variable bound to vw units.

Anatomy

  • HTML: A structural .selector wrapper containing a .knob div and an unordered list <ul>. Each <li> houses a visually hidden label and a functional <input type="radio">.
  • CSS (SCSS): The powerhouse. It registers custom properties via @property to allow CSS transitions on geometric angles and colors. The layout distributes the list items radially using trigonometric math embedded in SCSS for loops.
  • JS: A minimal operational bridge. It listens for clicks on the central .knob to toggle the .active class and resets the internal radio button states when the dial closes.

Logic

The standout feature is the orchestration of state entirely through the CSS :has() selector and custom @property registration.

@property --angle {
  syntax: "<number>";
  initial-value: -90deg;
  inherits: true;
}

/* State Management via :has() */
@for $i from 1 to 7 {
  &:has(li:nth-child(#{$i}) input[type="radio"]:checked) {
    --angle: calc(calc((360deg / 6) * #{$i - 1}) - var(--angle-offset));
    --color-accent-on-code: var(--angle) 100% 72%;
    
    /* ... */
  }
}

Instead of using JavaScript to calculate the knob’s rotation angle and apply inline styles, the CSS engine actively monitors the DOM tree. When a specific radio button is :checked, the :has() pseudo-class instantly recalculates the global --angle variable. Because --angle is registered as a <number> via @property, the browser natively interpolates the rotation and dynamically shifts the hue of the neon glow based on that exact angle.

Feel

Mechanical, precise, and highly satisfying. Clicking the center knob causes the menu to physically expand, mimicking the iris of a camera lens. Selecting an item rotates the central indicator with smooth, engineered easing, while the glowing accent color shifts in real-time. It feels less like navigating a webpage and more like operating a premium piece of audio equipment.

Advertisement