cssnext 环境下1px border 解决方案

解决一像素问题网上有很多种方法,除去缩放图片这种限制颜色的方案,以及兼容性并不好的 border-image ,我选择了这两种方案进行了尝试。下面是尝试截图。

cssnext 环境下1px border 解决方案_第1张图片
15257817289049.jpg

使用 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");
}

此方案优势:

  1. 获得 svg 能力 绘制出符合需求的任意角度、任意长度、任意位置的线.
  2. 并且可以使用 background 实现多背景绘制多条线。
.multi {
    @apply --self-line-item;
    background-image: svg(line param(--color #00b1ff) param(--y1 100%) param(--y2 100%)), svg(line param(--color red));
}
  1. 移动端兼容性极佳。

此方案劣势:

  1. 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));
}
  1. 语义化并不明确,有学习成本的,具备解决北京冲突的能力。

使用伪类解决

设置伪类边框,根据 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.解决圆角问题

此方案劣势:

  1. 伪元素边框为溢出展示的所以要设置 overflow:visible,否则你就只有一半的边框了。
cssnext 环境下1px border 解决方案_第2张图片
15257825853338.jpg
  1. 设置圆角需要同样在媒体查询下设置
.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;
        }
    }
}

你可能感兴趣的:(cssnext 环境下1px border 解决方案)