具有 0px 间隙的 CSS 网格中的 SVG 显示背景颜色

标签 svg css-grid

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/

相关文章:

css - 在单个 CSS 网格行上设置高度值

css - 创建一个带有 n*n 方 block 的 css 网格

css - Edge 和 IE CSS 网格兼容性

html - 浏览器能否在 SVG 元素本身之外呈现 svg 元素的某些部分?

javascript - 在 d3js 中生成箭头

javascript - 在用 d3.js 制作的 map 上显示图标/图像而不是圆圈/路径

html - 网格元素未使用 minmax() 函数正确包装

html - 媒体查询不适用于移动屏幕尺寸

image - 用于将 TIFF 或 PNG 或 JPEG 转换为 SVG 的 Java API

javascript - 我如何在我的站点中使用 codepen 中的 svg 动画?