css|border-image+点九图高雅的做背景边框🎨🎨

5,092 阅读6分钟

什么是点九图

Android平台里有一种特殊的图片形式,文件扩展名 xxx.9.png,为了方便记忆,所以称其为点九图,英文是 Nine Patch。

应用场景

当我们需要为一段文字添加图片背景,而我们并不知道这段文字的长度和宽度,该如何解决?

一个图片在不同的分辨率下,边角会失真,如何解决?

思考💡:我们怎么做到对图片进行部分拉伸,如果可以实现部分拉伸,那就可以解决上述的场景

对比图

在日常开发中,我们很多时候都会处理这样的场景,就是ui提供了背景图片,但是背景图片可能宽度不够,我们就肆意的拉伸来满足需求,但是实践发现,拉伸的图片会模糊,这个时候我们就需要用点九图处理

看一下对比图

image.png

上面的是肆意拉伸的结果,下面是用点九图拉伸的结果,点九图的制作主要跟下面几个属性有关,依次学习一下

border-image

border-image 属性可以通过一些简单的规则,将一副图像划分为 9 个单独的部分,浏览器会自动使用相应的部分来替换边框的默认样式。

border-image是border-image-source || border-image-slice|| border-image-width|| border-image-outset || border-image-repeat 属性的简写

其中,border-image-width 通常省略,取border-width的值,border-image-outset也很少用。所以实际应用中最常用的写法就是:border-image: source slice round;

我们常见的格式可能就是 border-image: url('./image/link-on.png') 20 14 20 14 fill stretch stretch;

border-image-source:定义边框图像的路径;

border-image-slice:定义边框图像从什么位置开始分割;

border-image-width:定义边框图像的厚度(宽度);

border-image-outset:定义边框图像的外延尺寸(边框图像区域超出边框的量);

border-image-repeat:定义边框图像的平铺方式

url

url就不解释了

border-image-slice

主要解释一下border-image-slice,这个代表把我们的图片怎么切割,切割的值是1~4个,不用写单位的,默认值就是px,对应css的常见规则 上 右 下 左,我们把图片切割四刀,就会形成一个九空格了,切割出来的四个角是不变的,那拉伸的时候,只有图中的5 8 9 6 7 这5个部分会被拉伸,那我们接着学一下拉伸border-image-repeat

image.png

border-image-repeat

border-image-repeat 属性用来设置如何填充使用 border-image-slice 属性分割的图像边框,例如平铺、拉伸等等,该属性的语法格式如下

border-image-repeat:stretch | repeat | round

1.stretch(拉伸)默认值

border-image:url() 27 stretch(水平和垂直方向都是拉伸)

image.png

就像上面所说的那样,边角的不会发生变化,水平的部分就是水平拉伸,垂直部分就是垂直拉伸,很明显

2.round(平铺)

border-image:url() 27 round(水平和垂直都是平铺)

image.png

和上图进行对比会发现,这就是重复,而且重复的还是除了边角之外的部分,这个重复得很整齐,也就是说这个并没有多出一部分不能完好的放置,而是每一个都很完整,这就是平铺和重复的区别了,再往下看就知道了。

3.repeat(重复)

border-image:url() 27 repeat(水平和垂直都是重复)

image.png

小总结

1.border-image的常用参数有三个,分别是图片链接,裁剪位置,重复方式

2.裁剪位置是按照上右下左顺时针的方式进行裁剪,即离上面多少,离右边多少,离下面多少,离左边多少

3.在进行变化的时候,边角是不发生变化的

4.第三个参数分为水平和垂直的变化,当只有一个参数时,表示水平和垂直的变化相同,round和repeat重复方式的区别在于round会将要重复的内容进行等比例的缩放来实现不重叠的效果,而repeat就是单纯的重复,可能会产生重叠的效果(注意:这里说的是可能会,因为如果裁剪的大小刚好的话就不会发生重叠的效果,此时round和repeat的效果相同)

border-width和border-image-width的区别

思考💡:border-image-width 和 border-width 各自的作用是什么?通过两个例子来看

image.png

上图中,border-width 是30px,border-image-width 是15px,所以边框图片被缩小成15px的尺寸填充到border里面。

image.png

再看上图,border-width 还是30px,border-image-width 是60px,所以边框图片被放大到60px的尺寸填充到border里面,甚至超出了border区域,延伸到盒子的background当中。

所以,border-image图片填充的区域大小,取决于 border-image-width ,跟素材图尺寸无关,跟border-width也无关。只是在不设置border-image-width的时候,它的值默认等于border-width

最后,border-width要在border-image之前设置,否则在chrome可能显示不正确。

案例

案例1

image.png

把我们前面提到的对比图,展示一下,原图是这样的

link-on.png

那我再拉伸的时候,自然是想保持四个角不变 ,这里介绍一个好用的点九图网站

image.png

通过这个网站的解析,我们很容易得到我们的切割值,下面看一下核心代码

    .jiu-bg {
        width: 273px;
        border-width: 20px;
        border-style: solid;
        border-image: url('./image/link-on.png') 20 14 20 14 fill stretch;
    }

案例2

想要的效果是这样的

image.png

原图是这样的

20210910161239291.png

通过网站获取切割值,因为我们无论怎么拉伸,都不希望四个不规则顶角边框变化,所以

Snipaste_2022-08-07_15-19-43.png

核心代码

    .jiu-bg {
        width: 1024px;
        min-height: 300px;
        border: 58px solid transparent;
        border-image: url('./image/test.png') 58 58 fill stretch;
    }

体会一下fill,如果没有fill会是什么样的 border-image: url('./image/test.png') 58 58 stretch; Snipaste_2022-08-07_15-24-33.png

案例3

需求图是这样的,手机端的气泡图的原理就是点九图实现的

Snipaste_2022-08-07_15-36-34.png

原图是这样的

12253747-5f007edbaf38baf3.webp

核心代码


<html>
    <head>
        <title>border-image</title>
    </head>
    <style>
        body{
            background: black;
        }

        .con{
            height: 220px;
            padding: 0px 50px;
            width: fit-content;
            color: white;
            border-width: 1px;
            border-style: solid;
            border-image: url('./image/test2.webp') 0 170 0 170 fill / 1px 170px stretch;
        }
        .ctn{
            position: relative;
            top: 96px;
        }
    </style>
    <body>
        <img id="img" src="image.png" />

        <div class="con">
            <span class="ctn">我是内容我是内容我是内容我是内容我是内容我是内容</span>
        </div>
    </body>
</html>

image.png

主要解释一下border-image: url("image.png") 0 170 0 170 fill / 1px 170px stretch 因为不在乎高度,只管左右的拉伸,所以上下切割0,左右各选了170像素,这个部分是不会因为width增加而改变的。 fill字段就是让两个| | 中间的部分填充背景

后面的1px 170px指的是border-image-width ,字面意思是边框图片宽度,上下是1px,左右是170px

3.gif

总结

CSS3中的border-image详解

border-image属性总结

CSS border-image(边框图片

前端web的点9图效果实现