问题描述
在Chrome和其他基于Blink / webkit的浏览器中,SVG背景显示为模糊:
Chrome中的SVG的一部分的屏幕截图:
Firefox中SVG的一部分的屏幕截图:
仅当显示带有“ background-repeat:true”和“ background-size:contain” CSS值的SVG时,才会发生这种情况。我们希望重复SVG背景高度,因为页面高度是动态的,并且拉伸矢量图像的效果会很差。
SVG在下面的示例页面的CSS中内联显示,但是当我链接到外部SVG图像时,问题也会以相同的方式发生。
以下是显示此行为的测试页: https://august-13-2020-test-canvas.bubbleapps.io/version-test/pagemaker-test-original-2 (使用“用户名”和“密码”登录,我们需要在此处输入此身份验证。)
具有正确显示的(清晰/平滑的边缘)SVG的测试页位于:https://august-13-2020-test-canvas.bubbleapps.io/version-test/pagemaker-test-online-1
具有清晰/平滑边缘的版本以完全相同的方式显示-唯一的区别是SVG的内容。
以下是指向模糊页面的背景SVG的链接:https://dd7tel2830j4w.cloudfront.net/d44/f1588704991659x396570736162959360/background.svg
我在此页上测试的所有SVG都有清晰的边缘:https://www.svgbackgrounds.com/#flat-mountains(右下角是上述链接中使用的那个)
在尝试解决此问题或在SVG代码中确定其原因的过程中,我对SVG进行了很多编辑,尝试以下操作:
- 将所有SVG点值(路径的d属性)转换为整数
- 在SVG的开始标签中添加“ PreserveAspectRatio”
- 从SVG的打开声明中删除高度和宽度
- 从SVG中删除“线性渐变”,并用静态颜色替换
- 将SVG形状的尺寸加倍,以查看模糊度是否随着较大的初始宽度和高度而减小
- 将“ crispEdges”属性添加到SVG路径
- 使用Svgomg优化SVG
此外,我尝试了一下CSS更改,但是无法正常工作。
关于变通办法的一些想法如下:
- 使用多个背景图像重复显示SVG(在背景中显示5-10次,模仿背景重复:重复y效果,但包括多个背景图像)
- 使用JS在页面上内联绘制SVG(不会发生此错误),创建一个与我们组的动态高度完全相同的高度的HTML(可以随时更改而不会触发JS事件)并在该组中以某种方式重复使用SVG。
- 向设计师询问其他SVG背景,并希望不会再出现模糊问题。
这里的任何帮助将不胜感激,我为此付出了很多努力,但在CodeMentor.io上咨询了几位开发人员后,无法解决此问题。
解决方法
眨眼似乎应用了错误的算法,首先以错误的尺寸渲染SVG,然后缩放生成的光栅图像。要解决此问题非常棘手,因为涉及到两种缩放机制,即SVG viewBox
和CSS background-size
。
我只能提供部分解决方案,可以在Chrome和Edge(两个引擎)中使用,但不能在Firefox中使用。
它使用background
元素将缩放和重复的职责从CSS <pattern>
属性移到SVG本身。 SVG图像的完整内容在此元素内移动,包括将viewBox
属性设置为相同的值。
然后,将图案重复的宽度和高度值设置为width="100vw" height="504vw"
。这将填充视口宽度,并保持高度的纵横比。 (Firefox在这种情况下似乎无法解释vw
单位)。
最后,定义宽度为height = 100%的<rect>
并用图案填充,并且将没有<svg>
属性的根viewBox
元素类似地设置为width =高度= 100%。
<svg width="100%" height="100%" fill="none" xmlns="http://www.w3.org/2000/svg">
<pattern id="pt" width="100vw" height="504vw" x="0" y="0" viewBox="0 0 1440 7258" patternUnits="userSpaceOnUse" preserveAspectRatio="xMinYMin meet">
<rect width="1440" height="7258" fill="white"/>
<path d="M-137 1749L1546 1994.95V2870L-137 2624.64V1749Z" fill="#F7F8FF"/>
<path d="M-137 3776L1546 4021.95V4897L-137 4651.64V3776Z" fill="url(#paint0_linear)"/>
<path d="M-137 3969L1546 4214.95V4900L-137 4654.64V3969Z" fill="url(#paint1_linear)"/>
<path d="M1319 2764L1545 2796.96V2870L1319 2837.12V2764Z" fill="#264CE9"/>
<path d="M-53 2645L96 2666.68V2744L-53 2722.37V2645Z" fill="#FBE89F"/>
<path d="M-29 2571L307 2620.13V2699L-29 2649.99V2571Z" fill="#54A5F2"/>
<path d="M1209 2820L1545 2869.13V2948L1209 2898.99V2820Z" fill="#6AD2F6"/>
<path d="M-147 4649L307 4715.42V4891L-147 4824.74V4649Z" fill="#6AD2F6"/>
<path d="M-137 -233L1546 12.9461V688L-137 442.638V-233Z" fill="url(#paint2_linear)"/>
<g style="mix-blend-mode:multiply">
<path d="M987 -144L2119 21.4151V388L987 222.978V-144Z" fill="#6AD2F6"/>
</g>
<path d="M-137 27L1546 272.946V948L-137 702.638V27Z" fill="url(#paint3_linear)"/>
<path d="M-258 455L490 564.509V794L-258 684.751V455Z" fill="url(#paint4_linear)"/>
</pattern>
<linearGradient id="paint0_linear" x1="43.9999" y1="3807" x2="458.5" y2="4665" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.06"/>
<stop offset="1" stop-color="#F7F8FF" stop-opacity="0.26"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="43.9999" y1="4000" x2="1229" y2="5099" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.06"/>
<stop offset="1" stop-color="#F7F8FF" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="194" y1="87.4999" x2="1671" y2="300" gradientUnits="userSpaceOnUse">
<stop offset="0.270833" stop-color="#264CE9"/>
<stop offset="1" stop-color="#6AD2F6"/>
</linearGradient>
<linearGradient id="paint3_linear" x1="194" y1="347.5" x2="1671" y2="560" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9"/>
<stop offset="1" stop-color="#6AD2F6"/>
</linearGradient>
<linearGradient id="paint4_linear" x1="-108" y1="550.5" x2="490" y2="638" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.43"/>
<stop offset="1" stop-color="#264CE9"/>
</linearGradient>
<rect width="100%" height="100%" fill="url(#pt)" />
</svg>
我稍微简化了标记,但是这些更改都是修饰性的,包括删除clipPath
-无论如何,它都适用于图案元素。
从来没有找到解决此问题的方法(或者至少没有实现ccprog提出的解决方案)。
我们选择将SVG文件编辑更长。我们的SVG文件被用作具有动态长度且理论上没有高度限制的网页的背景。
通过重复将SVG高度提高到约8000px 5次,它会覆盖直到网页达到40000px的高度,这对于我们的用例来说应该没问题。我使用了inkscape来复制每个SVG的内容,然后复制该内容几次,使最终的SVG比原始SVG高5倍。