CSS 行高问题 - 无法获得准确的行数
CSS line height problem - Can't get an exact number of lines
我找到了关于这个主题的更早的 post,但对于很多人来说,最受欢迎的答案和其他任何答案都没有用。多年以后,那也包括我。
我正在尝试使 div
恰好 19 行高(最终我将达到 19.5 行,因此当有更多文本要滚动到时,您总是会看到恰好半行,但是我首先尝试 19。)当我调整我的浏览器 window 大小时,我看到了文本的各种小数部分:这正是我试图防止的问题。下面,显示大约 19 和大约半行:
这是我正在使用的 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
一起,或代替 max-height
,但没有任何区别。)这看起来确实应该出现 19 行,正如在浮点精度允许的情况下。
当我检查 web 控制台时,div
的高度正好或几乎正好是行高的 19 倍,几乎正好是 em
大小的 22.8 倍,我可以通过检查外div
.
的填充大小来检查
内部 div
有 0 个内边距、0 个边距和 0 个边框,以消除数字。
根据我看到的所有数值,我得到了 19 行。但是渲染仍然渲染了一点。超出部分出现在 Chrome、Firefox 和 Safari 中。
我一定是遗漏了什么明显的东西?
更新
我试过了,使用从网络控制台获取的精确像素值:
#marquee-big-text {
font-size: 3vh;
line-height: 31.968px; /* 3.6vh; */
max-height: 607.392px; /* 22.8em; */
overflow: auto;
}
我仍然遇到同样的问题,尽管这些是 19 行的接近精确值。
更新 2
我从屏幕截图中取了一些尺寸。基于从基线到基线的测量,呈现的每个文本行 为 62 像素高。整个 div
是 1212 像素高。根据这些测量值,大约 19.55 行应该适合 space,这解释了我所看到的。如果要接近 19 行,基线到基线的测量值应该约为 63.79 像素,每行几乎多 2 个像素。
这看起来几乎像是渲染舍入误差,但奇怪的是,如果它是舍入的,那么浏览器与浏览器之间的舍入是一致的。
更新 3
这是一个工作示例:
https://codepen.io/kshetline/pen/NWNGOWL
有趣的是,在这个简化的示例中,问题仍然出现在 Chrome 和 Safari 中,但 Firefox 总能解决问题。
您可能需要将 Codepen 视图切换到这个方向:
...看到问题了。该错误仅在相当大的字体大小时出现,并且当我调整浏览器的大小时 window 在快速回到 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
我找到了关于这个主题的更早的 post,但对于很多人来说,最受欢迎的答案和其他任何答案都没有用。多年以后,那也包括我。
我正在尝试使 div
恰好 19 行高(最终我将达到 19.5 行,因此当有更多文本要滚动到时,您总是会看到恰好半行,但是我首先尝试 19。)当我调整我的浏览器 window 大小时,我看到了文本的各种小数部分:这正是我试图防止的问题。下面,显示大约 19 和大约半行:
这是我正在使用的 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
一起,或代替 max-height
,但没有任何区别。)这看起来确实应该出现 19 行,正如在浮点精度允许的情况下。
当我检查 web 控制台时,div
的高度正好或几乎正好是行高的 19 倍,几乎正好是 em
大小的 22.8 倍,我可以通过检查外div
.
内部 div
有 0 个内边距、0 个边距和 0 个边框,以消除数字。
根据我看到的所有数值,我得到了 19 行。但是渲染仍然渲染了一点。超出部分出现在 Chrome、Firefox 和 Safari 中。
我一定是遗漏了什么明显的东西?
更新
我试过了,使用从网络控制台获取的精确像素值:
#marquee-big-text {
font-size: 3vh;
line-height: 31.968px; /* 3.6vh; */
max-height: 607.392px; /* 22.8em; */
overflow: auto;
}
我仍然遇到同样的问题,尽管这些是 19 行的接近精确值。
更新 2
我从屏幕截图中取了一些尺寸。基于从基线到基线的测量,呈现的每个文本行 为 62 像素高。整个 div
是 1212 像素高。根据这些测量值,大约 19.55 行应该适合 space,这解释了我所看到的。如果要接近 19 行,基线到基线的测量值应该约为 63.79 像素,每行几乎多 2 个像素。
这看起来几乎像是渲染舍入误差,但奇怪的是,如果它是舍入的,那么浏览器与浏览器之间的舍入是一致的。
更新 3
这是一个工作示例:
https://codepen.io/kshetline/pen/NWNGOWL
有趣的是,在这个简化的示例中,问题仍然出现在 Chrome 和 Safari 中,但 Firefox 总能解决问题。
您可能需要将 Codepen 视图切换到这个方向:
...看到问题了。该错误仅在相当大的字体大小时出现,并且当我调整浏览器的大小时 window 在快速回到 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