解决一像素问题网上有很多种方法,除去缩放图片这种限制颜色的方案,以及兼容性并不好的 border-image ,我选择了这两种方案进行了尝试。下面是尝试截图。
使用 svg 解决一像素问题
- 安装
postcss-write-svg
基于 postcss 处理 简化 svg 的能力 - 编写代码片段
@svg line {
@line {
x1: var(--x1, 0);
x2: var(--x2, 100%);
y1: var(--y1, 0);
y2: var(--y2, 0);
stroke: var(--color, red);
fill: transparent;
stoke-width: 1;
}
}
:root {
--self-border-color: #00b1ff;
--self-line-item: {
height: 40px;
line-height: 40px;
text-align: center;
margin-top: 15px;
}
--self-rect-item: {
width: 90vw;
height: 40px;
line-height: 40px;
text-align: center;
margin: 20px;
}
}
- 使用定义好的函数
.svg {
@apply --self-rect-item;
background-image: svg(line param(--color #00b1ff) param(--y1 100%) param(--y2 100%));
}
/** 产出结果 **/
.svg{
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cline x1='0' x2='100%25' y1='100%25' y2='100%25' stroke='%2300b1ff' fill='transparent' stoke-width='1'/%3E%3C/svg%3E");
}
此方案优势:
- 获得
svg
能力 绘制出符合需求的任意角度、任意长度、任意位置的线. - 并且可以使用
background
实现多背景绘制多条线。
.multi {
@apply --self-line-item;
background-image: svg(line param(--color #00b1ff) param(--y1 100%) param(--y2 100%)), svg(line param(--color red));
}
- 移动端兼容性极佳。
此方案劣势:
- svg 绘制圆角时表现不佳,代码展示如下,效果请参考图片。
@svg square {
@rect {
fill: transparent;
stroke: var(--color, transparent);
stroke-width: 1;
width: 100%;
height: 100%;
rx: var(--rx, 0);
ry: var(--ry, 0);
}
}
.rect {
@apply --self-rect-item;
background-image: svg(square param(--color #00b1ff) param(--rx 10) param(--ry 10));
}
- 语义化并不明确,有学习成本的,具备解决北京冲突的能力。
使用伪类解决
设置伪类边框,根据 dpi 缩放容器元素的伪类实现 1px。
@custom-media --low-resolution (max-device-pixel-ratio: 1.49),(max-resolution: 143dpi), (max-resolution: 1.49dppx);
@custom-media --mid-resolution (min-device-pixel-ratio:1.5) and (max-device-pixel-ratio:2.49), (min-resolution:144dpi) and (max-resolution:239dpi), (min-resolution:1.5dppx) and (max-resolution:2.49dppx);
@custom-media --high-resolution (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx);
--border {
position: relative;
&::after{
pointer-events: none;
position: absolute;
z-index: 999;
top: 0;
left: 0;
bottom: 0;
content: "\0020";
transform-origin: 0 0;
}
@media (--low-resolution) {
&:after {
width: 100%;
height: 100%;
}
}
@media (--mid-resolution) {
&:after {
width: 200%;
height: 200%;
transform: scale(.5);
}
}
@media (--high-resolution) {
&:after {
width: 300%;
height: 300%;
transform: scale(.333);
}
}
}
/** 使用 **/
.fack{
@apply --border;
&::after{
border-bottom: 1px solid red;
}
}Ï
此方案优势:
1.解决圆角问题
此方案劣势:
- 伪元素边框为溢出展示的所以要设置
overflow:visible
,否则你就只有一半的边框了。
- 设置圆角需要同样在媒体查询下设置
.fack_border{
@apply --self-rect-item;
@apply --border;
&::after{
border: 1px solid var(--self-border-color);
}
@media (--low-resolution) {
&:after {
border-radius: 10px;
}
}
@media (--mid-resolution) {
&:after {
border-radius: 20px;
}
}
@media (--high-resolution) {
&:after {
border-radius: 30px;
}
}
}