图像边框 ( border-image )
元素的边框除了基本的样式和颜色,也可以使用“图像”作为边框,这篇教学会介绍 border-image、border-image-slice、border-image-repeat 等边框图像的样式属性,运用丰富的图像素材,让边框更加特别,最后还会运用图像边框,实作“波浪形状”的边框效果。
请先阅读:边框 border
快速导览:
教学影片
搭配教学影片一起阅读,效果会更好!欢迎大家订阅 STEAM 教育学习网的 Youtube 频道。
border-image-source 边框的图像来源
如果元素具有较宽的边框,可以使用 border-image-source 设定边框的背景图片,用法和 background-image 完全相同,支援 jpg、gif、webp、png、svg 等常见的图像格式,也支援使用 CSS 渐层色函数产生的渐层色,写法如下:
图像边框不支援
border-collapse: collapse;的表格元素。
div {
border-image-source: url("圖片網址");
}
在单纯使用 border-image-source 且没有搭配其他样式的状况下,执行结果会将图片填满“四个角落”,在四个方向边框宽度相同时,图像缩放为“正方形”,如果四个方向边框宽度不同,则会缩放呈现不同的“长方形”,下方范例会呈现使用外部 jpg、svg 和内嵌 svg 的做法,并用浅灰色背景凸显元素范围。
<!-- HTML 程式碼 -->
<div class="a">使用外部 jpg</div>
<div class="b">使用外部 svg</div>
<div class="c">使用內嵌 svg</div>
<div class="d">使用漸層色</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 5px;
box-sizing:border-box;
border: 50px solid #000;
background: #eee;
float: left;
}
.a {
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-1.jpg");
}
.b {
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-svg-1.svg");
}
.c {
border-image-source: url('data:image/svg+xml,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 237 237" style="enable-background:new 0 0 237 237;" xml:space="preserve"><g><rect style="fill:%23FF5F5F;" width="79" height="79"/></g><g><rect x="79" style="fill:%23FFBD52;" width="79" height="79"/></g><g><rect x="158" style="fill:%2389FF00;" width="79" height="79"/></g><g><rect y="79" style="fill:%231B9E00;" width="79" height="79"/></g><g><rect x="79" y="79" style="fill:%237BCAFF;" width="79" height="79"/></g><g><rect x="158" y="79" style="fill:%230019FF;" width="79" height="79"/></g><g><rect y="158" style="fill:%23B440FF;" width="79" height="79"/></g><g><rect x="79" y="158" style="fill:%23CCCCCC;" width="79" height="79"/></g><g><rect x="158" y="158" style="fill:%233D3D3D;" width="79" height="79"/></g></svg>');
}
.d {
border-image-source: conic-gradient(
#500 0, #500 45deg,
#f00 45deg, #f00 90deg,
#f50 90deg, #f50 135deg,
#ff0 135deg,#ff0 180deg,
#0c0 180deg, #0c0 225deg,
#09d 225deg, #09d 270deg,
#00b 270deg, #00b 315deg,
#909 315deg, #909 360deg
);
}
</style>
使用图像边框后,元素边框会有下列几种有特性:
- 忽略边框颜色:
border-color相关样式失效。- 不会被边框圆角裁切:边框的图像覆盖在元素上,反而会覆盖在边框圆角上方。
下方的范例虽然有套用了边框圆角效果,但因为使用了图像边框,如果是“全部填满”的图像边框,圆角效果看起来就像是没有作用,如果是“背景透明”的图像边框,就可以观察到边框圆角效果。
<!-- HTML 程式碼 -->
<div class="a">hello apple</div>
<div class="b">hello banana</div>
<div class="c">hello oxxo</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 10px;
box-sizing:border-box;
border: 50px solid #000;
background: orange;
float: left;
border-radius: 80px;
}
.a {border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-1.jpg");}
.b {border-image-source: url("https://steam.oxxostudio.tw/download/css/border-svg-2.svg");}
.c {
border-radius: 50px; /* 把邊框圓角半徑變小 */
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-1.jpg");
}
</style>
border-image-slice 边框的图像切片
border-image-slice 样式属性会将作为边框图像的图片,透过“切片”的方式分割成“九宫格”,九宫格的每个格子按照下图,分别对应元素容器和边框组成的九宫格:
border-image-slice 撰写语法和 border 相似,使用单一数值 ( 无单位 ) 或使用空白分隔多个数值,最后也可以加入 fill 关键字。
/* 使用 1~4 個數值 */
div {
border-image-slice: (上下左右);
border-image-slice: (上下) (左右);
border-image-slice: 上 (左右) 下;
border-image-slice: 上 右 下 左;
}
/* 使用 1~4 個數值,最後加上 fill 關鍵字 */
div {
border-image-slice: (上下左右) fill;
border-image-slice: (上下) (左右) fill;
border-image-slice: 上 (左右) 下 fill;
border-image-slice: 上 右 下 左 fill;
}
属性数值表示“切片的长度”,意思为图片指定位置切线“由外往内”的移动距离,支援数字和百分比两种:
| 属性值 | 说明 |
|---|---|
| 数字 | 必须“无单位”数字,但实际单位为 px。 |
| % ( 默认值,100% ) | 乘以图片原始宽度的百分比。 |
| fill ( 关键字 ) | 默认不使用,表示不会用边框填满元素内容,使用后会九宫格的中间区域填满元素内容。 |
下方的例子使用一张 300x300 九宫格正方形的九色图片,设定不同切片数字后会对应到不同的套用结果 ( 图片的左侧是图片切片的对照 )。
<!-- HTML 程式碼 -->
<div class="a">apple</div>
<div class="b">banana</div>
<div class="c">coconut</div>
<div class="d">oxxo</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 10px;
padding: 10px;
box-sizing:border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg");
}
.a {border-image-slice: 100;}
.b {border-image-slice: 100 50;}
.c {border-image-slice: 100 50 20;}
.d {border-image-slice: 100 50 20 10;}
</style>
从上图可以看出,如果将“非正方形”的切片套用到正方形的区域,就会发生拉伸变形的状况,同理如果将“正方形”切片套用到长方形的区域,也会发生拉伸变形的状况,下方范例将正方形九宫格的切片图案,套用到长方形容器的图像边框,除了四个正方形的角落,其他四个方向的边缘都会出现拉伸或压缩的状况 ( 如果是位图,将小图片到用到大容器时,还会发生分辨率不足的状况 )
<!-- HTML 程式碼 -->
<div class="a"></div>
<div class="b"></div>
<!-- CSS 程式碼 -->
<style>
div {
margin: 10px;
padding: 10px;
box-sizing:border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg");
border-image-slice: 100;
}
.a {
width: 300px;
height: 150px;
}
.b {
width: 100px;
height: 300px;
}
</style>
通常设定切片时,必须注意“切片总尺寸”必须小于“图片尺寸”( 宽高分开计算 ),不然就会发生“无法切出图片”的空白状况,对应的边框也就不会有图像,相关规则如下:
| 状况 | 边框四个角 | 边框四个边 |
|---|---|---|
| 图片尺寸 > 切片总尺寸 | 填满切片 | 填满切片 |
| 图片尺寸 <= 切片总尺寸 | 填满切片 | 空白 |
下方范例的前两个 div 的切片总尺寸都小于图片尺寸,所以可以正常计算出图像边框的图片,但后两个 div 因为切片总尺寸太大,部分边框无法计算出要套用的图片尺寸,就会保留空白 ( 范例使用一个 span 作为实际内容区域 )。
<!-- HTML 程式碼 -->
<div class="a"><span>apple</span></div>
<div class="b"><span>banana</span></div>
<div class="c"><span>coconut</span></div>
<div class="d"><span>oxxo</span></div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 20px;
box-sizing:border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg");
}
span {
display: block;
width: 100%;
height: 100%;
padding: 10px;
background: yellow;
box-sizing:border-box;
}
.a {border-image-slice: 140;} /* 140+140 < 300 */
.b {border-image-slice: 100 249 100 50;} /* 249+50 < 300 */
.c {border-image-slice: 500;} /* 500+500 > 300 */
.d {border-image-slice: 100 250;} /* 250+250 > 300 */
</style>
如果使用“百分比”为单位,表示“原始图片的尺寸的百分比”,使用方法和使用数字差不多,但因为是以百分比为单位,就不需要去知道原始图片尺寸,只要注意不要超过 50% 就都可以正常显示 ( 裁切总尺寸如果等于图片尺寸,仍然无法正常切片 )。
<!-- HTML 程式碼 -->
<div class="a"><span>apple</span></div>
<div class="b"><span>banana</span></div>
<div class="c"><span>coconut</span></div>
<div class="d"><span>oxxo</span></div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 20px;
box-sizing:border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg");
}
span {
display: block;
width: 100%;
height: 100%;
padding: 10px;
background: yellow;
box-sizing:border-box;
}
.a {border-image-slice: 33.3%;} /* 33.3% + 33.3% < 100% */
.b {border-image-slice: 25% 10%;} /* 25% + 25% < 100% */
.c {border-image-slice: 50%;} /* 50% + 50% = 100% */
.d {border-image-slice: 100%;} /* 100% + 100% > 100% */
</style>
border-image-slice 默认会将内容的部分“留空”,如果加上 fill 关键字,则会将切片后九宫格正中间的切片,填满内容区域,不过如果元素有内容,内容会覆盖在边框之上 ( 边框覆盖在背景色之上 ),此外,如果切片总尺寸大于图片尺寸,中间区域就会像四个边缘一样呈现空白。
<!-- HTML 程式碼 -->
<div class="a"><span></span></div>
<div class="b"><span></span></div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 20px;
box-sizing:border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg");
}
span {
display: block;
width: 100%;
height: 100%;
padding: 10px;
background: #ff0a; /* 使用半透明黃色,凸顯內容 */
box-sizing:border-box;
}
.a {border-image-slice: 33.33% fill;}
.b {border-image-slice: 25% 10% fill;}
</style>
border-image-repeat 边框的图像重复
border-image-repeat 可以设定图像边框四周图像的“重复模式”,有下列几个属性值:
| 属性值 | 说明 |
|---|---|
| stretch | 默认值,每个区域套用一个切片,“不等比例”缩放切片填满区域。 |
| repeat | “等比例”缩放并重复切片直到填满区域 ( 切片可能会被截断 )。 |
| round | “不等比例”缩放并重复切片直到填满区域 ( 切片不会被截断 )。 |
| space | “等比例”缩放并重复切片,搭配“空白”填满区域 ( 切片不会被截断 )。 |
下面使用四个 div 和同一张边框图像,呈现不同重复模式的效果。
<!-- HTML 程式碼 -->
<div class="a">border-image-repeat: stretch;</div>
<div class="b">border-image-repeat: repeat;</div>
<div class="c">border-image-repeat: round;</div>
<div class="d">border-image-repeat: space;</div>
<!-- CSS 程式碼 -->
<style>
div {
width: 370px;
height: 180px;
margin: 5px;
padding: 10px;
box-sizing:border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg");
border-image-slice: 100;
}
.a {border-image-repeat: stretch;}
.b {border-image-repeat: repeat;}
.c {border-image-repeat: round;}
.d {border-image-repeat: space;}
</style>
border-image-outset 边框的图像扩展范围
border-image-outset 可以设定边框图像向外的“扩展范围”,设定后会将图像边框往外推,不过这个样式不会影响容器和其他容器的关系,也不会影响容器的行高,纯粹只影响显示的“样式”。
border-image-outset 的属性值使用“具有长度单位”或“不具有单位”的数字,并且和 border-width 一样,也有支援 1~4 个数值的写法。使用的单位如下:
| 属性值单位 | 说明 |
|---|---|
| 没有单位 | border-width 的几倍。 |
| px | 像素。 |
| em | 元素本身字号的几倍。 |
| rem | 根元素字号的几倍。 |
| pt、cm、mm、in | 印刷单位。 |
下方范例会呈现不同 border-image-outset 产生的扩展效果,可以看到虽然 div 的前后有 span 元素,但扩展范围不会影响其他元素。
<!-- HTML 程式碼 -->
<div class="a"><span></span></div>
<span>hello world, I am oxxo!!</span>
<br>
<div class="b"><span></span></div>
<span>hello world, I am oxxo!!</span>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 20px 40px;
box-sizing:border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg");
border-image-slice: 100;
}
div span {
display: block;
width: 100%;
height: 100%;
background: yellow;
}
.a {
border-width: 20px 40px 60px 80px;
border-image-outset: 0.5; /* 10px 20px 30px 40px */
}
.b {
border-image-outset: 30px;
}
</style>
border-image-width 边框的图像宽度
border-image-width 可以设定边框的“图像宽度”,通常使用图像边框时,默认都会将图像“填满”边框,但运用这个样式就能设定图像的尺寸,进而产生“裁切”或“留白”的效果,如果图像宽度小于边框宽度就会留白,如果大于边框宽度就会裁切,最大的图像宽度为元素宽高的一半。
border-image-width 的属性值使用“具有长度单位”或“不具有单位”的数字,和 border-width 一样,也支援 1~4 个数值的写法。使用的单位如下:
| 属性值单位 | 说明 |
|---|---|
| 没有单位 | border-width 的几倍。 |
| px | 像素。 |
| % | 元素对应方向的宽度或高度。 |
| em | 元素本身字号的几倍。 |
| rem | 根元素字号的几倍。 |
| pt、cm、mm、in | 印刷单位。 |
下方范例使用不同的 border-image-width 数值呈现不同效果。
<!-- HTML 程式碼 -->
<div class="a"><span></span></div>
<div class="b"><span></span></div>
<div class="c"><span></span></div>
<div class="d"><span></span></div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 30px;
box-sizing:border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg");
border-image-slice: 100;
}
div span {
display: block;
width: 100%;
height: 100%;
background: yellow;
}
.a {border-image-width: 10%;} /* 200px x 10 = 20px */
.b {border-image-width: 20px;}
.c {border-image-width: 20px 50px; }
.d {border-image-width: 80px;}
</style>
border-image 图像边框 ( 缩写格式 )
如果不要一个一个样式的设定图像边框,也可以使用 border-image 撰写缩写格式,缩写格式的样式会包含上述各个样式,撰写规则如下:
| 属性值 | 是否必要 | 分隔符号 | 按照顺序 |
|---|---|---|---|
border-image-source |
必要 | 空白 | 不用按照顺序 |
order-image-repeat |
非必要,默认 stretch | 空白 | 不用按照顺序 |
border-image-slice |
非必要,默认 100% | / | 按照顺序,顺序 1 |
border-image-width |
非必要,默认 1 | / | 按照顺序,顺序 2 |
border-image-outset |
非必要,默认 0 | / | 按照顺序,顺序 3 |
border-image 撰写语法如下,需要按照顺序的属性值必须按照写法顺序撰写。
div {
border-image: border-image-source border-image-slice / border-image-width / border-image-outset border-image-repeat;
}
下方的范例会使用四个 div,透过不同的 border-image 撰写方式,产生四种截然不同的效果 ( 同一张图片 )。
<!-- HTML 程式碼 -->
<div class="a"><span>apple</span></div>
<div class="b"><span>banana</span></div>
<div class="c"><span>coconut</span></div>
<div class="d"><span>oxxo</span></div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
margin: 30px;
box-sizing: border-box;
border: 50px solid #000;
float: left;
}
div span {
display: block;
width: 100%;
height: 100%;
background: yellow;
}
.a {border-image: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg") 100;}
.b {border-image: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg") 120 repeat;}
.c {border-image: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg") 100 50 / 50px / 5px;}
.d {border-image: url("https://steam.oxxostudio.tw/download/css/border-img-2.jpg") 50 30 fill / 10px / 10px 5px space;}
</style>
波浪造型边框效果
下方范例会利用波浪造型的图片,搭配 border-image-slice 和 border-image-repeat 的方式,做出波浪造型的边框 ( 类似邮票 )。
<!-- HTML 程式碼 -->
<div class="a"><span>apple</span></div>
<div class="b"><span>banana</span></div>
<div class="c"><span>coconut</span></div>
<div class="d"><span>oxxo</span></div>
<!-- CSS 程式碼 -->
<style>
div {
width: 200px;
height: 200px;
box-sizing: border-box;
border: 50px solid #000;
border-image-source: url("https://steam.oxxostudio.tw/download/css/border-svg-3.svg");
border-image-slice: 33.33% 38% 44.3%;
border-image-width: 1 1 1.3 1;
border-image-repeat: round;
float: left;
}
div span {
display: block;
width: 100%;
height: 100%;
background: yellow;
}
.a {width: 300px;}
.b {height: 300px;}
.c {border-width: 20px;}
.d {
width: 100px;
height: 100px;
border-width: 20px;
}
</style>
小结
图像边框的样式大概是 border 相关样式中最为复杂的,同时也是需要理解图像和切片概念才能操作的样式,不过一但熟悉之后,就会是最容易做出特殊效果的样式。
微信扫码关注
抖音扫码关注