Cyclical keyboard UX with a radio group and CSS trig functions

Adam Argyle March 10, 2023
Source

CSS trig functions can do some neat layout stuff, like circles! In this bite size blog post I quickly share how I turned the cyclical roving tab index feature of a radio group, into a circle so it can cycle seamlessly. I'm just inside a radio group usin arrow keys. The gist # Bramus wrote a great post on the new CSS trigonometry functions , and it got me thinking. Those thoughts led to this demo , where I wanted the infinite cycling of focus of a radio group, to tail call itself via a circle layout. < fieldset style = "--sibling-count: 8" > < input style = "--sibling-index: 1" type = "radio" name = "cyclical-group" checked> < input style = "--sibling-index: 2" type = "radio" name = "cyclical-group" > < input style = "--sibling-index: 3" type = "radio" name = "cyclical-group" > < input style = "--sibling-index: 4" type = "radio" name = "cyclical-group" > < input style = "--sibling-index: 5" type = "radio" name = "cyclical-group" > < input style = "--sibling-index: 6" type = "radio" name = "cyclical-group" > < input style = "--sibling-index: 7" type = "radio" name = "cyclical-group" > < input style = "--sibling-index: 8" type = "radio" name = "cyclical-group" > </ fieldset > I also used a custom property version of this spec proposal I have open with the CSSWG for sibling-count() and sibling-index() , where an element could know how many siblings it has and which index it currently is. By "used a version of this proposal" I mean, I hand wrote the values ๐Ÿ˜… fieldset { /* divide circle by total children / --_offset : calc (360 deg / var (--sibling-count)) ; / size also used for circle translateX and Y / --_circle-size : 25 vmin ; inline-size : var (--_circle-size) ; block-size : var (--_circle-size) ; / 1x1 centered cell / --_cell-size : 10 vmin ; display : grid ; place-content : center ; grid : var (--_cell-size) / var (--_cell-size) ; / stack them together in 1 cell / > * { grid-area : 1/1 ; } } Get used to that nesting syntax!! woot woot! With a grid layout setup with all the radios aligned in the middle, and the radius known of the circle, we can do the math. input { / take child index * circle fraction offset / --_angle : calc ( var (--sibling-index) * var (--_offset)) ; / cos() translateX, sin() translateY */ translate : calc ( cos ( var (--_angle)) * var (--_circle-size)) calc ( sin ( var (--_angle)) * var (--_circle-size)) ; } And that's that, individual transforms making x and y easy to set. Each radio takes it's current index and multiplies it by the ratio in offset, then uses that angle against the circle radius with cos() and sin() . Rad. Try it on Codepen # I used CSS nesting and trig functions, so you'll need Canary with web experiements turns on, for now. See the Pen by Adam Argyle ( @argyleink ) on CodePen .

Discussion in the ATmosphere

Loading comments...