有没有办法让文本字符在 HTML5 中刷新到其边界框的顶部?

Posted

技术标签:

【中文标题】有没有办法让文本字符在 HTML5 中刷新到其边界框的顶部?【英文标题】:Is there a way to make text characters flush to the top of their bounding box in HTML5? 【发布时间】:2016-05-01 05:38:55 【问题描述】:

这是 html 中的 Label 元素,红色虚线轮廓显示它的边界框。请注意,字符与其边界框的上边缘齐平:

line-height:1.2; /* default */

这是显示上面图片的 JSFiddle http://jsfiddle.net/6gLQU/16/。

这里是line-height 样式设置为 1 或 100% 的相同文本(更好但仍不刷新):

line-height:1;

最后,如果我将 line-height 样式设置为 0.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 中将 line-height 设置为 0.8 或 80%,字体会与边界框的顶部齐平(如上所示)。伟大的!这就是我想要的,但它不适用于多行文本。如果有多条线,则下一条线被“拉起”并与前一条线重叠,因为很明显,我只给每条线的实际高度的 80%。


无论如何,我的问题是:

    是否可以使用另一种方法使 HTML 字符与边界框顶部齐平?我与line-height 一起使用的hack 导致多行文本靠得太近。 Flash TLF 中是否有设置使其行为和外观像 HTML 文本行?也就是说,让它不会将文本字符拉到边界框的顶部(匹配 HTML 布局规则)。

我找到了一个使用负边距空间的替代方案,但我必须手动输入它。这并不理想,因为它是每个字体大小的不同值(通过反复试验发现)并且它向上移动文本框,而不是字符。通过line-height hack,我可以使用.8,而且我知道它的位置会正确。

这是link to the code 和使用负边距的图片。我只将它应用于最后一个元素。注意红色边框:

font-size:64px;
line-height:1.2;
margin-top:-14px;

这里是 another test 和 another using multiples of 12 使用负边距百分比。同样,每个负边距值都是不同的,并且是通过反复试验找到的:

font-size:12px;
line-height:1.2;
margin-top:-.19%;

这里是FTE engine 的信息。我读了一个小时,现在我意识到我知道其中的一些词。

PS 抱歉,这个问题太长了。显然,我正在努力赢得最长的职位奖。另外,我添加了 两个 问题,因为存在实际问题,如果实际问题可解决,则可能不需要解决方法问题。我不确定这叫什么,但有人告诉我这是关于 SO 的编程问题的常见问题。此外,添加 Firefox 标签,因为它在 Firefox 中运行,并且其中一位 Firefox 开发人员可能会看到它并知道这一切是如何工作的。

2019 年更新: 我在某处发布了另一个关于此的问题,但接受的修复适用于特定字体,但不适用于每种字体。

IIUC 文本字符的上边缘,称为字形,称为大写高度,字形周围的容器高度称为 em 高度。每种字体的大写高度都不同,因为字体是不同的样式并且由不同的作者创建。

IIUC 浏览器不根据 em 或字体大小定位,不考虑大写高度。

我对浏览器的功能请求将支持将段落文本的第一行或标签的第一行对齐到大写高度,以便文本与顶部边缘齐平。这可能是负文本边距。这将使浏览器准确地再现许多设计工具所支持的内容。

// something like any of these: 
align-caps-height: true;  
first-line-position: caps-height;
margin-top: caps-height;

【问题讨论】:

这不是预期的行为吗?实际的字形在它们周围包含空间,因为它们基于旧的金属/木制类型块。否则,字符或行之间的间距为零的文本看起来会很奇怪......不是吗? 在这种情况下这是有道理的,但在设计工具中,边界框定义了字形的边界。字形远低于其边界是没有意义的。想象一下,如果您在 Photoshop 中使用文本工具,并且文本距离边界顶部 14 像素。你会认为有些东西坏了 但这不是图像或设计工具..它是一个网页..字形有间距。 我只能建议您对排版进行更多研究。间距是内置的。 【参考方案1】:

字体间距不是这里的问题,因为文本会均匀缩放。问题是由百分比的边距造成的。百分比边距计算为 宽度 的百分比。因此,正如您所料,百分比边距和

之间没有关系

方法一

您可以做的是,以像素为单位找到一个块的边距。然后让k = font_size/ margin 用于该块。将font-size 除以k 以获得其他块的边距。


方法二

不要使用百分比边距,而是尝试使用 transform: translate; 使用 em 值:

相关代码

label  /* added properties*/
  transform: translateY(-0.2em);

Updated Fiddle 1


方法三

虽然有点晚了,但我意识到 transform 不是必需的。你可以简单地使用margin-top: -0.2em;

相关代码

label  /* added properties*/
  margin-top: -0.2em;

Updated Fiddle 2

#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>

【讨论】:

以上是关于有没有办法让文本字符在 HTML5 中刷新到其边界框的顶部?的主要内容,如果未能解决你的问题,请参考以下文章

在页面上使用文本字符串搜索功能,有没有办法让搜索忽略特定的 div?

有没有办法让 CSS 边距通过字段集边界折叠?

如何让 ListBox 刷新其项目文本?

有没有办法以编程方式在 TextView 中选择文本?

有没有办法让 HTML5 视频全屏显示?

HLS 流 HTML5 视频 - 缓冲 X 时间后刷新