仅用 CSS 实现元素圆形排列的方法

说在前面,别怪我没提醒你。在这个卷生卷死的前端圈,用纯CSS把一堆元素死死摁在环形布局上,其实早就分化出了两条截然不同的路子。

一条是稳如老狗的"工业级"方案,全浏览器通吃,我每天都在靠它混饭吃;

另一条则是刚出炉不久的"实验性"黑魔法,代码干净得让人直呼内行,可惜有的浏览器就是死活不买账。

这两种环形布局手段,鄙人皆有涉猎。可是呢,它们在我心里的定位,却有着天壤之别。

今天,我就大发慈悲,把这层窗户纸给你彻底捅破。

套路一:可以直接拉去摇钱的"工业级"CSS大法

谈及能够在生产环境里无脑上的环形布局,这套经典方案简直就是我的救命稻草。不论是需要制作花里胡哨的按钮、精致的图标,还是团队大屏里的环状头像,这套逻辑永远是我的第一顺位选择。

之所以这么偏爱它,原因无他:极度靠谱。并且,这种被广泛接纳的环形布局逻辑,其实傻白甜得可爱。

到底有多简单?我一般是这样给自己洗脑的:

  • 先把所有元素统统塞到正中间。

  • 接着,让每个子元素按比例稍微转个身。

  • 然后,一脚把它踹离中心点(利用位移)。

  • 最后,为了不让里面的文字可怜巴巴地倒立着,再把它给反向转回来。

这套把戏,说破天也就这么点东西。既然CSS本就精通旋转之道,我们不过是顺水推舟,将这种力量发挥到极致罢了。

基础的HTML长这样:

go 复制代码
<div class="circle">
  <div style="--i:0">A</div>
  <div style="--i:1">B</div>
  <div style="--i:2">C</div>
  <div style="--i:3">D</div>
  <div style="--i:4">E</div>
  <div style="--i:5">F</div>
</div>

凭借CSS变量 --i,每一个元素都被赋予了一个专属序号。正是这个不起眼的数字,残忍地决定了它在环形布局里的最终宿命。

真正在背后出大力的CSS代码如下:

go 复制代码
:root {
  --total: 6; /* 元素总数 */
  --radius: 150px; /* 圆的半径 */
}

/* 环形容器 */
.circle {
  position: relative;
  width: calc(var(--radius) * 2);
  height: calc(var(--radius) * 2);
  margin: 3rem auto;
}

/* 环形元素 */
.circle > div {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 60px;
  height: 60px;
  margin: -30px;
  border-radius: 50%;
  background: #6c5ce7;
  color: white;
  display: grid;
  place-items: center;

  --angle: calc(360deg / var(--total) * var(--i));

  transform:
    rotate(var(--angle))
    translateX(var(--radius))
    rotate(calc(-1 * var(--angle)));
}

清清爽爽,半句JavaScript的废话都没有。间距、角度、定位,统统被CSS一手包办。一旦你悟透了这个套路,天下所有的环形布局你都可以横着走。

实战演练

实不相瞒,这种环形布局,我早就用它在实际业务里大杀四方了。闭上眼睛想想:那些手机App里一按就弹出的"+"号菜单,或是悬浮在页面角落的快捷操作面板。

go 复制代码
<div class="circle menu">
  <button style="--i:0">编辑</button>
  <button style="--i:1">分享</button>
  <button style="--i:2">保存</button>
  <button style="--i:3">删除</button>
</div>
go 复制代码
.menu {
  --total: 4;
  --radius: 120px;
}

.menu button {
  border: none;
  background: #00b894;
  color: white;
  cursor: pointer;
}

用户点得爽,看着也高级,更关键的是它绝对不会崩。不仅仅是菜单,音乐播放器的周边控件、团队看板的环状头像,我全是用它扛下来的。每一次,这种环形布局都稳稳当当,从不掉链子。

适配屏幕?一行代码教做人

最让我爽到头皮发麻的,是它的响应式处理机制。为了让整个环形布局能大能小,游刃有余,我只需要轻描淡写地改动一行代码:

go 复制代码
.circle {
  --radius: 30vw;
}

搞定。没用什么劳什子的媒体查询,也不需要硬生生地去设什么断点。

至于这套方案是否被所有浏览器接纳?答案是肯定的。毕竟它利用的不过是 transformrotate()calc() 和 CSS变量这些老面孔。Chrome、Firefox、Safari、Edge,这些主流大佬统统绿灯放行。

套路二:让人又爱又恨的"实验性"CSS黑科技

