网页设计里有个叫border-image的CSS属性,能往边框里塞图片甚至渐变,做出各种花里胡哨的边缘效果。但好多人看到它的写法就头大,border-image: source slice/width/outset repeat这一串看着像天书。其实拆开看每一步都很简单,就像切蛋糕一样把图片分成九宫格,再贴到元素的四条边上。下面用两个真实项目里抠出来的操作流程,把这玩意儿整得明明白白。
概念拆解
border-image的核心是把一张图(或者CSS渐变)切成九块,分别塞到边框的四个角、四条边和中间。切片指的是从图片边缘往里量距离,画四条切割线,就像用刀切出九宫格。填充控制中间那块要不要显示,默认是忽略的。重复方式决定四条边上的图块是拉伸、平铺还是整块排开。有个容易踩坑的点:必须给border-image-width设置具体数值,否则边框区域没空间展示图片,忙活半天啥也看不见。浏览器渲染顺序是背景在下、边框图片在上、内容在最上面,所以边框图片能盖住背景但挡不住文字。
| 重复值 | 效果描述 |
|---|---|
| stretch | 拉长填满整条边 |
| repeat | 重复铺开可裁剪 |
| round | 重复时缩放保完整 |
| space | 重复加空格保完整 |
实战一 石头按钮
做一套边缘参差不齐的石头质感按钮,就像从石碑上凿下来那种。先准备一个SVG图形,形状是带破碎边缘的矩形。把SVG转成Data URI塞进CSS,省掉一次网络请求。
button {
border-image-source: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="60" height="60" viewBox="0 0 60 60"><path d="M10,0 L50,0 Q55,5 60,10 L60,50 Q55,55 50,60 L10,60 Q5,55 0,50 L0,10 Q5,5 10,0 Z" fill="#8B5A2B"/></svg>');
border-image-slice: 10 10 10 10 fill;
border-image-width: 20px;
border-image-repeat: stretch;
border: none;
padding: 12px 24px;
background: #5a3e1b;
color: #f0e6a0;
font-size: 18px;
}切片值10 10 10 10表示从图片上边、右边、下边、左边各往里量10像素切一刀。加上fill关键字后,中间那块也会被塞进按钮背景区域,这样石头纹理能铺满整个按钮。border-image-width: 20px定义了边框显示宽度,实际切片只有10像素,图片会被放大到20像素,边缘看起来更粗犷。重复方式选stretch,因为石头纹理是平滑的,拉伸不会露馅。万一用的是带花纹的图,拉伸会变形,就得换repeat或round。按钮里的文字和背景色是独立于边框图片的,可以随便调。
实战二 卷轴文章
做长文章区域的卷轴效果,上下带卷起来的纸筒,中间是正文区。传统做法要切三张图(上筒、中段、下筒)加两个伪元素,代码又臭又长。用border-image一张SVG全搞定。
先画一个完整的卷轴SVG,高600宽600,上下是半圆筒造型,中间是平整纸面。计算好切割位置:上筒高度150像素,左右边距各95像素,下筒高度150像素。
article {
border-image-source: url('data:image/svg+xml;utf8,<svg ...>...</svg>');
border-image-slice: 150 95 150 95 fill;
border-image-width: 150px 95px 150px 95px;
border-image-repeat: stretch round;
border: none;
padding: 40px 30px;
margin: 20px;
background: #fdf8e7;
}切片值150 95 150 95按上右下左顺时针:上切150像素,右切95,下切150,左切95。这样图片四个角区域正好对应卷轴的上下筒左右边角。border-image-width必须跟切片值匹配,否则图案错位。重复方式上写stretch round,意思是上下两条边用拉伸,左右两条边用圆整平铺。左右边缘通常比较窄,用round能保证卷轴侧边的图案完整显示不截断。这里有个细节:切片值和宽度值用的是带px单位的数字,因为SVG的viewBox定义了像素尺寸,不带单位浏览器也能猜对,但带上更稳当。中间用fill把纸面背景铺满,就不需要额外设背景图了。滚动起来边框图片纹丝不动,内容再多也不怕。
延伸玩法 渐变叠加层
做悬停效果时想给背景图叠一层彩色透明膜,通常得加额外元素或者用伪元素。其实border-image直接塞一个渐变就能搞定。
section:before {
content: "";
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
background-image: url('zoom-bg.svg');
background-size: cover;
transition: opacity 0.25s;
}
section:hover:before {
border-image: fill 0 linear-gradient(135deg, rgba(0,0,255,0.3), rgba(255,0,0,0.6));
}这里border-image的写法是简写:fill让中间区域填充渐变,0表示四条边的切片宽度为0(因为不需要给边框留位置),后面跟渐变源码。浏览器会把渐变当成图片源,按边框区域渲染,但因为宽度是0,渐变只出现在中间填充区,恰好盖住整个伪元素。悬停时瞬间叠一层蓝红渐变,比再套一个半透明层省代码。注意渐变要带透明度,否则会完全盖住底下的背景图。
