【发布时间】:2014-12-20 16:47:31
【问题描述】:
我有一个 SVG 元素,可以将项目绘制到精确的像素。当元素本身被放置在 DOM 中的一个精确像素上时,它在所有主流浏览器中都不会出现锯齿。但是,当元素的祖先中有任何子像素偏移时,它就会变得混叠。
我可以通过将形状渲染设置为清晰边缘或优化速度来防止在大多数浏览器中出现锯齿,但是如果 SVG 以错误的方向四舍五入,可能会使 SVG 的内容错位 1 个像素,因此像素行可能是错过了图片的顶部或侧面。
我可以使用 el.getBoundingClientRect() 解决问题并调整边距以消除子像素偏移。这工作一次,但如果元素在 dom 中移动 - 通过滚动、拖动等,则必须重新应用该方法。这意味着监听 DOM,这似乎效率不高。
我想找到一个 CSS 规则,或者我可以将 SVG 包裹在其中以强制将其定位在精确像素处的元素。我想知道是否有一些原生元素 - 例如一个复选框,浏览器可能会为了自己的渲染目的而强制在一个精确的像素上渲染。然后我可以将 SVG 相对于那个对齐......
http://codepen.io/anon/pen/HvCcK(这个问题在Firefox中得到最好的演示)
HTML:
Crisp on FF and Chrome/Safari:<br/>
<div id="s2" style="width:21px; height:7px; background-color:#FFFFFF;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" overflow="hidden" viewBox="0 0 50 70" preserveAspectRatio="xMinYMin" style="display: block;"><defs></defs><g style="display: block;">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="none"></rect>
<path d="M10 10 L 40 10 40 20 20 20 20 30 40 30 40 60 10 60 10 50 30 50 30 40 10 40 Z" fill="white" stroke="none"></path>
</g></svg>
</div>
<br/>
<div class='offpixel'>
Blurry on Firefox (not on exact pixel):<br/>
<div id="s2" style="width:21px; height:7px; background-color:#FFFFFF;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" overflow="hidden" viewBox="0 0 50 70" preserveAspectRatio="xMinYMin" style="display: block;"><defs></defs><g style="display: block;">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="none"></rect>
<path d="M10 10 L 40 10 40 20 20 20 20 30 40 30 40 60 10 60 10 50 30 50 30 40 10 40 Z" fill="white" stroke="none"></path>
</g></svg>
</div>
<br/>
Crisp on Firefox - but not properly drawn: (not on exact pixel, but uses shape-rendering):<br/>
<div id="s2" style="width:21px; height:7px; background-color:#FFFFFF;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" overflow="hidden" viewBox="0 0 50 70" preserveAspectRatio="xMinYMin" style="display: block; shape-rendering: crispedges"><defs></defs><g style="display: block;">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="none"></rect>
<path d="M10 10 L 40 10 40 20 20 20 20 30 40 30 40 60 10 60 10 50 30 50 30 40 10 40 Z" fill="white" stroke="none"></path>
</g></svg>
</div>
</div>
CSS:
body{
font-family:sans-serif;
font-size:10px;
}
.offpixel {
padding:3.5px;
}
【问题讨论】:
-
你能用一个相对位置,然后用一些 CSS 来圆整吗?就像总是产生 int 的计算规则一样?
-
你解决了吗?
-
@JorisMans 我最近找到了一个简单的解决方案。看看我的回答吧。希望它仍然对您有所帮助,因为您的评论还不算太旧...