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

前言

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

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

题目

不规则图形如下:

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

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

点九图属性

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

js 复制代码
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
js 复制代码
border-image-source:none; // 默认值
border-image-source:url('./test.png'); // 设置图片
border-image-source:linear-gradient(to right, red, yellow); // 设置渐变色

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

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

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

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

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

border-image-width
arduino 复制代码
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
css 复制代码
border-image-outset: [ <length> | <number> ]{1,4}

图片相对边框区域的偏离

border-image-repeat
r 复制代码
border-image-repeat: [ stretch | repeat | round | space ]{1,2}

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

例子

  1. 实现开篇的题目
js 复制代码
<!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)

js 复制代码
<!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)

js 复制代码
<!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>

参考

  1. 什么是点九图,如何在CSS中实现点九图?彻底搞懂 border-image!
  2. 知乎:Web端的"点九图"
  3. 点九图
  4. 使用 CSS 轻松实现一些高频出现的奇形怪状按钮
  5. cdn的点九图
  6. 知乎:web端如何实现点9图
  7. border-image工具调试:贼好用
相关推荐
bloxed25 分钟前
前端文件下载多方式集合
前端·filedownload
余生H31 分钟前
前端Python应用指南(三)Django vs Flask:哪种框架适合构建你的下一个Web应用?
前端·python·django
LUwantAC39 分钟前
CSS(四)display和float
前端·css
cwtlw43 分钟前
CSS学习记录20
前端·css·笔记·学习
界面开发小八哥1 小时前
「Java EE开发指南」如何用MyEclipse构建一个Web项目?(一)
java·前端·ide·java-ee·myeclipse
米奇妙妙wuu1 小时前
react使用sse流实现chat大模型问答,补充css样式
前端·css·react.js
傻小胖1 小时前
React 生命周期完整指南
前端·react.js
梦境之冢2 小时前
axios 常见的content-type、responseType有哪些?
前端·javascript·http
racerun2 小时前
vue VueResource & axios
前端·javascript·vue.js
m0_548514772 小时前
前端Pako.js 压缩解压库 与 Java 的 zlib 压缩与解压 的互通实现
java·前端·javascript