有没有办法让文本字符齐平到 HTML5 中的边界框顶部?
Is there a way to make text characters flush to the top of their bounding box in HTML5?
这是 HTML 中的一个标签元素,红色虚线轮廓显示它的边界框。请注意,字符 not 与其边界框的上边缘齐平:
line-height:1.2; /* default */
这是显示上图的 JSFiddle http://jsfiddle.net/6gLQU/16/.
这里是相同的文本,其中 line-height
样式设置为 1 或 100%(更好但仍然不齐平):
line-height:1;
最后,如果我将 line-height
样式设置为 .8 (80%),如 this code example,它是齐平的,除了最后一个测试文本中的一个小但可接受的单个像素差异.这很好,但如果有不止一行文本(多行),那么下一行会被拉得太高,因为这会使每行高度达到其实际高度的 80%。
line-height:.8;
这是 JSFiddle 代码 http://jsfiddle.net/6gLQU/16/。
(不懂Flash的可以跳过这一段)
在 Flash TLF(FTE 或 Flash 文本引擎)中,如果您添加一个文本字段,使用 FTE 或 TLF 作为它的引擎,文本字符将对齐到边界矩形的最顶部。它们看起来像最后一张图片中的文本(字符紧贴边界框的顶部边框)。
在 HTML 中,文本字符未对齐到边界矩形的顶部,如上例所示。当您增加字体大小时,您也会增加从字符顶部到边界框矩形顶部的间隙。
在我对 HTML 和 CSS 中使用的文本的研究中,字体样式 line-height
将调整文本字符在其边界框内的位置(如上图)。在 Flash 中,line-height
样式不会影响文本第一行中的字符,但会调整以下行以及 HTML 中的字符(因此它在 HTML 或 Flash 中不起作用多线)。
我已经确定,如果我在 HTML 中将行高设置为 .8 或 80%,则字体会与边界框的顶部齐平(如上所示)。伟大的!这就是我想要的,但它不适用于多行文本。如果不止一行,则下一行是 "pulled up" 并与前一行重叠,因为很明显,我只给每行提供了其实际高度的 80%。
无论如何,我的问题是:
- 有没有其他方法可以让 HTML 字符齐平到边界框的顶部?我对
line-height
使用的 hack 导致多行文本靠得太近。
- Flash TLF 中是否有设置使其行为和显示像 HTML 文本行?也就是说,使其不会将文本字符拉到边界框的顶部(匹配 HTML 布局规则)。
我找到了一个使用负边距的替代方案 space 但我必须手动输入它。这并不理想,因为它对每种字体大小都有不同的值(通过反复试验发现)并且它会向上移动文本框,而不是字符。通过 line-height
hack,我可以使用 .8
并且我知道它会被正确定位。
这是一张 link to the code 和使用负边距的图片。我只将它应用到最后一个元素。注意红色边框:
font-size:64px;
line-height:1.2;
margin-top:-14px;
这里 another test and another using multiples of 12 使用负保证金百分比。同样,每个负边距值都是不同的,并且是通过反复试验发现的:
font-size:12px;
line-height:1.2;
margin-top:-.19%;
这是关于 FTE engine 的信息。我读了一个小时,现在我意识到我知道其中的几个词。
PS 抱歉这个问题太长了。显然,我正在努力赢得最长的 post 奖项。此外,我添加了 两个 问题,因为存在实际问题,然后是如果实际问题可以解决则可能没有必要的解决方法问题。我不确定这叫什么,但有人告诉我这是关于 SO 的编程问题的常见问题。此外,添加 Firefox 标记,因为它在 Firefox 中是 运行,并且 Firefox 开发人员之一可能会看到它并知道这一切是如何工作的。
2019 年更新:
我在某处有另一个问题 posted 关于这个问题,但公认的修复适用于特定字体,但不适用于所有字体。
IIUC 文本字符的上边缘称为字形,称为大写高度,字形周围容器的高度称为 em 高度。每种字体的大写高度都不同,因为字体具有不同的样式并且由不同的作者创建。
IIUC 浏览器不根据 em 或字体大小定位,并且不考虑大写高度。
我对浏览器提出的 功能请求 是支持将段落或标签文本的第一行对齐到大写高度,以便文本齐平到顶部边缘。那可能是负文本边距。这将使浏览器准确地重现许多设计工具所支持的内容。
// something like any of these:
align-caps-height: true;
first-line-position: caps-height;
margin-top: caps-height;
这里的字体间距不是问题,因为文本会均匀缩放。问题是由保证金百分比造成的。边距百分比计算为 宽度 的百分比。因此,正如您所料,保证金百分比与
之间没有关系
方法一
您可以做的是,找出一个块的边距(以像素为单位)。然后让 k = font_size/ margin
代表该块。将 font-size
除以 k
得到其他块的余量。
方法二
尝试使用 transform: translate;
和 em 值,而不是使用百分比保证金:
相关代码
label { /* added properties*/
transform: translateY(-0.2em);
}
方法三
我意识到,虽然有点晚,但 transform
不是必需的。您可以简单地使用 margin-top: -0.2em;
相关代码
label { /* added properties*/
margin-top: -0.2em;
}
#BorderContainer1711 {
position:absolute;
left:32px;
top:60px;
width:500px;
height:160px;
background-color:#FFFFFF;
background-alpha:1;
border-width:1px;
border-style:solid;
border-color:#00DD00;
color:#000000;
}
label { /* added properties*/
margin-top: -0.2em;
}
#Label1551 {
position:absolute;
left:46px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:12px;
}
#Label1613 {
position:absolute;
left:123px;
top:60px;
width:61px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:24px;
}
#Label937 {
position:absolute;
left:220px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:36px;
}
#Label2125 {
position:absolute;
left:342px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:64px;
}
*, *:before, *:after {
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
*, *:before, *:after {
outline:1px dotted red;
}
<div id="BorderContainer1711">
</div>
<label id="Label1551">[12px]</label>
<label id="Label1613">[24px]</label>
<label id="Label937">[36px]</label>
<label id="Label2125">[64px]<br>nextline</label>
这是 HTML 中的一个标签元素,红色虚线轮廓显示它的边界框。请注意,字符 not 与其边界框的上边缘齐平:
line-height:1.2; /* default */
这是显示上图的 JSFiddle http://jsfiddle.net/6gLQU/16/.
这里是相同的文本,其中 line-height
样式设置为 1 或 100%(更好但仍然不齐平):
line-height:1;
最后,如果我将 line-height
样式设置为 .8 (80%),如 this code example,它是齐平的,除了最后一个测试文本中的一个小但可接受的单个像素差异.这很好,但如果有不止一行文本(多行),那么下一行会被拉得太高,因为这会使每行高度达到其实际高度的 80%。
line-height:.8;
这是 JSFiddle 代码 http://jsfiddle.net/6gLQU/16/。
(不懂Flash的可以跳过这一段) 在 Flash TLF(FTE 或 Flash 文本引擎)中,如果您添加一个文本字段,使用 FTE 或 TLF 作为它的引擎,文本字符将对齐到边界矩形的最顶部。它们看起来像最后一张图片中的文本(字符紧贴边界框的顶部边框)。
在 HTML 中,文本字符未对齐到边界矩形的顶部,如上例所示。当您增加字体大小时,您也会增加从字符顶部到边界框矩形顶部的间隙。
在我对 HTML 和 CSS 中使用的文本的研究中,字体样式 line-height
将调整文本字符在其边界框内的位置(如上图)。在 Flash 中,line-height
样式不会影响文本第一行中的字符,但会调整以下行以及 HTML 中的字符(因此它在 HTML 或 Flash 中不起作用多线)。
我已经确定,如果我在 HTML 中将行高设置为 .8 或 80%,则字体会与边界框的顶部齐平(如上所示)。伟大的!这就是我想要的,但它不适用于多行文本。如果不止一行,则下一行是 "pulled up" 并与前一行重叠,因为很明显,我只给每行提供了其实际高度的 80%。
无论如何,我的问题是:
- 有没有其他方法可以让 HTML 字符齐平到边界框的顶部?我对
line-height
使用的 hack 导致多行文本靠得太近。 - Flash TLF 中是否有设置使其行为和显示像 HTML 文本行?也就是说,使其不会将文本字符拉到边界框的顶部(匹配 HTML 布局规则)。
我找到了一个使用负边距的替代方案 space 但我必须手动输入它。这并不理想,因为它对每种字体大小都有不同的值(通过反复试验发现)并且它会向上移动文本框,而不是字符。通过 line-height
hack,我可以使用 .8
并且我知道它会被正确定位。
这是一张 link to the code 和使用负边距的图片。我只将它应用到最后一个元素。注意红色边框:
font-size:64px;
line-height:1.2;
margin-top:-14px;
这里 another test and another using multiples of 12 使用负保证金百分比。同样,每个负边距值都是不同的,并且是通过反复试验发现的:
font-size:12px;
line-height:1.2;
margin-top:-.19%;
这是关于 FTE engine 的信息。我读了一个小时,现在我意识到我知道其中的几个词。
PS 抱歉这个问题太长了。显然,我正在努力赢得最长的 post 奖项。此外,我添加了 两个 问题,因为存在实际问题,然后是如果实际问题可以解决则可能没有必要的解决方法问题。我不确定这叫什么,但有人告诉我这是关于 SO 的编程问题的常见问题。此外,添加 Firefox 标记,因为它在 Firefox 中是 运行,并且 Firefox 开发人员之一可能会看到它并知道这一切是如何工作的。
2019 年更新:
我在某处有另一个问题 posted 关于这个问题,但公认的修复适用于特定字体,但不适用于所有字体。
IIUC 文本字符的上边缘称为字形,称为大写高度,字形周围容器的高度称为 em 高度。每种字体的大写高度都不同,因为字体具有不同的样式并且由不同的作者创建。
IIUC 浏览器不根据 em 或字体大小定位,并且不考虑大写高度。
我对浏览器提出的 功能请求 是支持将段落或标签文本的第一行对齐到大写高度,以便文本齐平到顶部边缘。那可能是负文本边距。这将使浏览器准确地重现许多设计工具所支持的内容。
// something like any of these:
align-caps-height: true;
first-line-position: caps-height;
margin-top: caps-height;
这里的字体间距不是问题,因为文本会均匀缩放。问题是由保证金百分比造成的。边距百分比计算为 宽度 的百分比。因此,正如您所料,保证金百分比与
之间没有关系方法一
您可以做的是,找出一个块的边距(以像素为单位)。然后让 k = font_size/ margin
代表该块。将 font-size
除以 k
得到其他块的余量。
方法二
尝试使用 transform: translate;
和 em 值,而不是使用百分比保证金:
相关代码
label { /* added properties*/
transform: translateY(-0.2em);
}
方法三
我意识到,虽然有点晚,但 transform
不是必需的。您可以简单地使用 margin-top: -0.2em;
相关代码
label { /* added properties*/
margin-top: -0.2em;
}
#BorderContainer1711 {
position:absolute;
left:32px;
top:60px;
width:500px;
height:160px;
background-color:#FFFFFF;
background-alpha:1;
border-width:1px;
border-style:solid;
border-color:#00DD00;
color:#000000;
}
label { /* added properties*/
margin-top: -0.2em;
}
#Label1551 {
position:absolute;
left:46px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:12px;
}
#Label1613 {
position:absolute;
left:123px;
top:60px;
width:61px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:24px;
}
#Label937 {
position:absolute;
left:220px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:36px;
}
#Label2125 {
position:absolute;
left:342px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:64px;
}
*, *:before, *:after {
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
*, *:before, *:after {
outline:1px dotted red;
}
<div id="BorderContainer1711">
</div>
<label id="Label1551">[12px]</label>
<label id="Label1613">[24px]</label>
<label id="Label937">[36px]</label>
<label id="Label2125">[64px]<br>nextline</label>