我们现在可以在屏幕 CSS 上准确地映射英寸吗?

Can we map inches on screen CSS accurately now?

好的。这是一个古老的,但很有趣。

我知道我们有 1in 物理单位映射到屏幕 dpi 上的 96px。此映射来自 90 年代,当时 monitors/screens 的分辨率要低得多。那是一个不同的时代。当时 Web 是 'desktop only' 实用程序,正如人们所怀疑的那样,今天的实现跟不上新 landscape of the web.

的步伐

大约 2020 年。

我想在我的网页 :root 处声明一个 css 变量 --inch 并使用媒体查询将其映射到不同设备的绝对英寸。我可以在我目前拥有的设备上执行此操作,例如:

/* css */
:root {
   --inch: 130px; /* this value is from my Macbook Pro 2017 for example. */
}

.square {
  width: var(--inch);
  height: var(--inch);
  background: red;
}

然后我用尺子测量了屏幕上正方形的尺寸。我什至为此制作了一个 codepen 来测试和比较绝对英寸与 browser/machine 支持的 in 单位。

现在。我们应该如何设置 --inch 跨移动设备、watchos、iPad、台式机以及可能的电视和投影仪的变量?


更新 1:稍微确定了范围。

以下 media-queries 涵盖了市场上可供选择的各种屏幕。此列表来自 2013 年 (credits),可能并不详尽,但可以改进:

@media only screen and (min-width: 320px) {

  /* Small screen, non-retina */

}

@media
only screen and (-webkit-min-device-pixel-ratio: 2)      and (min-width: 320px),
only screen and (   min--moz-device-pixel-ratio: 2)      and (min-width: 320px),
only screen and (     -o-min-device-pixel-ratio: 2/1)    and (min-width: 320px),
only screen and (        min-device-pixel-ratio: 2)      and (min-width: 320px),
only screen and (                min-resolution: 192dpi) and (min-width: 320px),
only screen and (                min-resolution: 2dppx)  and (min-width: 320px) { 

  /* Small screen, retina, stuff to override above media query */

}

@media only screen and (min-width: 700px) {

  /* Medium screen, non-retina */

}

@media
only screen and (-webkit-min-device-pixel-ratio: 2)      and (min-width: 700px),
only screen and (   min--moz-device-pixel-ratio: 2)      and (min-width: 700px),
only screen and (     -o-min-device-pixel-ratio: 2/1)    and (min-width: 700px),
only screen and (        min-device-pixel-ratio: 2)      and (min-width: 700px),
only screen and (                min-resolution: 192dpi) and (min-width: 700px),
only screen and (                min-resolution: 2dppx)  and (min-width: 700px) { 

  /* Medium screen, retina, stuff to override above media query */

}

@media only screen and (min-width: 1300px) {

  /* Large screen, non-retina */

}

@media
only screen and (-webkit-min-device-pixel-ratio: 2)      and (min-width: 1300px),
only screen and (   min--moz-device-pixel-ratio: 2)      and (min-width: 1300px),
only screen and (     -o-min-device-pixel-ratio: 2/1)    and (min-width: 1300px),
only screen and (        min-device-pixel-ratio: 2)      and (min-width: 1300px),
only screen and (                min-resolution: 192dpi) and (min-width: 1300px),
only screen and (                min-resolution: 2dppx)  and (min-width: 1300px) { 

  /* Large screen, retina, stuff to override above media query */

}

更新 2:

例如,以下子句处理 2017 年所有视网膜 MBP 的像素到 --inch 映射。

@media (resolution: 192dpi) and (-webkit-device-pixel-ratio: 2) {
  :root {
    --inch: 130px;
  }
}

.square {
  width: var(--inch);
  height: var(--inch);
  background: orangered;
}

其中 --inch 变量表示要测量的真实物理英寸。请注意,我们没有在媒体查询上使用 min/max 来适应此处的屏幕 dpis 范围。此映射仅适用于 MBP'17,返回的 dpi 为 192,dpr 为 2。

显然,现在可以将 css 像素映射到真实的物理英寸。这很麻烦,但可能。为此,我们需要使用 CSS custom properties 也称为 CSS 变量,如下所示:

/* 13.3-inch MBP (2012) (1280 x 800) */
@media (resolution: 96dpi) and (device-width: 1280px) {
  :root {
    --inch: 116px;
  }
}

/* 17" Retina MBP/Chrome values */
@media (resolution: 192dpi) and (device-width: 1680px) {
  :root {
    --inch: 130px;
  }
}

/* Windows 10 @100% (1366 x 768) landscape*/
@media (resolution: 96dpi) and (device-width: 1366px) {
  :root {
    --inch: 114px;
  }
}

/* Windows 10 Pro @100% (1920 x 1080px) landscape. */
@media (resolution: 96dpi) and (device-width: 1920px) {
  :root {
    --inch: 144px;
  }
}

/* Windows 10 Pro @125% (1920 x 1080px) landscape. */
@media (resolution: 120dpi) and (device-width: 1536px) {
  :root {
    --inch: 115px;
  }
}

/* 27" EIZO monitor (2560 x 1440)*/
@media (resolution: 115dpi) and (device-width: 2560px) {
  :root {
    --inch: 92px;
  }
}

/****************/
/* MOBILE ZONE */
/****************/

/* iPhone 11 Pro Max */

@media (device-width: 414px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait) {
  :root {
    --inch: 370px;
  }
}

@media (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape) {
  :root {
    --inch: 189px;
  }
}
/****************/
/* MOBILE ZONE */
/****************/

/* iPhone 11 Pro Max */

@media (device-width: 414px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait) {
  :root {
    --inch: 370px;
  }
}

@media (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape) {
  :root {
    --inch: 189px;
  }
}

/* …and so on. */

您需要针对市场上的大多数主要设备或您希望支持的设备进行特定于硬件的映射。也可以使用 dpi+设备宽度组合的 min()/max() 范围在文档的 :root 处声明一个 --inch css 变量,但这会引入略高的误差幅度。

一次,您已准备好所有映射,只需在样式表上使用 var(--inch) 进行布局,您就成功了!

我已将此解决方案转变为涵盖当今主要设备的开源 polyfill here。如果您的 device/browser 尚未包含在其中,请随意使用它并提交 PR 以添加新的 --inch:pixels 映射。