无法在打印和屏幕之间获得一致的字体大小

Cannot get consistent font sizes between print and screen

我作品的标准演示格式是 Google 比例为 16:9 的幻灯片,宽度设置为 10 英寸。但我讨厌手动输入绘图等,所以最初使用 Beamer 模仿它,但现在我尝试使用 xaringan 来获得所有现代 html 功能。

我的问题是在屏幕上显示演示文稿和打印它们之间无法轻易获得字体大小的任何一致性。详细说明。假设我在 Google 幻灯片中有一些设计为 12pt (16px) 的文本。当我在演示模式下显示时测量文本的大小时,这与下载为 pdf 的相同文本的大小一致(然后放入演示模式 - 使用 Sumatra)。好吧,我知道这是一件很奇怪的事情,但它强调了 Google 幻灯片必须做很多背景工作才能使它们保持一致 - 事实上我无法获得与 [=12= 相同的一致性] 是——也许——突出了一个问题。也许 - 我认为实际上它可能更正确,因为我假设它正在调整我的显示器的尺寸/分辨率(14 英寸,1920 x 1080)。

无论如何。如果我在 xaringan 中使用下面的示例代码执行相同操作,那么(前提是我添加了 css @page 代码以强制 pdf 打印为正确的物理尺寸)然后结果 pdf 中的字体大小与 Google 生成的 pdf 中的字体大小匹配。伟大的!这里的一切都是一致的,我可以像打印 Google 幻灯片一样打印我的 xaringan 幻灯片 - 例如与直接拒绝使用 Google 并且只想通过电子邮件发送 pdf 的客户共享。我知道。

我的问题是,在全屏模式下查看 xaringan html 幻灯片时,字体大小仅为“正确”pdf 大小的 75% 左右。这是一个问题,因为 - 好吧,我可以把字体大小调大一点,这样在屏幕上显示就相当于 Google 幻灯片 - 但是 pdf 中的字体都太大了。因此,没有简单的方法可以使我可以使用相同的 .Rmd 文件以 pdf 格式在线呈现和发送,所有字体大小看起来都像我一直使用 Google 一样(除非我只提供 pdf,但也可以恢复为 Beamer)。

我想这一切的原因是在后台处理字体大小的某种方式,但也许这是一个错误?如果没有,有没有办法在屏幕和 pdf 之间强制使用这种一致的字体大小?

tl;dr Google 幻灯片在屏幕和 pdf 上查看时的字体大小似乎一致 - 但 xaringan 似乎不一致。

这是一个示例 Rmd。您可以看到生成的 pdf(在演示模式下查看时)的字体大小明显大于演示模式下的 html 文件。在 Google 幻灯片中,这些字体的大小都相同。我使用 xaringanthemer 是为了方便。

---
title: "Presentation Ninja"
subtitle: "⚔<br/>with xaringan"
author: "Yihui Xie"
institute: "RStudio, PBC"
date: "2016/12/12 (updated: `r Sys.Date()`)"
output:
  xaringan::moon_reader:
    nature:
      ratio: "16:9"
      highlightStyle: github
      highlightLines: true
      countIncrementalSlides: false
    seal: false
knit: pagedown::chrome_print
---

```{css, echo = FALSE}
@page {
  size: 10in 5.625in; # makes sure pdf comes out same size as Google Slides pdf
}
```

```{r setup, include=FALSE}
options(htmltools.dir.version = FALSE)
library(xaringanthemer)
style_mono_light(
  base_font_size = "16px",
  header_h1_font_size = "1.5rem"
)
```


# Hello World

Install the **xaringan** package from [Github](https://github.com/yihui/xaringan):

哦,我也在代码块中尝试了这个 CSS,但是虽然它确实修复了 html 幻灯片的大小,但是当进入全屏模式时,同样的问题出现了:

.remark-container {
    height: 540px!important;
    width: 960px!important;
}

好吧,所以这里有一个问题 - 虽然我仍然不完全满意,但我理解为什么 xaringan 这样做。我实际上认为这与 remark.js 本身以及它似乎处理全屏的方式有关 - 或者可能是浏览器的方式(问题在我尝试过的所有方面都很明显) - 因为它似乎是为了也是“正常”remark.js 演示文稿。

反正很简单,如果在屏幕上查看时使用@media规则修改字体大小。有多种方法可以做到这一点,具体取决于您希望缩放的“自动化”程度。重要的一点是确保您只在任何 non-relative 单位中设置基本 html 字体大小,并使用 rem 定义与此相关的所有其他内容 - 这样其他所有内容都会适当缩放。否则你将不得不手动更改其他所有内容,例如所有 h1 等等

前两种方法看起来是等同的,但我对这一切都是新手,所以也许不是,要么直接重置 html 字体:

```{css, echo = FALSE}
@page {
  size: 10in 5.625in; # makes sure pdf comes out right size
}
@media only screen {
  html {
    font-size: 22px;
  }
}
```

或使用以下方法重置 base-font-size 变量:

```{css, echo = FALSE}
@page {
  size: 10in 5.625in; # makes sure pdf comes out right size
}
@media only screen {
  :root {
    --base-font-size: 22px;
  }
}
```

这将被现有的 html 字体大小调用自动使用(假设您使用的是 xaringanthemer - 如果没有,应该不难适当调整)。

实际上,您可以做得更好,让所有内容自动缩放,包括基本 html 字体,无论您手动设置什么,如果您这样做:

```{css, echo = FALSE}
@page {
  size: 10in 5.625in; # makes sure pdf comes out right size
}
@media only screen {
  html {
    font-size: calc(1.23 * var(--base-font-size));
  }
}
```

这样,如果您在 xaringanthemer 中更改 base_font_size 选项,则无需手动更改任何其他内容(使用前两种方法,您必须进入并增加相应的字体大小)。

我正在使用 1.23 因为它在我的屏幕上对我有用 - 但是,因为我不明白为什么字体表现不一致,我真的不确定这是一个可靠的解决方案跨越不同的屏幕。事实上,我敢打赌它不是。我的 CSS 和 JS 基本上是 non-existent 所以请随意提出更好的解决方案 - 我偷偷怀疑你可以比我更有针对性地使用 @media

显然,为了更整洁,您可能希望将以上内容放在 .css 文件中,而不是放在 .Rmd 顶部的代码块中。

编辑:似乎 1.23 接近于幻灯片的“实际”物理尺寸 Google 幻灯片定义 (10" x 5.625") 与我的显示器的物理尺寸 (14.1") 之间的比率 - 所以假设这就是原因。但必须检查多个不同的显示尺寸才能确认。

编辑 2:

更新。我对整个屏幕尺寸与打印输出尺寸的比例有点切线。在我的例子中,用于字体的正确缩放大小是 1.2611,如:

@media only screen {
  html {
    font-size: calc(1.2611 * var(--base-font-size)); 
  }

只有当我开始检查巨大的字体时,我才能分辨出不同。

原因是,在深入挖掘 remark.js 源代码后,它设置了参考 4:3 幻灯片尺寸 908 x 681(在 scaler.js 中)- 然后根据当前显示设备(或打印页面)的宽度调整缩放比例。但它从不相应地更正高度,这会导致字体缩放不一致。

在我的例子中,我的幻灯片被定义为 960 x 540,所以我需要将字体大小(加上任何其他具有可变高度的对象 - 例如 hr)更正为 681/540,然后所有内容都一致地缩放。