接下来,我要给你看点刺激的了。提前声明:这段环形布局代码,我是坚决不敢直接扔到生产环境里去的。即便如此,这玩意儿绝对能让你看湿了眼眶。

在这个方案里,一种名为 CSS Motion Path(运动路径) 的新锐技术被引入了进来。我们不再去死磕什么恶心的角度计算,而是像霸道总裁一样直接命令浏览器:"看到这个圆了吗?把这些亲兄弟给我均匀地摆上去!"

Motion Path 的惊艳代码:

go 复制代码
.container {
  display: inline-grid;
}

.container > div {
  width: 150px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: purple;

  offset-path: circle(180px);
  offset-distance: calc(
    100% * sibling-index() / sibling-count()
  );

  transition: 1s;
}

发现盲点了没?没有CSS变量,没有伪类,不需要JS帮忙,更没有那些让人头秃的角度数学题。CSS自己就把活儿全干了,聪明得让人心疼。

为什么这套方法让人如此上头?

原因无他,这种环形布局的处理方式,完全颠覆了以往的认知。代码极其优雅,动画丝滑得要命。更重要的是,你的大脑被彻底释放了------你再也不用被那些复杂的旋转逻辑折磨得死去活来。显然,这才是CSS未来该有的狂傲姿态。

然而,现实总是喜欢在你最兴奋的时候泼冷水。

这套绝美的技术,偏偏重度依赖于几个还处于实验阶段的属性:offset-pathsibling-index()sibling-count()。测试结果相当残酷:Chrome和Edge?完美运行。

Safari?勉勉强强。

Firefox?直接半身不遂,得靠手动开启隐藏标识才能强行续命。正因如此,这种实验性的环形布局,我目前只能把它死死锁在实验室里。

如何抉择?成年人不做选择题

关于这两种环形布局的取舍,我的规矩向来简单粗暴:真正要交差、拿去赚钱的项目,老老实实用第一种 transform 经典方案;自己偷偷搞的实验和Demo,果断上 Motion Path 爽一把。借由这种方式,我既保住了饭碗,又没被时代抛弃。

总而言之,环形布局从来都不只是个看着炫酷的杂耍把戏。在导航、菜单和视觉界面里,它是实打实的交互杀器。

基于 transform 的环形布局早已瓜熟蒂落,我也是高频使用。反之,Motion Path 虽然干净利落,却还没拿到属于它的通关文牒。所以我把它们都塞进工具箱,一个用来赚钱,一个用来拓宽眼界。

如果你今天就要把项目发出去,听我的,用 transform,先跑通再说。等到周末做个人项目时,再去试试 Motion Path,盯着浏览器的支持率。等到哪天绿灯全亮了,你自然知道该怎么将旧代码彻底替换。

能用现在的技术把活干得漂亮,同时又死死盯着明天的风向。坦白说,这才是咱们做开发最爽的瞬间啊。感谢你的阅读。

全栈AI·探索:涵盖动效、React Hooks、Vue 技巧、LLM 应用、Python 脚本等专栏,案例驱动实战学习,点击二维码了解更多详情。

最后:

CSS终极指南

Vue 设计模式实战指南

20个前端开发者必备的响应式布局

深入React:从基础到最佳实践完整攻略

python 技巧精讲

React Hook 深入浅出

CSS技巧与案例详解

vue2与vue3技巧合集

相关推荐
Momo__3 小时前
VueUse createReusableTemplate —— 单文件组件内的模板复用神器
前端·vue.js
程序员小富3 小时前
我开源了一个开发者专属的智能 JSON 工具,得到了媳妇高度认可
前端·vue.js·后端
小小小小宇3 小时前
程序员如何给 LLM 装工具以及看懂推理过程
前端
写代码的皮筏艇3 小时前
React中的forwardRef
前端·react.js·面试
槑有老呆3 小时前
花三个月工资请了个 AI 程序员,结果它连青岛啤酒股价都查不了
前端
风骏时光牛马3 小时前
Verilog开发常见问题汇总解析
前端
子兮曰3 小时前
AI Coding Method Map:一张图看懂 AI 编程的完整链路
前端·人工智能·后端
weedsfly3 小时前
语法糖褪去之后——Babel 转译产物中的 JavaScript 本貌
前端·javascript
JustHappy3 小时前
「软件设计思想杂谈🤔」“切图仔”也能懂编译原理?框架源码也许没那么难。聊聊 Vue 的编译(上)
前端·javascript·vue.js