可用CSS变量+sin()/cos()实现环形菜单布局,需浏览器支持原生三角函数(Chrome 115+/Firefox 117+/Safari 16.4+),用@supports检测并降级,--angle须带角度单位,配合transform: translate(-50%,-50%)居中,动态数量需服务端注入--i变量。

直接用 CSS 变量 + sin() 和 cos() 就能算出每个菜单项的坐标,不需要 JS 计算位置,也不用预设一堆 nth-child 规则 —— 但前提是浏览器支持原生三角函数(Chrome 115+、Firefox 117+、Safari 16.4+)。
确认浏览器是否支持 sin()/cos()
不加判断直接写会触发无效声明(被忽略),且无报错提示。最稳妥的方式是用 @supports 包裹关键布局规则:
- 检查是否支持:
@supports (transform: translate(calc(sin(0deg) * 1px), 0)) - 不支持时降级为静态中心堆叠或 JS 补充定位
- 注意:仅检测
sin()不够,cos()可能单独不支持(极少见,但 Safari 16.3 有此问题)
--angle 必须是角度单位,不能传纯数字
CSS 三角函数只接受带单位的角度值(deg、rad、turn),传 30 或 var(--i)(未带单位)会导致整个 calc() 失效,元素位置塌陷到左上角。
- 正确写法:
--angle: calc((var(--i) - 1) * 30deg) - 错误写法:
--angle: calc((var(--i) - 1) * 30)(无单位) - 若用 SCSS/Less 预处理,记得显式拼接单位字符串,如
#{$i * 30}deg
坐标计算必须配合 transform: translate(-50%, -50%)
因为 left 和 top 是基于父容器左上角定位的,而 sin()/cos() 算出的是绝对像素偏移,直接赋值会导致菜单项“贴边”而非“环绕”。
立即学习“前端免费学习笔记(深入)”;
- 假设圆心在
50% 50%,半径--r: 120px,则:--x: calc(50% + var(--r) * cos(var(--angle)));--y: calc(50% + var(--r) * sin(var(--angle))); - 但此时元素左上角落在该坐标,需用
transform: translate(-50%, -50%)把自身中心对齐过去 - 漏掉这步,所有菜单项会整体偏右下约半个自身尺寸
动态数量菜单需用 CSS 自定义属性递增,不能依赖 :nth-child
如果菜单项数量不固定(比如由 CMS 输出),硬写 div:nth-child(1) 到 12 会失效。可行方案只有两种:
- 服务端/构建时生成带
style="--i: 1"的内联变量(推荐,兼容性好) - 用
@property声明--i并配合animation触发(复杂,且 Safari 对@property类型限制严) - 千万别试图用
attr(data-index)转成数值 —— CSS 不支持字符串转数字
最易被忽略的是:当菜单项少于 12 个时,--i 的起始值必须从 1 开始连续,否则角度间隔错位,环形就“缺一块”。



















