【问题标题】:Rounding CSS Subpixels on transforms在变换上舍入 CSS 子像素
【发布时间】:2015-05-29 18:14:48
【问题描述】:

所以,这个问题以前出现过,比如这里:Translate + Canvas = Blurry Text 在这里:Is it possible to "snap to pixel" after a CSS translate?

对于这些链接或我读过的任何其他文章,似乎都没有任何结论。一些响应者认为它不够重要,所以这就是为什么在我的情况下它是:Chrome 41.0.2272.104 中的屏幕截图

Safari 8.0.4 (10600.4.10.7) 中的屏幕截图

在 Safari 中查看损失的详细信息? (看航天飞机图像中的结构,或第三张图像中岩石的细节)

这些人的 CSS 是

width: 100%;
height: auto;
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);

因此,在某些情况下,translateY 会以半像素结束。左边的第一张图像以这样的变换矩阵结束:

-webkit-transform: matrix(1, 0, 0, 1, 0, -56.5);

目前,chrome 似乎可以很好地呈现这一点(我看到一些人说不同的浏览器会在不同的版本中产生问题),但目前 Safari 存在问题。所以,我解决这个问题的假设是确保只有整个像素,我已经通过数学计算和在 javascript 中应用转换来完成,但是当在大量图像上运行时,这会花费更多的性能时间.

我尝试了一些纯 CSS 技巧,例如使用 scale3d,但均未成功。如果有人有任何无 JS 的解决方案,我将不胜感激。

【问题讨论】:

  • 如果能集成JS就很简单了...
  • 感谢@maioman,在我解释的问题中我已经做到了——但是当我有很多图像时,使用 JS 会对性能产生负面影响。
  • @maioman 另外,没有什么比旧的纯 CSS 解决方案更好的了。

标签: css rendering transform css-transforms


【解决方案1】:

在某些浏览器中,您可以利用 calc 中的浮点舍入误差将您的数字舍入到所需的最接近增量:

calc((2.55px * 5e-324) / 5e-324)

应该使 2.55 像素四舍五入到 3 像素。支持的浏览器是 Chrome(包括 Brave、Electron、Edge 和 Opera 等衍生产品),不支持的浏览器是 IE、Firefox 和 Safari(包括 Midori 等衍生产品)。值得庆幸的是,不支持的浏览器 IE、Firefox 和 Safari 只是将 calc 视为无效的属性值,因为使用的数字超出了可接受的范围。因此,要利用这一点,只需使用下面的示例来生成 CSS 以满足您的需求。是的,我知道这个生成器并不总是结合相似词,是的,有一个原因:结合这些相似词会产生一个无法存储的数字。

var unit = document.getElementById('unit'),
  precision = document.getElementById('precision'),
  property = document.getElementById('prop'),
  output = document.getElementById('output');

function formatProp(x) {
  return (property.value.indexOf('%s') ?
      property.value.replace(/%s/g, x) :
      proprty.value + x).replace(/\\n/g, '\n')
    .replace(/\\t/g, '\t').replace(/\\r/g, '\r');
}
(unit.oninput = precision.oninput = property.oninput = function() {
  var Val = parseFloat(precision.value),
    V1 = "5e-324",
    V2 = "5e-324";
  if (Val < 1)
    V1 = V2 = '' + 5e-324 / Val;
  else if (Val > 1)
    V2 += ' * ' + Val, V1 += ' / ' + Val;

  output.textContent = formatProp(unit.value) + ';       /* for IE and FF*/\n' + formatProp('calc((' + unit.value + ' * ' + V1 + ') / ' + V2 + ')') + ';';
})();
CSS Unit: <input type="text" id="unit" value="-50%" style="width:14em" /><br /> Property : <input type="text" id="prop" value="-webkit-transform: translateY(%s);\ntransform: translateY(%s)" style="width:40em" /><br /> Round to: <input type="number" id="precision"
  value="1" style="width:14em" /> pixels (can be decimal)<b5 />
<pre id="output" style="background:#eee"> </pre>

请注意,根据实时响应的语言定义,是的,您可以在上面的演示中输入自己的值,并且会实时生成相应的CSS。

我创建的测试页面:purposeful-rounding-errors browser support test

请注意,虽然上面的图表功能目前支持浏览器,但它有很大的变化,因为利用舍入误差有点不标准:W3C 规范仅在浮点数的定义中暗示它们,但确实从未明确声明浏览器需要实现低于正常的浮点表示法或舍入错误。

【讨论】:

  • ? 很棒的“解决方案” - 不幸的是它在 Safari 中不起作用
  • @jantimon 很高兴知道。我已经相应地更新了答案。
猜你喜欢
  • 1970-01-01
  • 2019-05-12
  • 1970-01-01
  • 2019-10-08
  • 2012-04-12
  • 1970-01-01
  • 2020-07-13
  • 1970-01-01
相关资源
最近更新 更多