CSS揭秘——连续的图像边框

498 阅读4分钟

背景边框

在一些情况下,我们想把一个图片应用为边框,而不是背景。

最容易想到的应该就是使用两个 DOM 元素,一个用来设置背景,一个用来展示内容,并设置一个纯色背景。

1.png

.wrap {
    background: url(bg.png);
    background-size: cover;
    padding: 1em;
}
.wrap > div {
    background: white;
    padding: 1em;
}

效果是没有问题,但是还不够理想,一来需要多个额外的元素,二来这样会被结构和表现混合起来,在某些场景下,就不适用了。

那如果是用 border-image 可以实现吗?因为要实现图像边框,肯定会想到这个属性,但是 border-image 原理是用的九宫格伸缩法,就是会固定四个点,然后中间进行平铺或者拉伸,不是说一定不能用,就算针对特定的元素宽高和边框找到了切割位置,稍有差异的其他元素就不能适配,这种肯定不是我们可以接受的方案。

这里我们还是可以引入渐变来实现,主要思路就是在背景图上,再叠加一层纯白色的实色背景,同时给两层背景指定不同的 background-clip 值。

11.png

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white), url(bg.png);
background-size: cover;
background-clip: padding-box, border-box;

这个结果已经很接近我们想得到的效果,但仔细看会发现边框的图片有一种怪异的拼接效果。这是因为 background-origin 默认值是 padding-box,因此图片的显示尺寸不仅取决于 padding box 的尺寸,而且会被放置在 padding box 的左上角,这样周围的 border box 区域就会以平铺的方式展现出来,为了修正这个问题,就需要把 background-origin 改为 border-box 就可以。

2.png

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white), url(bg.png);
background-size: cover;
background-clip: padding-box, border-box;
background-origin: border-box;

这些新属性一样可以使用 background 这个简写属性书写,这样就可以减少代码量:

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white) padding-box, url(bg.png) border-box 0 0 / cover;

信封边框

上面的技巧还可以用到渐变图案中,比如实现一种老式信封样式的边框:

padding: 1em;
border: 1em solid transparent;
background: linear-gradient(white, white) padding-box, 
            repeating-linear-gradient(-45deg, red 0, red 12.5%,
            transparent 0, transparent 25%, #58a 0, #58a 37.5%,
            transparent 0, transparent 50%) 0 / 5em 5em;

这个效果也可以使用 border-image 来实现:

padding: 1em;
border: 1em solid transparent;
border-image: 16 repeating-linear-gradient(-45deg, red 0, red 1em,
                transparent 0, transparent 2em, #58a 0, #58a 3em, 
                transparent 0, transparent 4em);

不过这种方法会存在一些问题。

  • 当改变 border-image-slice 时,需要同时修改 border-width 来匹配。
  • 不能在 border-image-slice 属性中使用 em 单位,只能把边框厚度指定为像素单位。
  • 条纹宽度需要在色标位置中写好,因此在改变条纹宽度,需要修改四处。

蚂蚁行军框

这个技巧还能生成蚂蚁行军框,就是一种虚线边框,一直在不断转动,就像排队前进的蚂蚁一样。

8.png

GIF 2021-10-28 11-15-44.gif

GIF 2021-10-28 11-19-15.gif

.ants {
    padding: 1em;
    border: 1em solid transparent;
    background: linear-gradient(white, white) padding-box,
                    repeating-linear-gradient(-45deg, black 0, black 25%,
                    white 0, white 50%) 0 / .6em .6em;
    animation: ants 12s linear infinite;
}
​
@keyframes ants {
    to {
        background-position: 100%;
    }
}

这个技巧还可以创建各种特殊样式的虚线框,可以自定义虚线长度,间隙长度,颜色等都可以配置。

如果要用 border-image 来实现,就只能为 borde-image-source 指定一个 GIF 动画。

上面对 border-image 的感觉在哪都不太适用,其实 border-image 也有自己强大的地方,尤其在搭配渐变图案时。假设需要一个顶部边框被裁切的效果,就像脚注那样的,就需要 border-image 属性再加上一条渐变生成的垂直条纹,并把要裁切的长度在渐变中写好。

9.png

border-top: 0.2em solid transparent;
border-image: 100% 0 0 linear-gradient(90deg, currentColor 4em, transparent 0);
padding-top: 1em;

这里使用 currentColor 这个变量属性,所以会根据 color 属性的变化自动适应。

浙江大华技术股份有限公司-软研-智慧城市产品研发部招聘高级前端!!!!! 欢迎大家来聊,有意向可发送简历到 chen_zhen@dahuatech.com,加入我们,可以一起进步,一起聚餐,一起旅游,让我们从世界村的小伙伴变成大华村的小伙伴。