CSS 渐变锯齿消失术

在 CSS 中,渐变(Gradient)可谓是最为强大的一个属性之一 。
但是 , 经常有同学在使用渐变的过程中会遇到渐变图形产生的锯齿问题 。
何为渐变锯齿?那么,什么是渐变图形产生的锯齿呢?
简单的一个 DEMO:
<div></div>div {    width: 500px;    height: 100px;    background: linear-gradient(37deg), #000 50%, #f00 50%, #f00 0);}效果如下:其实 , 锯齿感已经非常明显了,我们再放大了看,其内部其实是这样的:

CSS 渐变锯齿消失术

文章插图
又或者是这样:
CSS 渐变锯齿消失术

文章插图
有意思的是,锯齿现象在 DPR 为 1 的屏幕下特别明显,而在一些高清屏(dpr > 1)的屏幕下 , 感受不会那么明显 。
DPR(Device Pixel Ratio)为设备像素比,DPR = 物理像素 / 设备独立像素,设备像素比描述的是未缩放状态下,物理像素和设备独立像素的初始比例关系 。
那么为啥会产生锯齿感呢?
传统网页的呈现是基于像素单位的,对于这种一种颜色直接过渡另外一种颜色状态的图片,容易导致可视质量下降(信息失真) 。因而对于普通的渐变元素 , 像是上述写法,产生了锯齿 , 这是非常常见的在使用渐变过程中的一个棘手问题 。
简单的解决办法解决失真的问题有很多 。这里最简单的方式就是不要直接过渡 , 保留一个极小的渐变过渡空间 。
上述的代码,我们可以简单改造一下:
div {    width: 500px;    height: 100px;  - background: linear-gradient(37deg), #000 50%, #f00 50%, #f00);  + background: linear-gradient(37deg), #000 49.5%, #f00 50.5%, #f00);}仔细看其中的变化,我们从 50% --> 50% 的直接过渡,变化成预留了 1% 的渐变过渡空间,效果如下:
CSS 渐变锯齿消失术

文章插图
可以看到,效果立马有了大幅提升!
当然,如果不想修改原代码,也可以通过叠加一层伪元素实现,这里给出 3 种方式的对比图:
<div></div><div class="gradient"></div><div class="pesudo"></div>:root {    --deg: 37deg;    --c1: #000;    --c2: #f00;    --line-width: 0.5px;}div {    margin: auto;    width: 500px;    height: 100px;    background: linear-gradient(        var(--deg),        var(--c1) 50%,        var(--c2) 50%,        var(--c2) 0    );}// 方法一:.gradient {    background: linear-gradient(        var(--deg),        var(--c1),        var(--c1) calc(50% - var(--line-width)),        var(--c2) calc(50% + var(--line-width)),        var(--c2) 0    );}// 方法二:.pesudo {    position: relative;    &::before {        content: "";        position: absolute;        top: 0;        left: 0;        right: 0;        bottom: 0;        background: linear-gradient(            var(--deg),            transparent,            transparent calc(50% - var(--line-width)),            var(--c1) calc(50% - var(--line-width)),            var(--c2) calc(50% + var(--line-width)),            transparent calc(50% + var(--line-width)),            transparent        );    }}

推荐阅读