必须同时满足容器宽高相等、border-radius: 50%、overflow: hidden(或配合object-fit: cover的img),否则图片仍显示为方形或椭圆;border-radius仅定义可视区域形状,不强制裁剪内容。

直接用 border-radius: 50% + overflow: hidden 就能做出可点击的圆形头像区域,但必须确保容器是正方形、图片不拉伸、事件绑定在正确层级——否则点中的是“方图”而不是“圆心”,或者点击热区错位、四角露出来。
为什么只加 border-radius: 50% 图片还是方的?
因为 border-radius 只画边框形状,不裁内容。浏览器默认不会主动裁掉超出圆角的部分,除非你明确告诉它“别显示外面的”。
- 漏写
overflow: hidden→ 图片四角照常溢出,圆角纯属“视觉假象” - 只给
<img>加border-radius不加overflow→ 部分旧版 Safari/Android WebView 中完全失效 - 父容器宽高不等(比如
width: 100%; height: auto)→50%按宽高分别算,结果是椭圆,不是圆 - 图片原始尺寸非正方形,又没配
object-fit: cover→ 要么拉伸变形,要么上下/左右留白,圆心偏移
<map></map> + area shape="circle" 真实热区怎么配?
这是唯一能定义“像素级圆形点击判定”的原生方案,和视觉样式无关,适合需要精确坐标响应(比如头像编辑器、地图标记)的场景。
-
<img>必须带usemap="#xxx",且值要和<map name="xxx"></map>完全一致(注意:Chrome 只认name,不认id) -
<area shape="circle" coords="cx,cy,radius">坐标系以图片左上角为原点,cx/cy是圆心,radius是半径(单位像素) - 如果图片缩放(比如
width: 100%),coords值必须同步按比例换算,否则热区漂移——建议固定图片尺寸或用 JS 动态重算 - 不支持 CSS 动画、伪元素、
transform,热区永远贴合原始图片坐标,放大/缩小时容易“点不中”
点击区域和视觉圆形不一致怎么办?
常见于用 <div> 包 <code><img> 后加状态点、边框、阴影,或用了 transform: scale(),导致事件坐标和渲染位置错开。
- 点击事件绑在
<img>上,但圆角裁剪发生在父<div> → 实际可点区域仍是矩形,只是被遮住了 <li>解决办法:把点击事件绑定到父容器(<code><div class="avatar">),并确保它设了 <code>cursor: pointer和tabindex="0"(键盘可访问) - 如果用了
transform缩放/平移,offsetX/offsetY会失真,得用getBoundingClientRect()+event.clientX手动换算真实坐标 - 状态点(如在线小绿点)若用绝对定位,必须给父容器加
overflow: hidden,否则点在圆外也能触发——因为状态点本身没被裁,只是“看起来”在圆内
真正麻烦的不是画圆,而是让“可点范围”“视觉范围”“上传内容”三者对齐。很多人卡在上传后还是方图,就因为以为 border-radius 能改数据——它不能。要导出圆形图片,必须走 <canvas></canvas> 或服务端裁剪。











