有没有一种方法可以让变宽字体在HTML中像固定宽度字体一样工作?

23
有没有办法让变宽字体在HTML中像固定宽度字体一样呈现?
例如,如果我在“Courier New”中显示句子“The quick grey fox jumped over the lazy dog”,这是一种固定宽度字体,则它的总宽度会比在变宽字体“Arial”中显示时更宽。 我想使用“Arial”而不是“Courier New”,但希望字符具有固定宽度。
可变宽度字体示例:
The quick grey fox jumped over the lazy dog.
固定宽度示例:
The quick grey fox jumped over the lazy dog
请注意,每个示例中单词“quick”和“grey”中的字符彼此相邻程度很接近。

HTML还是TLF?你想要哪一个?这两种完全不同的渲染技术需要不同的解决方案。 - RIAstar
没错。我现在开始的是一个文本列表。在这种情况下,我可以选择任何一种技术来使用。但我也可以创建一个新问题。 - 1.21 gigawatts
你似乎得到了很多HTML的答案,而我也想不出TLF的快速解决方案。因此,也许你可以根据这个来选择技术。 - RIAstar
看起来是这样。我已经为TLF创建了一个单独的问题,因为将来访问此帖子的某些人可能会对两种不同技术的答案感到困惑。 - 1.21 gigawatts
HTML方法也可以适用于TLF。我需要创建span元素,并设置每个元素的宽度和文本对齐方式。不幸的是,TLF中的HTML导入非常非常慢(TLF 2.0)。 - 1.21 gigawatts
5个回答

14

仅使用 CSS 是不行的。我建议您使用流行的 Lettering.js(需要 jQuery)来生成 span 标签,将每个字符包装在其中,然后跨所有字符设置宽度。

.monospace > span {
  display: inline-block; /* Enable widths */
  width: 1em;            /* Set width across all characters */
  text-align: center;    /* Even out spacing */
}

测试用例


我能通过在前面添加span标签来删除要求吗?body { font: 16px/1.5 Arial, sans-serif } 是做什么用的? - 1.21 gigawatts
如果您想手动将“span”标签编码到文档中,那也可以。那么您就不需要使用Lettering.js。“font”声明设置了整个文档的基本“字体大小”为16px,“行高”为1.5em(或24px),以及Arial的“字体系列”,备用为sans-serif。这是使用所有这些属性的速记方式。 - JoeJ
1
@JoeJ,我要给你点个踩,因为我无法让它正常工作,而且测试用例也不存在了。 - Eric

3

我能想到的唯一方法是将每个字母放在一个 HTML 元素中,并为该元素设置类似以下样式:

width: 8px;         /* Whatever fixed width you want here */
display: block;     /* Force the width to be respected. See also: inline-block */
float: left;        /* So it won't be 1-per-line. Not needed for inline-block */
text-align: center; /* So the character appears in the middle of the block */

我不熟悉Flex,但如果我要实现这种方法,我会编写一些Javascript代码来为我生成所有元素。


每个字符已经在自己的<span>标签中,所以我认为这可能会起作用。 :) - 1.21 gigawatts
2
这段代码实现了问题所要求的功能,但这意味着字母看起来并不像等间距分布;例如,在“World”中,前两个字母似乎比其余字母更接近。关键是要创建等宽印象,你需要一个真正的等宽字体。 - Jukka K. Korpela
@AshleyRoss 你可以使用inline-block并且去掉float。Inline block允许你在元素上设置大小,但是以行内方式显示(没有新行)。 - 1.21 gigawatts
如果字母居中并手动设置宽度,它应该看起来像等宽字体。我需要看一个例子。 - 1.21 gigawatts

1
这是一个老问题,但我建议寻找适合作为Web字体使用的等宽字体,并具备您想要的功能。例如,我非常喜欢Inconsolata。
我建议从Google Fonts开始,取消选择所有类别,只留下Monospace。

0

由于比例字体不是为此而设计的,因此结果可能不太好。

尽管如此,您可以通过在字符周围使用单独的span来实现:http://jsfiddle.net/rvYES/

body {
  font: normal 100%/1.5 Arial;
}

span {
  outline: 1px dotted darkred;
}
span:nth-of-type(even) {
  outline-color: blue;
}

.w-fixed span {
  display: inline-block;
  min-width: 1em;
}

我添加了可视化提示(轮廓线)以查看发生了什么,并使用min-width以防万一,而不是width
这种方法会对使用这些辅助技术的盲人和部分视力受损者的屏幕阅读器造成巨大的无障碍问题。字母进入单独的span中将被拼写/读出
o
n
e

b
y

o
n
e

w
h
i
l
e

a

正常

参数

作为

a

发送,

作为

平常。

漂亮的

有点烦人

啊?

双关语


1
从排版上看,结果可能会很糟糕,但屏幕阅读器没有理由拼出每个字母。(不过较差的屏幕阅读器可能会做一些奇怪的事情。) - Jukka K. Korpela
身体标签中的CSS是做什么的?我现在已经在很多地方看到它了。 - 1.21 gigawatts
@JukkaK.Korpela 如果您正在开发一个AT,当在单独的span中看到字母时,您可能有不同的行为原因,而不是在正常的句子中,尽管我没有来自现实世界的测试用例,这导致了他们做出这个决定。如果您想要为段落的第一个字母设置样式,那么至少CSS有:first-letter - FelipeAls
@1.21gigawatts font 是一堆 font-something 属性以及 line-height 的速记属性。在 font-size 中使用百分比是由于使用 em 单位(而不是像素)以及大多数 IE 版本中存在 em 单位的 bug,特别是在这个元素上 http://clagnut.com/blog/348/ (IE 对于任何其他元素中的 em 值都可以正常工作...)。/1.5 是整个文档将继承的 line-height 值(无单位)。 - FelipeAls

0

你可以尝试使用字母间距的 CSS 属性来实现你想要的效果。按照定义,等宽字体的字符宽度相同,不像衬线或无衬线字体。使用字母间距是你最好的选择W3C 参考文献


字母间距的值不就是在给定字体的默认字距上加上的吗?虽然它会增加或减少每个字母之间的间距,但并不能使间距变得均匀,对吧?但如果这满足了1.21千兆瓦的需求,那绝对比我的建议更好。 :) - Ashley Ross
我认为Ashley是正确的。我认为它会添加或减去字体字符间距表中的值。 - 1.21 gigawatts
letter-spacing 值指定字符之间添加的间距(字距是完全不同的东西),因此它根本不会使间距变得均匀。 - Jukka K. Korpela
我认为这是一个很好的点来补充,虽然它不完全是"固定宽度",但它可能有助于解决一个主要问题,即只因文本太难读而需要使用固定宽度。所以提到letter-spacing作为一个需要考虑的因素是很好的。 - Guy Park

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接