【问题标题】:How granular are CSS rem units?CSS rem 单位的粒度如何?
【发布时间】:2016-05-31 06:58:48
【问题描述】:

我正在开发一个可扩展的移动/桌面友好型网站,使用基于网站平均视口大小的 CSS rem 单位。

我已经为某些填充和边距设置了低至 0.001rem 的 rem 大小,这在我的 Firefox 浏览器中运行良好......但它可以在所有现代浏览器中运行吗?

我只是质疑使用 0.001rem 单位的能力,因为我在千分之一之前看到的最高粒度是不透明度的百分之一……例如opacity:0.25

rem 单位可以走多低? 0.00000001rem 在现代浏览器中是可接受的值吗?

【问题讨论】:

  • w3.org/TR/css3-values/#numeric-types "CSS 理论上支持所有值类型的无限精度和无限范围;但实际上实现的容量是有限的。UA 应该支持合理有用的范围和精度。"
  • This website 是关于百分比舍入和像素渲染,我的猜测是浏览器会像他们如何舍入百分比一样舍入 em/rem 单位。页面底部的表格和测试站点可能会让您感兴趣。
  • 在默认设置为默认缩放的浏览器上,0.00000001rem 相当于 0.00000016 CSS 像素,前提是计算的根字体大小为 16px。您将如何开始在当今存在的任何显示器上表示 0.00000016 CSS 像素?

标签: css units-of-measurement


【解决方案1】:

最终,您的粒度是 1 个物理像素(从技术上讲,现代浏览器中的子像素,但出于讨论的目的,我将忽略它)。您可以根据emrem 获得不同的计算像素值,甚至可以精确到几位数。然后,您会遇到现实世界的问题,即在渲染时,当浏览器最终四舍五入以适应设备像素密度相对于参考像素密度 (96ppi) 的可用像素时,小数精度将丢失。

本质上,这个参考像素是 1/96 英寸。所以1px 在 CSS 术语中基本上意味着 96ppi 时的 1/96"。在像素密度较高的屏幕上(比如许多 Apple“视网膜”屏幕的 326 ppi),会进行缩放以将 CSS 参考像素转换为物理像素。对于提到的视网膜显示,这个比例因子是~3.4。所以如果你指定一个CSS规则来设置10px,视网膜显示浏览器应该显示在34个物理像素上(假设没有其他HTML更改(即元元素)会改变显示行为)。由于这种缩放行为,元素的物理尺寸仍为 10/96",这与在 96ppi 屏幕上渲染元素时的物理尺寸完全相同。

现在让我们将emrem 添加到组合中。因此,让我们使用 10px 根元素字体大小的示例,并在 .001rem 的某个其他元素上声明。这意味着您正在尝试以 0.01 (10px * .001rem) 参考像素渲染此元素,这将在视网膜显示中转换为 0.034 物理像素。您可以清楚地看到,rem 的 0.001 值与在物理显示上产生显着差异至少相差一个数量级,因为在这种情况下,.01rem 将转换为 0.34 个物理像素——四舍五入显示时没有差异对于“更精确”的.001rem 规范。

所以我认为你定义的基于 rem 的 CSS 规则比绘制物理像素时在现实世界中实际可以容纳的更具体,除非你定义了非常高的根元素大小和/或你拥有一个像素密度比视网膜显示器大一个数量级的物理屏幕。我猜后一种情况是不正确的。

仅仅因为 CSS 可以计算到小数点后 3 位或其他精度,这并不意味着物理渲染可以以相同的精度级别进行。

【讨论】:

    【解决方案2】:

    JSBin 上的一个简单示例显示,1.001 rem 的高度呈现为18.0156 px,而1.0001 rem 的高度呈现18 px(这与仅使用1 rem 相同)。

    这意味着您可以精确到 3 位小数(至少在桌面版 Chrome 和常规字体大小中)。

    我也试图编写一个 JavaScript 测试来测量准确性,但 element.offsetHeight 它是一个整数,所以它对这个问题没用。除非有不同的方法来测量以像素为单位的元素尺寸(带小数位)。

    编辑 1:根据 CSS 规范(参见 thisthis),小数位数似乎没有限制。

    但最后,我认为您受到设备像素密度的限制。屏幕上的物理像素是不可分割的,因此所有计算的尺寸都四舍五入到最接近的整数。

    【讨论】:

      【解决方案3】:

      “CSS 理论上支持所有值类型的无限精度和无限范围;但实际上实现的容量是有限的。UA 应该支持合理有用的范围和精度。” w3.org

      然而,在实践中,我的结论是:在 Chrome 中,您可以达到千分之一位 无限精度,直到像素值的小数部分降至 0.015 以下 .

      编辑:一旦将字体大小增加到更大的数字,就会发现原始结论存在缺陷。

      自己测试一下(我用Element.getBoundingClientRect()):

      var l = [
        "normal",
        "tens",
        "hundreds",
        "thousands",
        "ten-thousands",
        "hundred-thousands"
      ];
      var o = document.getElementById("output");
      
      for (var i = 0; i < l.length; i++) {
        o.innerHTML += l[i] + ": " + document.getElementById(l[i]).getBoundingClientRect().height + "px<br>";
      }
      body,
      html {
        font-size: 1000px;
      }
      #normal {
        height: 1rem;
      }
      #tens {
        height: 1.1rem;
      }
      #hundreds {
        height: 1.01rem;
      }
      #thousands {
        height: 1.001rem;
      }
      #ten-thousands {
        height: 1.0001rem;
      }
      #hundred-thousands {
        height: 1.00001rem;
      }
      #output {
        font-size: 16px;
      }
      <div id="output"></div>
      <br>
      <div id="normal">Hello</div>
      <div id="tens">Hello</div>
      <div id="hundreds">Hello</div>
      <div id="thousands">Hello</div>
      <div id="ten-thousands">Hello</div>
      <div id="hundred-thousands">Hello</div>

      我的输出是:

      normal: 1000px
      tens: 1100px
      hundreds: 1010px
      thousands: 1001px
      ten-thousands: 1000.09375px
      hundred-thousands: 1000px
      

      表示万分之一位(0.00001)超出了我的浏览器支持的精度。

      在进一步增加字体大小并使用它之后,我找不到可以产生小数部分 font-size: 1556px和1557px

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-12-06
        • 1970-01-01
        • 2016-07-24
        • 2018-12-27
        • 2017-11-13
        • 2018-05-04
        • 2016-05-02
        相关资源
        最近更新 更多