一、实现方式
本文章采用postcss-write-svg与border-image这个css3属性进行1px细线的绘制(仅适合直线,圆角建议用transform于伪类实现),其他的像border-shadow、transform与伪类的实现方式在这里就不说了,网上也搜得到。
具体代码在这webpack-esnext-cli,目录src/pages/test下有使用svg绘制1px线的全部例子。
二、border-image
简单介绍一下border-image的拆分:
border-image-source:url('bg.jpg'); // 用于设置背景源图片
border-image-slice: 1; // 用于设置九宫格上右下左四个方向的裁切比例(也可设置百分比)
border-image-repeat: stretch; // 图片在各边进行拉伸、平铺或重复
border-image-width: 1; // 定义图像边框宽度假如border-image-width大于已指定的border-width,那么它将向内部(padding/content)扩展.
border-image-outset: 0; // 定义边框图像可超出边框盒的大小
复制代码
原理可以看看CSS3 border-image详解,讲解的很清晰了。
三、postcss-write-svg使用
首先我们先配置好postcss-write-svg,这里我们选择生成base64编码图片
require("postcss-write-svg")({
utf8: false
})
复制代码
在css中写一个svg的生成函数
// 仓库的例子中,我是将svg函数写在assets/scss/svg.scss中了,通过webpack插件sass-resources-loader自动引用,所以在vue单文件中可以直接使用不需要再写一遍
@svg 1px-border {
width: 4px;
height: 4px;
@rect {
fill: transparent; // content为透明
width: 100%; // 宽度为4px * 100%
height: 100%; // 高度为4px * 100%
stroke-width: 25%; // 边框宽度 4px * 25%(即1px)
stroke: var(--color, black); // 颜色
}
}
复制代码
上面的函数,可以让我们生成一个有1px边框,宽高为4px的矩形,下面是我运用此svg函数生成的1px线:
途中可以看到,我们使用普通的border: 1px solid red;生成的1px线是会粗一点的,这是由于retine屏幕导致的(原理可看大漠的一篇再谈Retina下1px的解决方案_CSS, mobile 教程_w3cplus)。下面是该函数的具体应用:
#real-1px {
margin: 10px;
height: 20px;
}
#real-1px {
border: 1px solid;
border-image: svg(1px-border param(--color red)) 1 stretch;
}
复制代码
这里使用25%的裁切(即上右下左各做1px的裁切,获取裁切出来的部位给我们的border进行背景的设置),这里我们裁切出一个具有1px红边框与1px透明内边框的图片大概如下图所示
这里你会发现图中在低版本安卓和iphone中有个错误的上边框显示,三条1px边框是粗的,单边上边框却是细的。
下面是解决方法
// 仓库中代码编写了mixin去做这种兼容,比如设置顶部边框,则@include setSvgSingleBorder(top);
#real-top-1px {
...
border: 0; // 将其余三遍的border宽度设置成0
border-top: 1px solid; // 这里将单边覆盖上面border的宽度设置
border-image: svg(1px-border param(--color red)) 1 stretch;
}
复制代码
上面我们需要将border的其余三边不需要显示红线的设置为0,否则将会出现兼容问题,iphone与部分低端安卓无法正常显示。这样我们就可以在开发中愉快得使用svg去绘制自己想要的1px细线了。