border-image-slice详细介绍

2026-05-15
481117 分钟
...

border-image-slice 是 CSS border-image 系列属性里最关键、也最容易让人懵的一个属性。

它的作用可以简单理解为:

把一张图片切成九宫格,然后决定哪几块用来绘制元素的边框。

它通常和这些属性一起使用:

border-image-source: url("./button.png");
border-image-slice: 20;
border-image-width: 20px;
border-image-repeat: stretch;

或者简写成:

border-image: url("./button.png") 20 / 20px stretch;

其中 border-image-slice 决定“怎么切图”。

**一、****border-image**是什么?

普通的 border 只能画纯色边框:

border: 2px solid red;

但有时候我们想用图片作为边框,比如:

  • 游戏按钮边框
  • 像素风 UI
  • 复古窗口
  • 聊天气泡
  • 卡牌边框
  • 花纹装饰框
  • 九宫格按钮背景

这时候就可以用 border-image

例如一张按钮图片长这样:

┌───────────────┐
│               │
button
│               │
└───────────────┘

我们希望按钮变宽时,四个角不要变形,中间和边缘可以拉伸。

这就是 border-image 的经典用途。

**二、****border-image-slice**的核心思想:九宫格切图

假设有一张图片:

+-----------------------+
|                       |
|                       |
|                       |
|                       |
|                       |
+-----------------------+

设置:

border-image-slice: 20;

意思是:

从图片的上、右、下、左四个方向,各切进去 20 个单位。

于是图片会被切成九块:

+---------+-------------+---------+
| 左上角  |    上边      | 右上角  |
+---------+-------------+---------+
| 左边    |    中间      | 右边    |
+---------+-------------+---------+
| 左下角  |    下边      | 右下角  |
+---------+-------------+---------+

这九块分别有不同用途:

区域

作用

四个角

放到元素边框的四个角,通常不拉伸

上下边

横向拉伸或重复,铺满上/下边框

左右边

纵向拉伸或重复,铺满左/右边框

中间区域

默认丢弃,除非加 fill

三、基本语法

border-image-slice: <number> | <percentage> [fill]?;

它可以写 1 到 4 个值,规则和 marginpadding 类似。

1. 一个值

border-image-slice: 20;

等价于:

border-image-slice: 20 20 20 20;

意思是:

20
20
20
20

从图片四个方向都切 20。

2. 两个值

border-image-slice: 20 30;

等价于:

border-image-slice: 20 30 20 30;

意思是:

20
30

3. 三个值

border-image-slice: 20 30 40;

等价于:

border-image-slice: 20 30 40 30;

意思是:

20
30
40

4. 四个值

border-image-slice: 10 20 30 40;

意思是:

10
20
30
40

顺序是:

也就是 CSS 经典的顺时针顺序。

**四、****numberpercentage**的区别

border-image-slice 可以写数字,也可以写百分比。

1. 数字:按图片原始像素切

border-image-slice: 20;

这里的 20 不是 20px,而是图片坐标里的 20 个单位。

对于普通位图,比如 PNG、JPG,可以近似理解为:

从图片边缘切进去 20px。

注意,这里不能写 20px

错误写法:

border-image-slice: 20px;

正确写法:

border-image-slice: 20;

这是很多人第一次用时会踩的坑。

2. 百分比:按图片尺寸比例切

border-image-slice: 25%;

意思是:

图片高度的 25%
图片高度的 25%
图片宽度的 25%
图片宽度的 25%

举个例子,如果图片是 100 × 50

border-image-slice: 25%;

那么大致等价于:

12.5
12.5
25
25

因为:

上下基于图片高度 50
左右基于图片宽度 100

所以百分比不是所有方向都按同一个尺寸算。

**五、****fill**是什么?

默认情况下,九宫格中间那块会被丢弃。

例如:

border-image-slice: 20;

只会使用:

四个角
四条边

中间区域不会绘制。

如果你希望中间区域也显示出来,需要加 fill

