简体   繁体   English

当用作等宽字体时,使用非等宽字体的替换字符以正确的宽度显示

[英]Make replacement characters from non-monospace fonts appear with correct width when used as monospace font

Web browsers replace a missing character in a font (usually an arrow, a graphical symbol and in my particular use-case the unicode character "≫" (U+226B)) with the character from another font. Web浏览器用另一种字体中的字符替换字体中的缺失字符(通常是箭头,图形符号和我的特定用例中的unicode字符“»”(U + 226B))。 If you are using a monospace-font, the replacement character comes (most of the time) from a proportional font and will mess up the strict grid-pattern that is in many cases desired when monospace fonts are used. 如果您使用的是等宽字体,则替换字符(大部分时间)来自比例字体,并且会破坏严格的网格图案,在使用等宽字体时,在很多情况下都会这样。

For example, in my browser this is messed up: 例如,在我的浏览器中,这搞砸了:

 <pre> 012345 1 | a | Ö | % | ≫ | 2 | b | X | & | </pre> 

The pipe-symbol after "≫" does not align with the others (at with the fonts that are installed on my machine). “»”之后的管道符号与其他符号不对齐(与我的机器上安装的字体对齐)。

Is there a way to make sure that the browser scales the replacement character to the correct width? 有没有办法确保浏览器将替换字符缩放到正确的宽度?

A JavaScript solution would be also fine if necessary. 如有必要,JavaScript解决方案也可以。

This is at the very best only a partial answer, but perhaps it will be helpful to some folks. 这是最好的只是部分答案,但也许它会对一些人有所帮助。 In your CSS font stack, you can include a mono-spaced font that does have good unicode coverage. 在CSS字体堆栈中,您可以包含具有良好unicode覆盖率的单倍间距字体。 For example, Courier New in OS X includes over 1200 glyphs which I'm guessing includes most of the useful unicode characters. 例如,OS X中的Courier New包含超过1200个字形,我猜这些字形包括大多数有用的unicode字符。 If you list it after your primary font in your font stack, you'd at least have a consistent width for those characters absent from your primary font. 如果您在字体堆栈中的主要字体之后列出它,那么对于主要字体中缺少的字符,您至少应该具有一致的宽度。

Of course, that doesn't really solve the problem if the width of the primary font differs from the width of the backup. 当然,如果主字体的宽度与备份的宽度不同,那么这并不能真正解决问题。 If you're lucky, you may be able to find a backup font with the same width that has sufficient unicode coverage, in which case you can use it as is. 如果幸运的话,您可以找到具有足够unicode覆盖范围的相同宽度的备份字体,在这种情况下,您可以按原样使用它。 Otherwise, I think you're out of simple solutions. 否则,我认为你没有简单的解决方案。 In that case I can think of a couple of alternatives. 在那种情况下,我可以想到几个替代方案。

  1. If the license permits it, you could modify the width of a backup font so that it matches your primary font. 如果许可证允许,您可以修改备份字体的宽度,使其与主要字体匹配。
  2. If you know in advance which unicode characters you want to display, you could wrap them in a <span> tag and adjust the styles to match the primary font's width. 如果您事先知道要显示哪个unicode字符,可以将它们包装在<span>标记中并调整样式以匹配主要字体的宽度。

Not an easy solution in any case I'm afraid. 在任何情况下我都不是一个简单的解决方案。

PS You might want to edit your title. PS您可能想要编辑您的标题。 I think you mean "mono-spaced" as "monotype" is a type foundry. 我认为你的意思是“单声道”,因为“monotype”是一种类型的代工厂。

How hardcore are you willing to be? 你愿意做多少铁杆?
Here's a code that wraps every letter of a text in a span with a given width: 这是一个包含给定宽度的跨度中文本的每个字母的代码:

var container = document.getElementsByClassName('mymonotext');
if (!container.length) {
    throw new Error('.mymonotext is not found');
}

container = container[0];
container.normalize(); //Merge all the adjacent text nodes inside a container (see https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize)

var currentNode = container.firstChild;
for (var i = 0, len = currentNode.textContent.length; i < len - 1; i++) {  
    var range = new Range(); //Create a range

    //Insert a first char into a range
    range.setStart(currentNode, 0); 
    range.setEnd(currentNode, 1);

    var wrapper = document.createElement('span');
    wrapper.className = 'letter';

    //Wrap the range with a span tag
    wrapper.appendChild(range.extractContents())
    range.insertNode(wrapper);

    //Detach the previous range and shift current node
    range.detach();
    currentNode = currentNode.nextSibling.nextSibling;
}

Styles for the wrapper tag: 包装标签的样式:

.letter {
    width: .5rem;
    display: inline-block;
    overflow: hidden;
}

Same thing on jsfiddle: http://jsfiddle.net/enwyoy4y/ 同样的事情在jsfiddle: http//jsfiddle.net/enwyoy4y/
(use at your own risk, yada-yada, does not supports IE8 and such). (使用风险自负,yada-yada,不支持IE8等)。

The advance width of characters in a monospace font is fixed for a specific font but may be different for different monospace fonts. 等宽字体中字符的前进宽度对于特定字体是固定的,但对于不同的等宽字体可能是不同的。 If you limit yourself to using a particular monospace font (on web pages, this is meaningful only when using @font-face , since there is no monospace font that is available in all computers), you can find out its advance width (eg using a font inspector program, or with some testing) and then scale an element to that width. 如果你限制使用特定的等宽字体(在网页上,这只有在使用@font-face时才有意义,因为所有计算机都没有可用的等宽字体),你可以找出它的前进宽度(例如使用字体检查程序,或一些测试)然后将元素缩放到该宽度。

However, you cannot make font size depend on an element's width, except with some JavaScript programming, so it is simplest to use an image, if your problem is just one character. 但是,除了使用一些JavaScript编程之外,您不能使字体大小取决于元素的宽度,因此如果您的问题只是一个字符,则最简单的方法是使用图像。 Write the character in some font in large size, take a screenshot, and then scale the image using an img element for which you set the width only. 以大尺寸的某种字体写入字符,截取屏幕截图,然后使用仅为其设置宽度的img元素缩放图像。 Alternatively you could create the image in just the right size, but this would be less flexible if you later change the font (so that the width may change too). 或者,您可以使用恰当的大小创建图像,但如果稍后更改字体(这样宽度也可能会更改),这将不太灵活。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM