我有一个带有SVG图像的HTML网页。当我使用iOS Safari或Android浏览器访问网页时,我在网页上遇到了问题(多余的白线,如下图所示)。屏幕截图分辨率为2x,锯边是SVG图像。
我发现当SVG图像的页面Y位置不是CSS像素的整数(px
)时,即½px
时,就会发生这种情况。浏览器在呈现网页时将SVG图像位置四舍五入为整数px
,而不围绕其他元素位置。这就是出现½px
行的原因。
您可以使用下面的代码段(或this CodePen)重现问题。您应该在具有高像素密度的设备上运行代码段。如果您进入自适应设计模式并选择iPhone或iPad,您也可以在桌面Safari中重现它。
.common-bg {
background: #222;
fill: #222;
}
.block {
max-width: 300px;
margin: 20px auto;
}
.block_content {
height: 50.5px;
}
.block_edge {
display: block;
}
<div class="block">
<div class="block_content common-bg"></div>
<svg
class="block_edge"
width="100%"
height="10"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<pattern id="sawPattern" x="50%" width="20" height="10" patternUnits="userSpaceOnUse">
<path d="M 0 0 L 10 10 L 20 0 Z" class="common-bg"/>
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="10" fill="url(#sawPattern)"/>
</svg>
</div>
如何在iOS Safari和Android浏览器上防止½px
SVG转换?这是一个错误,我应该向WebKit开发人员报告吗?也许有一种方法可以使浏览器在px
页面上的其他元素?{/ p>
我可以在不阻止½px
移位的情况下解决此问题:
.block_content
但我想知道有没有办法防止½px
转变,因为上述解决方案并非总是可行。
答案 0 :(得分:5)
iOS:您只需要将任何CSS转换添加到SVG元素以在Safari中修复它。例如.block_edge {-webkit-transform: scale(1); transform: scale(1)}
。
Android:首先,您需要为SVG元素添加一个微小的CSS比例变换。执行此操作后,<svg>
和<rect>
元素将呈现在必须的位置,但<rect>
背景将在顶部和底部重复显示:
要修复它,您需要将图案扩展到顶部和底部以防止背景重复。然后,您需要在SVG顶部正上方添加填充<rect>
以删除顶部的最后一个空行。在Android浏览器的顶部仍然会留下难以看见的深灰色线条。
.common-bg {
background: #222;
fill: #222;
}
.block {
max-width: 300px;
margin: 20px auto;
}
.block_content {
height: 50.5px;
}
.block_edge {
display: block;
/* Fix. No more than 5 zeros. */
-webkit-transform: scale(1.000001);
transform: scale(1.000001);
}
&#13;
<div class="block">
<div class="block_content common-bg"></div>
<svg
class="block_edge"
width="100%"
height="10"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<pattern id="sawPattern" x="50%" y="-1" width="20" height="12" patternUnits="userSpaceOnUse">
<path d="M 0 0 L 0 1 L 10 11 L 20 1 L 20 0 Z" class="common-bg"/>
</pattern>
</defs>
<rect x="0" y="-1" width="100%" height="1" common-bg="common-bg"/>
<rect x="0" y="0" width="100%" height="10" fill="url(#sawPattern)"/>
</svg>
</div>
&#13;
我在Android上的移动和桌面Safari 10,Android 4.4和Chrome 58上进行了测试。
结论:修复过于复杂且不可靠,所以我建议制作半像素移位不会导致空白行的布局。
.common-bg {
background: #222;
fill: #222;
}
.block {
max-width: 300px;
margin: 20px auto;
}
.block_content {
height: 50.5px;
}
.block_edge {
display: block;
/* Overflow for unexpected translateY */
margin-top: -1px;
}
&#13;
<div class="block">
<div class="block_content common-bg"></div>
<svg
class="block_edge"
width="100%"
height="12"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<!-- The teeth pattern is extended to the top -->
<pattern id="sawPattern" x="50%" width="20" height="12" patternUnits="userSpaceOnUse">
<path d="M 0 0 L 0 1 L 10 11 L 20 1 L 20 0 Z" class="common-bg"/>
</pattern>
</defs>
<rect x="0" y="0" width="100%" height="11" fill="url(#sawPattern)"/>
</svg>
</div>
&#13;
答案 1 :(得分:1)
将outline: 1px solid #000;
添加到.block_content
。这将填补iPhone 6上两个svg图形之间的差距。我意识到这会产生间距问题,但它确定了差距。
该问题的解决方案是创建一个@media查询,您只需将outline
添加到.block_content
,其大小会影响iPhone 4-6。
.block {
max-width: 300px;
margin: 20px auto;
}
.block_content {
background: #000;
font-size: 10px;
height: 50.5px;
outline: 1px #f00 solid;
}
.block_edge {
display: block;
}
.block_edge path {
fill: #000;
}
&#13;
<div class="block">
<div class="block_content"></div>
<svg
class="block_edge"
width="100%"
height="10"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<pattern id="sawPattern" x="50%" width="20" height="10" patternUnits="userSpaceOnUse">
<path d="M 0 0 L 10 10 L 20 0 Z"/>
</pattern>
</defs>
<rect id="Line" x="0" y="0" width="100%" height="10" fill="url(#sawPattern)"/>
</svg>
</div>
&#13;
答案 2 :(得分:1)
您是否考虑过使用css注入边框?
在snipped下面使用单个\/
重复并在android(chrome)和iOs上运行。我可以通过放大iOs来触发一条微弱的发际线。这可以通过在三角形上方添加一个块并将::after
与其父级重叠来解决。
Codepen version for testing on mobile
.block {
max-width: 300px;
margin: 20px auto;
}
.block_content {
background: #000;
font-size: 10px;
height: 50.5px;
position: relative;
}
.block_content::after {
content: '';
position: absolute;
height: 1em;
width: 100%;
top: 100%;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg width='2' height='1' xmlns='http://www.w3.org/2000/svg' %3e%3cpath d='m1 1L2 0H0z'/%3e%3c/svg%3e");
/* bg generated from https://codepen.io/elliz/full/ygvgay */
background-size: 2em 1em;
background-repeat: repeat-x;
}
<div class="block">
<div class="block_content"></div>
</div>