border-image-slice: 20 fill;

或者:

border-image-slice: 20 20 20 20 fill;

这样中间区域也会被拿来填充元素内容区域。

不加**fill**

.btn {
  border: 20px solid transparent;
  border-image-source: url("./button.png");
  border-image-slice: 20;
}

效果类似:

只画边框中间透明或由 background 决定

**fill**

.btn {
  border: 20px solid transparent;
  border-image-source: url("./button.png");
  border-image-slice: 20 fill;
}

效果类似:

边框 + 中间背景都使用图片

对于游戏按钮、像素风按钮、装饰卡片来说,fill 经常很有用。

**六、****border-image-sliceborder-image-width**的区别

这两个很容易混。

border-image-slice

决定:原图怎么切。

例如:

border-image-slice: 20;

表示在原图上切出 20 的区域。

**border-image-width**决定:切出来的边框在元素上显示多宽。

例如:

border-image-width: 10px;

表示绘制到元素上时,边框区域宽度是 10px。

对比理解

假设图片是 100 × 50

border-image-slice: 20;
border-image-width: 10px;

意思是:

从原图中切 20px 的边缘区域
但是绘制到页面上时边框宽度显示为 10px

所以:

  • slice 管原图
  • width 管页面显示
  • 两者不是一回事

七、必须设置**border**

很多人写了 border-image-slice 但没效果,原因是没有设置基础 border

通常需要这样:

.btn {
  border: 20px solid transparent;
  border-image-source: url("./button.png");
  border-image-slice: 20 fill;
  border-image-width: 20px;
}

或者:

.btn {
  border: 20px solid transparent;
  border-image: url("./button.png") 20 fill / 20px stretch;
}

为什么需要 border

因为 border-image 是画在边框区域上的。如果元素没有边框区域,浏览器就没有地方画。

一般推荐:

border: 20px solid transparent;

这里颜色写 transparent,因为真正显示的是图片,不是普通边框颜色。

八、完整示例:图片按钮

假设你有一张按钮图片:

button-green.png
尺寸100 × 50

你希望按钮宽度可以变成 300px,高度是 50px,四个角保持不变,中间拉伸。

可以这样写:

.gmc-btn-green {
  width: 300px;
  height: 50px;

  border: 16px solid transparent;

  border-image-source: url("/images/button-green.png");
  border-image-slice: 16 fill;
  border-image-width: 16px;
  border-image-repeat: stretch;

  background: transparent;
}

也可以简写:

.gmc-btn-green {
  width: 300px;
  height: 50px;

  border: 16px solid transparent;
  border-image: url("/images/button-green.png") 16 fill / 16px stretch;

  background: transparent;
}

**九、****border-image-repeat**会影响最终效果

border-image-slice 只是决定“怎么切”,而切出来的边怎么铺,还要看:

border-image-repeat

它常见值有:

stretch
repeat
round
space

1.****stretch

border-image-repeat: stretch;

表示把边缘区域直接拉伸铺满。

这是最常用的。

适合:

  • 渐变按钮
  • 普通 UI 边框
  • 非像素风图片

缺点是如果边缘有纹理,可能会被拉变形。

2.****repeat

border-image-repeat: repeat;

表示重复铺。

适合:

  • 像素风边框
  • 重复纹理边框

缺点是可能在末尾被裁剪,导致边缘对不齐。

3.****round

border-image-repeat: round;

也是重复铺,但浏览器会稍微缩放图片块,让它刚好铺满。

适合:

  • 希望重复但不要裁剪
  • 花纹边框
  • 像素风边框

4.****space

border-image-repeat: space;

表示重复铺,但多余空间用间距分散。

这个用得比较少。

十、为什么会出现黑线、白线、缝隙?

这是 border-image-slice 实战里最常见的问题。

尤其是游戏按钮、透明 PNG、像素风 UI,特别容易出现边缘黑线。

常见原因有几个。

1. 原图切割位置刚好切到阴影或描边

