likes
comments
collection
share

前端怎么实现点九图?看这里

作者站长头像
站长
· 阅读数 3

前言

页面开发过程中经常会遇到用不规则图片当背景图,这个就会导致当容器宽度大于或小于图片宽度的时候图片会变形,这就需要用到“点9图”

点9图,是Android开发中用到的一种特殊格式的图片,文件以“.9.png”命名,这种图片能告诉开发,图像哪一部分可以被拉伸,哪一部分不能被拉伸保持原有比例。这样能保证不规则图片不会因为拉伸变形。通常用于对话框和聊天气泡背景图片以及数据统计背景框

题目

不规则图形如下:

前端怎么实现点九图?看这里

实现容器背景根据内容撑开宽度且不变形?(图片大小为284 x 80)

回答:前端也能通过border-image实现类似于点九图的效果,请看下文

点九图属性

主要就是border-image这个属性,默认值是border-image: none 100% / 1 0 stretch,拆分出来是

border-image-source: none;
border-image-slice: 100%;
border-image-width: 1;
border-image-outset: 0;
border-image-repeat: stretch;

备注(配置更全):border-image: url("image.png") 0 170 0 170 fill / 1px 170px stretch

border-image-source
border-image-source:none; // 默认值
border-image-source:url('./test.png'); // 设置图片
border-image-source:linear-gradient(to right, red, yellow); // 设置渐变色

规定了边框的粗细、形态、颜色及引入图片的地址。

border-image-slice
bordre-image-slice [<number> | <percentage>]{1,4} && fill?

边框图片裁剪,将图片裁剪成9宫格,支持设置百分比和具体数值,1个值(上右下左)同个值、2个值(上下、左右)、3个值(上、左右、下)、4个值(上右下左)。

前端怎么实现点九图?看这里

1、3、6、8就是固定不被拉伸的区域,2、4、5、7就是拉伸区域,9为填充区域(设置了fill会将其作为背景图像显示出来)

<number> 表示到图像边缘的偏移量,在位图中的单位为像素点,在矢量图中则是坐标。对于矢量图,<number> 值与元素大小相关,而非矢量图的原始大小。因此,使用矢量图时,使用百分比值(<percentage>)更可取 <percentage> 以原始图像大小的百分比表示的边缘偏移量:水平偏移使用图像的宽度,垂直偏移则使用图像的高度 <fill> 保留图像的中心区域并将其作为背景图像显示出来,但其会堆叠在 background之上。它的宽度和高度分别对应顶部和左侧图像切片的宽度和高度。

border-image-width
border-image-width: [ <length> | <percentage> | <number> | auto ]{1,4}

控制边框图片大小,如果边框图片大小小于边框区域,则图片会被拉伸,如果大于边框区域,则图片会被裁剪

length 带 px, em, in … 单位的尺寸值

percentage 百分比

number 不带单位的数字;它表示 border-width 的倍数

auto 使用 auto, border-image-width 将会使用 border-image-slice 的值

border-image-outset
border-image-outset: [ <length> | <number> ]{1,4}

图片相对边框区域的偏离

border-image-repeat
border-image-repeat: [ stretch | repeat | round | space ]{1,2}

指定 border-image 的平铺方式,作用是指定 border-image的平铺方式。语法上最多可接收两个参数,第一个参数指定水平方向边框的平铺方式,第二个参数指定垂直方向边框的平铺方式,九宫格的中间区域受这两参数的共同影响

例子

  1. 实现开篇的题目

前端怎么实现点九图?看这里

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        position: absolute;
        top: 100px;
        left: 100px;
        padding: 0 30px;
        height: 40px;
        border-image-source: url(./jd_top_btn_selected.png);
        border-image-slice: 40 100 40 100;
        border-image-width: 40px 100px 40px 100px;
        border-image-repeat: no-repeat;
      }
    </style>
  </head>
  <body>
    <div class="box">测试点九图</div>
  </body>
</html>

// 因为平行四边形的纵轴必须是连续的,所以slice的上下都是为40(四边形的总高度是80),左右就按正常比例获取,我取的100(也可以其他值),注意使用过程中宽度至少大于40才不会断层
  1. 经典题

前端怎么实现点九图?看这里

背景图不变形且中间灰色块平铺填充中间区域?(图片大小90 x 90)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        border: 20px solid;
        border-image-source: url(./border-diamonds.png);
        border-image-slice: 30 fill; // fill是灰色块填充的关键,30是图片里面每个块的宽高
        border-image-repeat: round; // 设置image的平铺方式
      }
    </style>
  </head>
  <body>
    <div class="box">测试点九图</div>
  </body>
</html>
  1. 经典题2

前端怎么实现点九图?看这里

背景图不变形?(图片大小81 x 81)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        position: absolute;
        top: 100px;
        left: 100px;
        height: 100px;
        border-image-source: url(./22.png);
        border-image-slice: 27 27 27 27 fill; // 这里可以不要fill,因为本身这个图片中间区域就是透明的,设置和没设置效果一样
        border-image-width: 27px 27px 27px 27px;
        border-image-outset: 27px 27px 27px 27px; // 向外偏移了
        border-image-repeat: repeat;
      }
    </style>
  </head>
  <body>
    <div class="box">测试点九图</div>
  </body>
</html>

最后最后 ~ 如果觉的文章对你有帮助,也欢迎关注我的公众号哈,不定时推送新的技术文章。 前端怎么实现点九图?看这里

参考