CSS行高问题-无法获得确切的行数

问题描述

在这个问题上发现了一篇更老的文章,但是对于很多人来说,最流行的答案还是其他答案都没有用。多年以后,包括我在内。

我正在尝试使div高度恰好为19行(最终我的行距为19.5行,所以当有更多文本要滚动到时,您总是会看到恰好一半行,但是我我先尝试19个。)但是,当我调整浏览器窗口的大小时,我看到了各种不同程度的文本多余:正是我要避免的问题。下面显示了大约19行和大约一半的行:

screenshot

这是我正在使用的CSS,用于上面显示的外部div和内部较暗的div

#marquee-dialog > div {
  font-size: 3vh;
  line-height: 3.6vh;
  position: absolute;
  margin: auto;
  top: 0; left: 0; bottom: 0; right: 0;
  width: 80vw;
  height: 80vh;
  padding: 1em;
  background-color: white; /* Changed via JavaScript later */
  color: black;
}

#marquee-big-text {
  font-size: 3vh;
  line-height: 3.6vh;
  max-height: 22.8em;
  overflow: auto;
}

我将行高设置为字体大小的1.2倍,将max-height设置为19 * 1.2 = 22.8 em。 (我也尝试了68.4vh,并与height一起设置了max-height,或者没有设置div,这没什么区别。)当然,它应该出现在19行中在浮点精度允许的范围内。

当我检查Web控制台时,em的高度精确地或几乎精确地显示为行高的19倍,几乎精确地是div大小的22.8倍,我可以检查它的高度通过检查外部div的填充大小。

内部#marquee-big-text { font-size: 3vh; line-height: 31.968px; /* 3.6vh; */ max-height: 607.392px; /* 22.8em; */ overflow: auto; } 的填充为0,边距为0,边框为0,可将数字丢弃。

从我看到的所有数值中,我得到19行。但是渲染仍然只是渲染更多一点。多余的出现在Chrome,Firefox和Safari中。

我肯定想念一些明显的东西吗?

更新

我尝试了此操作,并从Web控制台获取了准确的像素值:

div

即使这是19行的精确值,我仍然遇到相同的问题。

更新2

我对屏幕截图进行了一些测量。根据从基线到基线的测量,每个呈现的文本行 高62像素。整个{{1}}高1212像素。通过这些测量,大约19.55条线应适合该空间,并解释了我所看到的。为了使某条线更精确地接近19条线,基线到基线的测量值应约为63.79像素,每条线要多出近2像素。

这几乎就像呈现舍入错误,但是很好奇,如果舍入,则舍入在浏览器之间是一致的。

更新3

这是一个可行的示例:

https://codepen.io/kshetline/pen/NWNGOWL

有趣的是,在这个简化的示例中,Chrome和Safari仍然出现了问题,但是Firefox总是能够正确解决问题。

您可能必须将Codepen视图切换为此方向:

codepen screenshot

...看问题。该错误只会以相当大的字体大小出现,并且当我调整浏览器窗口的大小时,多余的内容在恢复到19行之前不会超过半行。

这越来越像是字体大小的舍入错误。我猜这与渲染优化有关,避免了缓存字体大小差异太多的大字体位图。

解决方法

这不是我想要的答案,但是我可以使用JavaScript来解决问题。看来我不得不强迫使用整数像素大小来可靠地进行确切的行数计算。

const middiv = document.querySelector('.outer > div');
const inner = document.querySelector('.inner');
let lastLineHeight = 0;

function checkFont() {
  const style = document.defaultView.getComputedStyle(middiv,null);
  const exactHeight = parseFloat(style.getPropertyValue('line-height'));
  const roundedHeight = Math.floor(exactHeight);

  if (lastLineHeight !== roundedHeight) {
    inner.style.lineHeight = roundedHeight + 'px';
    inner.style.maxHeight = (roundedHeight * 19) + 'px';
    lastLineHeight = roundedHeight;
  }
}

window.addEventListener('resize',checkFont);
checkFont();

以下是一个Codepen演示的示例:https://codepen.io/kshetline/pen/vYGLjBo