比如图片边缘本身有黑色描边。

你设置:

border-image-slice: 25;

但这个位置刚好落在黑色描边中间。

浏览器切图再拉伸时,就可能把这条黑色像素拉成一整条线。

解决方法:

border-image-slice: 24;

或者:

border-image-slice: 26;

微调 1 到 2 个单位。

很多时候就是差这 1px。

2. 图片有半透明抗锯齿像素

PNG 边缘经常有半透明像素,比如:

透明
半透明黑
实体绿色

浏览器切图和缩放时,半透明像素被采样,就会出现黑边、灰边或白边。

解决方式:

  • 重新处理图片边缘
  • 避免切线经过半透明区域
  • 尽量切在纯色区域
  • 使用更干净的九宫格素材

3. 元素尺寸导致小数像素

比如图片原始宽度是 100px,按钮显示宽度是 301px

浏览器拉伸边框时,可能产生小数像素。

比如:

某一块需要显示成 137.5px

浏览器最终要渲染到物理像素上,就可能发生采样误差。

结果就是有时有线,有时没线。

这也是你调整屏幕宽度时,黑线时隐时现的原因之一。

解决方式:

width: 300px;
height: 50px;

尽量让尺寸是整数,避免复杂缩放。

如果是响应式宽度,可以考虑:

min-width: 120px;
height: 50px;

同时减少 border-image 对复杂缩放的依赖。

**4.****sliceborder-width**不匹配

例如:

border-image-slice: 25;
border-image-width: 13px;
border: 13px solid transparent;

原图切 25,显示却压成 13,浏览器会缩放边缘区域。

缩放过程中就可能采样到不该出现的像素。

一般建议先保持它们接近:

border: 16px solid transparent;
border-image-slice: 16 fill;
border-image-width: 16px;

如果图片本身尺寸允许,先让 sliceborder-image-width 对齐,问题会少很多。

十一、

border-image-slice

的调试方法

如果图片效果不对,可以按这个顺序排查。

第一步:确认图片尺寸

比如图片是:

100 × 50

那你要知道:

横向中心50
纵向中心25

如果你想四等分切,大概就是:

border-image-slice: 25 50 25 50;

但这个值非常极端,因为左右各切 50,就没有中间横向区域了。

对于 100 × 50 的图片,一般更现实的是:

border-image-slice: 16 24 16 24 fill;

或:

border-image-slice: 20 30 20 30 fill;

具体取决于图片的圆角、描边、渐变区域在哪里。


第二步:先画出明显边框

.btn {
  border: 20px solid red;
}

先确认元素真的有边框区域。

然后再加:

border-image-source: url("./button.png");
border-image-slice: 20 fill;

第三步:先用

stretch

border-image-repeat: stretch;

先不要用 repeatround

stretch 更容易判断切图是否正确。

第四步:微调

slice

例如从:

border-image-slice: 20 fill;

改成:

border-image-slice: 19 fill;

或者:

border-image-slice: 21 fill;

观察黑线是否消失。

这一步非常重要。很多 border-image 问题不是代码逻辑错,而是切线刚好切到了不该切的位置。

十二、简写语法怎么读?

完整写法:

border-image-source: url("./button.png");
border-image-slice: 20 fill;
border-image-width: 20px;
border-image-outset: 0;
border-image-repeat: stretch;

可以简写成:

border-image: url("./button.png") 20 fill / 20px / 0 stretch;

结构是:

border-image:
  source
  slice
  /
  width
  /
  outset
  repeat;

例如:

border-image: url("./border.png") 30 / 30px / 0 round;

意思是:

图片border.png
切图30
边框显示宽度:30px
向外扩展0
铺法round

不过实际开发中,我更建议新手不要一开始就写简写。

更清楚的写法是:

.box {
  border: 30px solid transparent;

  border-image-source: url("./border.png");
  border-image-slice: 30;
  border-image-width: 30px;
  border-image-repeat: round;
}

等你确认没问题,再压成简写。

