用object-fit: cover配合overflow: hidden和object-position可精确裁剪图片局部区域,而width/height仅强制缩放导致变形,并非真正裁剪。

直接用 overflow: hidden 套固定尺寸容器 + object-fit: cover 和 object-position,就能稳定控制图片只展示局部区域;别靠 width/height 硬缩放,那只是拉伸变形,不是裁剪。
为什么 img 的 width/height 不是裁剪
设 img { width: 200px; height: 150px; } 只会让整张图被强行挤压进框里,宽高比一变,人像就脸歪腿短。浏览器根本不会“切掉多余像素”,它只是渲染一个缩放后的完整图像——溢出部分依然存在,只是可能被父容器遮住(如果父容器没设 overflow: hidden,甚至还会撑开布局)。
- 真正裁剪 = 让容器成为“画框”,只露出图像中某一块
-
width/height是缩放指令,overflow: hidden才是裁剪开关 - 必须同时控制“图像如何填满容器”(
object-fit)和“从哪开始填”(object-position)
用 object-fit + object-position 精确控制显示哪一块
object-fit: cover 保证等比缩放并填满容器,object-position 决定缩放后图像的锚点落在容器哪个位置。比如想只显示原图顶部中间 200×150 区域,就这么写:
<div style="width: 200px; height: 150px; overflow: hidden;"> <img src="photo.jpg" style="width: 100%; height: 100%; object-fit: cover; object-position: center top;"> </div>
-
object-position: center top→ 图像垂直方向对齐顶部,水平居中 → 容器显示的是原图上半部分 -
object-position: 30% 20%→ 水平偏移 30%,垂直偏移 20%,支持百分比和像素值 - 注意:父容器必须有明确
width和height,否则height: 100%会失效(因为父级高度是auto) - 兼容性没问题:Chrome 32+、Firefox 36+、Safari 9.1+、Edge 16+ 都支持
需要像素级裁剪?Canvas 的 drawImage 是唯一可靠路径
当你要从一张 4000×3000 的图里,精确截取 x=827, y=142 开始的 600×400 像素区域,CSS 办不到,必须用 Canvas。关键在 ctx.drawImage() 的九参数重载:
立即学习“前端免费学习笔记(深入)”;
ctx.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
- 前四个参数(
sx,sy,sWidth,sHeight)必须基于原图真实像素坐标,不是 canvas 渲染后看到的位置 - 鼠标拖拽时拿到的
event.offsetX是渲染坐标,得用getBoundingClientRect()换算回原始像素 - 跨域图片必须加
crossOrigin="anonymous",否则 canvas 被污染,toBlob()静默失败 - 导出优先用
toBlob(),toDataURL()在大图时容易卡顿或内存溢出
容易被忽略的性能陷阱
前端裁剪只是“看起来裁了”,用户上传一张 5MB 的 4000×3000 图片,哪怕你只显示 200×150 区域,浏览器仍会下载并解码整张图。流量白耗,首屏也慢。真正省流量、保清晰度的做法是:把裁剪参数(x, y, width, height)传给服务端,让 CDN 或后端生成对应尺寸的新图再返回。前端只管交参数、收结果——这才是生产环境该走的路。


















