SVG 占据 100% 的 CSS-Grid 单元格(间隙:0px)
但是(仅在 Firefox 中!)有时会显示白色间隙:
不需要的“间隙”显示网格背景。 (Grid上有一个gap:0px!)
设置
shape-rendering:crispEdges
使差距更大。设置固定整数网格宽度(列 * N)像素“修复”不需要的间隙
(但我不能使用它,我有不同的网格大小,并且对整个网格使用可用的视口(viewport))在所有网格单元格上设置背景色,不显示该间隙线。
一个额外的
<rect width='100%' wheight='100%' fill='blue'/>
在每个 SVG 中确实显示更多不需要的间隙。在网格的右侧还有一条额外的线/间隙。
它是否需要 SVG 或 CSS 网格修复?
更新 1
.. 在 Chrome 中很好。
在 FireFox 中显示红色背景线。 102% 来自答案的溢出“修复”应用于鼠标悬停。 (但这确实会垂直拉伸(stretch) SVG)
<style>
body {
--width: 177px; /* simulating responsive error lines */
--Xwidth: 180px; /* N x 10px 'fixes' the unwanted gaps */
--overflow: 100%; /* see suggested 'fix' below */
background: darkslategrey;
}
#Tiles {
width: var(--width);height: var(--width);
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-template-rows: repeat(10, 1fr);
gap: 0px; background: red; /* should not be visible! */
box-sizing: border-box;
border: 2px solid yellow;
overflow:hidden;
}
#Tiles:hover{ --overflow: 102% }
svg { width: 100%;height: 100%; vertical-align: top }
/* "fix" still leaves one px line at the top. and stretches the SVG vertically */
svg {
width: var(--overflow);height: var(--overflow); overflow: visible;
margin-top: 0px; /* -1px to 'fix' top line */
}
</style>
<div id=Tiles></div>
<script>
Tiles.innerHTML = `<my-tile></my-tile>`.repeat(100);
customElements.define('my-tile', class extends HTMLElement {
connectedCallback() {
this.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 8 8">` +
`<rect width='100%' height='100%' fill='blue' /></svg>`;
}
});
</script>
更新2
将 SO 代码段调整为更小的尺寸...现在 Chrome 也出错了
这只剩下一个修复方法..计算单元格宽度并舍入到整个像素...
最佳答案
您遇到了舍入与抗锯齿陷阱:您的网格有 10 行和 10 列,总宽度超过 504 像素。用 repeat(1fr)
sizing 意味着每个单元格的宽度为 50.4px。 SVG 的大小调整为该值,带有 <rect>
填充整个视口(viewport)。
这意味着图形元素的轮廓与完整像素不重合,并且每个方向上的最外层像素获得部分透明度。
原则上,尝试用shape-rendering: crispEdges
改善显示或 shape-rendering: geometricPrecision
可能会产生结果,但不能保证。无论您分配 50.4 像素,要么至少有一侧带有抗锯齿伪像,要么浏览器可能会在某些行或列上向下舍入像素数。
end verdict总是一样的:
The shape-rendering property provides a hint to the implementation about what tradeoffs to make as it renders vector graphics elements...
提示不是规则。每个浏览器都可以实现自己的解决方案。
调整容器大小</h3>
确保元素具有完整的像素大小是一种解决方案,并且应该始终是第一选择。如果每个维度有 10 个元素的网格,则必须确保网格容器的大小始终为 10 像素的倍数。
但是如果您希望您的网格具有响应性,这可能会很复杂。只有media queries可以做到这一点。 (CSS calc()
函数只接受四个基本运算符,不会舍入值。)
欺骗舍入函数
但是还有另外一条路可走。相邻 <svg>
之间有些重叠元素可以通过 overflow: visible
实现,所以viewBox
之外的内容is not clipped ,并增加渲染内容的面积。这不会改变框大小的计算,它只意味着围绕 <svg>
的隐式剪辑路径。元素被删除。
这显然是错误的,如果正确显示最外面的像素很重要,那么这可能只是错误的解决方案。但对于您的示例,它改善了结果。
102%
宽度的选择大小如果 svg 在屏幕上以 ~50px 的大小显示,则足以覆盖 1px。显然,对于其他比例,此值可能是错误的,但这是在分成像素的屏幕上绘制矢量图形的本质。
div {
position: relative;
height: 51px;
width: 101px;
margin: 20px;
background: red;
}
svg {
width: 50.4px;
height: 50.4px;
}
rect {
fill: blue;
}
path {
stroke: white;
}
.overflowing svg {
overflow: visible;
}
<div>
<svg viewBox="0 0 8 8">
<rect width='100%' height='100%' />
<path d="M4 0v2"/><path d="M6 4h2"/>
<path d="M4 6v2"/><path d="M0 4h2"/>
</svg><svg viewBox="0 0 8 8">
<rect width='100%' height='100%' />
<path d="M4 0v2"/><path d="M6 4h2"/>
<path d="M4 6v2"/><path d="M0 4h2"/>
</svg><br/>
</div>
<div class="overflowing">
<svg viewBox="0 0 8 8">
<rect width='102%' height='102%' />
<path d="M4 0v2"/><path d="M6 4h2"/>
<path d="M4 6v2"/><path d="M0 4h2"/>
</svg><svg viewBox="0 0 8 8">
<rect width='102%' height='102%' />
<path d="M4 0v2"/><path d="M6 4h2"/>
<path d="M4 6v2"/><path d="M0 4h2"/>
</svg>
</div>
关于具有 0px 间隙的 CSS 网格中的 SVG 显示背景颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64695988/