**十三、****border-image-slicebackground-size**的区别

有些人会问:

我直接用 background-image 不行吗?

可以,但它们解决的问题不同。

background-image

适合:

整张图片作为背景

例如:

background-image: url("./button.png");
background-size: 100% 100%;

这样会把整张图片直接拉伸。

缺点是:

四个角也会被拉伸变形

如果按钮从 100px 拉到 300px,圆角、描边、阴影都会变形。

border-image

适合:

四角保持不变边缘和中间拉伸

也就是九宫格缩放。

对于 UI 按钮、卡片、弹窗边框,border-image 更适合。

十四、什么时候适合用**border-image-slice****?**

适合这些场景:

游戏 UI 按钮
像素风边框
聊天气泡
装饰卡片
弹窗面板
复古风窗口
RPG 对话框
带复杂纹理的边框

尤其是图片边框不能简单用 border-radiusbox-shadowlinear-gradient 实现时,就可以考虑它。

十五、什么时候不建议用?

不太建议用在这些场景:

普通圆角按钮
普通渐变按钮
简单边框
纯色描边
响应式特别复杂的容器
需要极高精度对齐的 UI

如果 CSS 本身能实现,就没必要上 border-image

例如普通按钮:

.button {
  border-radius: 12px;
  background: linear-gradient(#6ee76e, #28a728);
  border: 2px solid #137c13;
}

这种比 border-image 更稳定、更清晰。

十六、常见坑总结

1. 忘记写基础**border**

错误:

.btn {
  border-image-source: url("./button.png");
  border-image-slice: 20;
}

正确:

.btn {
  border: 20px solid transparent;
  border-image-source: url("./button.png");
  border-image-slice: 20;
}

2. 给**slice写了px**

错误:

border-image-slice: 20px;

正确:

border-image-slice: 20;

3. 忘记加

fill

如果你希望中间也显示图片,需要:

border-image-slice: 20 fill;

不加 fill,中间区域默认不会被绘制。

4. 切线切到了脏像素

例如切到了阴影、描边、半透明边缘。

解决:

border-image-slice: 19 fill;

或者:

border-image-slice: 21 fill;

上下微调。

5. 图片本身不适合九宫格

不是所有图片都适合 border-image

适合九宫格的图片最好满足:

四个角独立
四条边可以拉伸或重复
中间区域尽量干净
边缘没有奇怪半透明脏像素

如果图片是复杂插画,强行九宫格切割很容易变形。

十七、实战建议

如果你是在做游戏按钮,推荐流程是:

  1. 先确认图片原始尺寸。
  2. 找出四个角不能变形的区域。
  3. slice 切线尽量放在纯色区域。
  4. borderborder-image-widthslice 先保持一致。
  5. 加上 fill,让中间也绘制。
  6. stretch 测试。
  7. 如果有黑线,微调 slice 1px。
  8. 如果响应式变化时黑线时有时无,考虑换成伪元素或 canvas 方案。

例如:

.gmc-btn-green {
  height: 50px;
  min-width: 120px;

  border: 16px solid transparent;

  border-image-source: url("/images/btn-green.png");
  border-image-slice: 16 fill;
  border-image-width: 16px;
  border-image-repeat: stretch;

  background: transparent;
}

如果左右出现黑线,可以试:

border-image-slice: 16 15 16 15 fill;

或者:

border-image-slice: 15 16 15 16 fill;

根据黑线方向微调。

十八、一句话总结

border-image-slice 的本质是:

告诉浏览器:这张边框图片应该从哪里切成九宫格。

它不负责图片怎么铺,也不负责边框显示多宽。

对应关系是:

border-image-slice原图怎么切
border-image-width页面上显示多宽
border-image-repeat切出来的边怎么铺
fill中间区域要不要显示

掌握这几个关系之后,border-image-slice 就没那么玄学了。

但它确实比较吃图片素材质量。尤其是游戏 UI 按钮,如果原图边缘有抗锯齿、阴影、半透明像素,或者切割位置不干净,就很容易出现黑线、白线、缝隙。这不是你代码写错,而是九宫格切图和浏览器采样一起造成的经典问题。

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
css2026-06-17
外阴影和内阴影介绍
在前端页面设计中,阴影是非常常见的视觉效果。它可以让元素看起来更有层次感,也可以用来表达悬浮、按压、凹陷、卡片、按钮等状态。 CSS 中最常用的阴影属性是 。它既可以实现外阴影,也可以实现内阴影。 一、什么是外阴影 外阴影指的是元素外部的阴影效果。 它会出现在元素边框之外,让元素看起来像是从页面中“浮起来”了一样。常见的卡片、弹窗、按钮悬浮效果,基本都会用到外阴影。 例如: 这个阴影表示:元素下方有一层柔和的黑色阴影,让卡片看起来更有立...
学习
css2026-03-05
如何在最小副作用下创建 BFC
在 CSS 布局的江湖中, BFC (Block Formatting Context,块级格式化上下文) 是一个老生常谈却又至关重要的概念。无论是解决 高度塌陷 、 清除浮动 ,还是防止 垂直外边距重叠 ,BFC 都是我们的得力助手。 但是,创建 BFC 的方法有很多: 、 、 、 …… 哪种方法对现有布局的“破坏”最小? ❌ 过去的老方法 在过去,为了触发 BFC,我们不得不使用一些带有副作用的“黑客”技巧: : 元素会脱离文档流,...
学习
css2026-03-03
CSS过渡性能解析:transition: all
CSS过渡性能深度解析:为什么 可能是你页面的隐形杀手 一、引言:一个被忽视的性能陷阱 你是否曾在项目中这样写: 看似简洁优雅,却可能在低端设备上引发卡顿、掉帧。 真相 : 是前端性能优化中高频出现的“隐形陷阱”。本文将彻底揭开它的面纱。 二、核心概念: 到底在控制什么? 指定 哪些CSS属性变化时触发动画过渡 。它是过渡效果的“守门员”: | 值 | 含义 | 生成的CSS | | | | | | | 所有 可过渡属性变化时均触发动画...
学习
css2026-01-26
在CSS中,四种高度视口单位的区别
在CSS中,视口单位是构建响应式网页设计的重要工具,特别是针对移动端开发。除了传统的 ,CSS新引入了 、 和 等更精确的单位,解决传统单位在移动端的局限性。 四种高度视口单位的区别 | 单位 | 全称 | 含义 | 特点 | | | | | | | vh | Viewport Height | 传统视口高度单位,1vh = 视口高度的1% | 在移动端有问题:不考虑浏览器UI变化,经常导致内容被遮挡或出现意外滚动 | | svh |...
学习
css2025-11-04
keyframes 关键帧机制
一、什么是 @keyframes? 用于定义动画在不同时间点(关键帧)的样式变化;配合 属性应用到元素上。 定义动画 :使用 声明关键帧序列; 应用动画 :在选择器中通过 / 相关长属性控制表现。 二、基本语法 等价写法( / ): 三、与 属性配合使用 /相关长属性 | 属性名 | 含义 | 示例值 | | : | : | : | | | 动画名称 | | | | 持续时长 | 、 | | | 速度曲线 | / / / | | | 延...
学习
css2025-10-02
backdrop-filter属性介绍
CSS 属性详解: 一、什么是 是 CSS 中的一种滤镜属性,用于对 元素背后的区域 应用图形效果(如模糊、亮度调整、对比度等)。 与 的区别: :作用于元素自身内容。 :作用于元素的背景(背后内容),通常需要元素本身带有透明度才能看到效果。 例如: 二、基本语法 常见的 : :模糊效果 :亮度调整 :对比度调整 :灰度 :色相旋转 :反色 :透明度 :饱和度 :怀旧效果 可同时使用多个: 三、使用示例 1. 毛玻璃效果(Glassmo...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录