border-image-slice 不是图片切片工具,它仅将一张图九宫格切割后复用为边框,中间块默认丢弃或拉伸填充背景,无法导出独立图像;真分块需 canvas + drawimage 手动裁剪。

直接用 border-image 配合 border-image-slice 实现“分块显示”是常见误解——它不生成多张图,只是把一张图当边框素材切九宫格复用;真要分块导出或独立渲染,必须用 canvas + drawImage 手动裁剪。
为什么 border-image-slice 不是图片切片工具
border-image-slice 的作用对象是边框区域,它把一张图切成 3×3 网格后,只取 8 个外围块(角+边)来拼成元素的 border,中间那块默认丢弃。即使加了 fill,中间部分也只会拉伸铺满内容区背景,不会输出为独立图像。
常见错误现象:
- 写了
border-image-slice: 33% 33% 33% 33%却发现页面没变化 → 因为没配border-image-source和border-width - 加了
fill后中间显示了,但以为这是“第5张切图” → 实际它和边框共用同一张源图,无法单独提取 - 想用百分比切 1024×768 的图,写
border-image-slice: 25%→ 结果顶部/底部各切掉 192px,左右各切掉 256px,导致边区域严重变形甚至消失
用 canvas drawImage 实现真正可导出的切片
HTML5 没有原生“切图 API”,drawImage 是唯一可靠方式。核心是控制源图坐标(sx, sy, sw, sh)和目标画布尺寸(dw, dh)。
实操要点:
- 必须监听
img.onload,否则drawImage静默失败 - 读取真实尺寸用
img.naturalWidth/img.naturalHeight,别用被 CSS 缩放过的img.width - 每切一块,要新建一个
canvas元素:document.createElement('canvas'),不能复用同一个 canvas - 切完立刻调用
canvas.width = canvas.height = 0释放内存,尤其在循环中 - 导出多张时,
toBlob是异步的,避免闭包陷阱:用立即执行函数封装 canvas 和索引,或改用Promise.all聚合
移动端大图切片的兼容性红线
部分 Android WebView 和旧版 Safari 对单个 canvas 像素总数有限制(典型值为 16777216,即 4096×4096)。一张 8000×6000 的图直接按原尺寸创建 canvas,大概率渲染为空白。
应对策略:
- 切片前先检查:
if (img.naturalWidth * img.naturalHeight > 16777216) - 超限时按比例缩小源图:
const scale = Math.sqrt(16777216 / (w * h));,再用缩放后尺寸计算切片坐标 - 不要试图绕过限制——强行设置 canvas 宽高超过设备上限,结果不可控
真正难的不是写对 drawImage 参数,而是加载时机、导出顺序、设备限制这三点全都要兜住;漏一个,本地跑通,上线就只出第一张或全白。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











