假设我的页面中有以下CSS规则:
body {
font-family: Calibri, Trebuchet MS, Helvetica, sans-serif;
}
如何检测用户浏览器中使用了哪种定义的字体?
编辑让人不知道为什么要这样做的人:我检测到的字体包含其他字体不可用的字形,并且当用户没有该字体时,我要显示一个链接,要求用户下载该字体,以便他们可以以正确的字体使用我的Web应用程序。
当前,我正在为所有用户显示下载字体链接,我只想为未安装正确字体的用户显示此字体。
假设我的页面中有以下CSS规则:
body {
font-family: Calibri, Trebuchet MS, Helvetica, sans-serif;
}
如何检测用户浏览器中使用了哪种定义的字体?
编辑让人不知道为什么要这样做的人:我检测到的字体包含其他字体不可用的字形,并且当用户没有该字体时,我要显示一个链接,要求用户下载该字体,以便他们可以以正确的字体使用我的Web应用程序。
当前,我正在为所有用户显示下载字体链接,我只想为未安装正确字体的用户显示此字体。
Answers:
我已经看到它以一种不稳定但相当可靠的方式完成了。基本上,将元素设置为使用特定字体,并为该元素设置字符串。如果为元素设置的字体不存在,则采用父元素的字体。因此,他们要做的是测量渲染字符串的宽度。如果它与所需字体(与派生字体相反)相符,则表示存在。这不适用于等宽字体。
我写了一个简单的JavaScript工具,您可以用它来检查是否安装了字体。
它使用简单的技术,并且在大多数情况下应该是正确的。
@pat实际上,Safari不会提供所使用的字体,至少我认为,无论是否安装了Safari,Safari始终会返回堆栈中的第一个字体。
font-family: "my fake font", helvetica, san-serif;
假设已安装/使用过Helvetica,您将获得:
我通过了这个问题,并创建了Font Unstack,它测试堆栈中的每种字体并仅返回第一个已安装的字体。它使用@MojoFilter提到的技巧,但是如果安装了多个,则仅返回第一个。尽管它确实遭受了@tlrobinson提到的弱点(Windows将用Arial代替Helvetica并报告已安装Helvetica),但它还是可以正常工作的。
一种有效的技术是查看元素的计算样式。Opera和Firefox支持此功能(我在Safari中进行了侦察,但尚未测试)。IE(至少为7)提供了一种获取样式的方法,但似乎是样式表中的内容,而不是计算出的样式。有关quirksmode的更多详细信息:获取样式
这是获取元素中使用的字体的简单函数:
/**
* Get the font used for a given element
* @argument {HTMLElement} the element to check font for
* @returns {string} The name of the used font or null if font could not be detected
*/
function getFontForElement(ele) {
if (ele.currentStyle) { // sort of, but not really, works in IE
return ele.currentStyle["fontFamily"];
} else if (document.defaultView) { // works in Opera and FF
return document.defaultView.getComputedStyle(ele,null).getPropertyValue("font-family");
} else {
return null;
}
}
如果CSS规则是:
#fonttester {
font-family: sans-serif, arial, helvetica;
}
然后,如果已安装helvetica,则应返回helvetica,否则返回arial,最后返回系统默认的sans-serif字体的名称。请注意,CSS声明中的字体顺序很重要。
您也可以尝试的一个有趣的技巧是使用许多不同的字体创建许多隐藏的元素,以尝试检测计算机上安装了哪些字体。我确信有人可以用这种技术制作一个漂亮的字体统计信息收集页面。
有一个简单的解决方案-只需使用element.style.font
:
function getUserBrowsersFont() {
var browserHeader = document.getElementById('header');
return browserHeader.style.font;
}
此功能将完全满足您的要求。执行时,它将返回用户/浏览器的字体类型。希望这会有所帮助。
另一种解决方案是自动安装字体,通过@font-face
它可能不需要检测。
@font-face {
font-family: "Calibri";
src: url("http://www.yourwebsite.com/fonts/Calibri.eot");
src: local("Calibri"), url("http://www.yourwebsite.com/fonts/Calibri.ttf") format("truetype");
}
当然,它不会解决任何版权问题,但是您始终可以使用免费字体,甚至可以制作自己的字体。您将同时需要.eot
&.ttf
文件才能最佳工作。
Calibri是Microsoft拥有的字体,不应免费分发。另外,要求用户下载特定字体也不是很友好。
我建议购买字体的许可证并将其嵌入到您的应用程序中。
我正在使用Fount。您只需要将Fount按钮拖动到书签栏,单击它,然后单击网站上的特定文本即可。然后它将显示该文本的字体。
您可以将Adobe Blank放到要查看的字体之后的字体系列中,然后将不呈现该字体中没有的任何字形。
例如:
font-family: Arial, 'Adobe Blank';
据我所知,还没有JS方法可以判断元素中哪些字形是由该元素的字体堆栈中的哪种字体呈现的。
浏览器具有衬线/无衬线/等宽字体的用户设置,并且它们也具有自己的硬编码后备字体,如果在字体中的任何字体中都找不到字形,则将使用它们,这使情况变得复杂。字体栈。因此,浏览器可能会使用不在字体堆栈或用户浏览器字体设置中的字体来渲染某些字形。 Chrome开发工具会为您显示所选元素中字形的每种渲染字体。因此,在您的计算机上,您可以看到它在做什么,但是无法分辨用户计算机上正在发生的事情。
用户系统也可能在其中发挥作用,例如Window在字形级别上执行Font Substitution。
所以...
对于您感兴趣的字形,即使它们没有您指定的字体,也无法知道它们是否将由用户的浏览器/系统后备呈现。
如果要在JS中进行测试,则可以使用包括Adobe Blank的字体系列渲染单个字形,并测量其宽度以查看其是否为零,但您必须遍历每个字形和要测试的每种字体,但是,尽管您可以知道元素字体堆栈中的字体,但无法知道用户浏览器配置为使用哪种字体,因此对于至少某些用户而言,您要遍历的字体列表将是不完整的。(如果新字体问世并开始使用,这也不是未来的证明。)