如何在CSS中未定义实际渲染字体?

MC *_*ror 34 javascript css fonts

如果未定义CSS font-facefont-size属性,如何获取元素的实际字体和字体大小?

例如,JavaScript代码段

object.style.fontFamily
Run Code Online (Sandbox Code Playgroud)

不会返回任何价值.这很明显,假设CSS没有将样式应用到object任何地方.但是,当然,某种字体用于呈现文本,可能是系统字体或webbrowser默认字体.

那么,例如,JavaScript可以获得渲染的字体吗?

dan*_*ton 32

没有标准的,可靠的方法来确定使用的实际字体.此前的答案将报告样式化的fontFamily样式值,但这可以是字体名称列表,并不具体标识呈现的实际字体(这是此处提出的实际问题).

(正如一些评论所提到的,有一些方法可以猜测,在通过检查视觉提示的字体,但是这不可能是100%可靠的.)


Šim*_*das 30

我建议这个功能:

function css( element, property ) {
    return window.getComputedStyle( element, null ).getPropertyValue( property );
}
Run Code Online (Sandbox Code Playgroud)

用法:

css( object, 'font-size' ) // returns '16px' for instance
Run Code Online (Sandbox Code Playgroud)

注意:getComputedStyle在IE8中不起作用.

现场演示: http ://jsfiddle.net/4mxzE/

  • 虽然这仍将返回css指定的字体,但不是文本实际呈现的字体,如果它们不同.我正在寻找一种方法来查看浏览器是否已下载并显示我的自定义字体. (29认同)
  • IE具有可比较的`element.currentStyle`而不是:http://www.quirksmode.org/dom/getstyles.html (2认同)
  • @MoizTankiwala我认为,这是因为`getCompulatedStyle`返回“计算值”,而不是“使用值”([参见此处的示例](https://drafts.c​​sswg.org/css-cascade-4/#stages-examples) )。 (2认同)

Sal*_*n A 24

您可以在Chrome/Firefox开发者工具中找到有关渲染字体的信息.请尝试检查以下代码段中的段落:

p { font-family: sans-serif;  }
Run Code Online (Sandbox Code Playgroud)
<p>Some text and <span title="an emoji"></span></p>
Run Code Online (Sandbox Code Playgroud)


在Chrome开发者工具中(在55.0.2883.75 m 64位上测试),您将获得以下信息:

Chrome开发者工具>元素>计算选项卡


在Firefox Developer Tools(在47.0.2上测试about:config > devtools.fontinspector.enabled = true)中,您可以获得以下信息:

Firefox开发人员工具>元素>字体选项卡

  • 该死。搜索在未公开的“this._agent.getPlatformFontsForNode()”处结束。如果您感兴趣,请稍后调用 https://github.com/ChromiumWebApps/blink/blob/ea798590bf47f65436cd9d0803b3d7af4d5d614f/Source/core/inspector/InspectorCSSAgent.cpp#L772。 (2认同)

Iva*_*nos 7

我找到了一种方法(对于所有支持的浏览器<canvas>),通过检查像素是否为字体渲染已更改

function renderedfont(ele) {
    var getDefaultFonts = function () {
        var iframe = document.createElement('iframe');
        var html = '<html><body>';
        var fonts;
        document.body.appendChild(iframe);
        iframe.contentWindow.document.open();
        iframe.contentWindow.document.write(html);
        var subele = iframe.contentWindow.document.createElement(ele.tagName);
        iframe.contentWindow.document.body.appendChild(subele);
        fonts = getComputedStyle(subele)['font-family'];
        document.body.removeChild(iframe);
        return fonts;
    }
    var fonts = getComputedStyle(ele)['font-family'] + ',' + getDefaultFonts();
    var fontsArray = fonts.split(',');
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext("2d");
    var testString = "abcdefghijklmnopqrstuvwxyz!@#$%^&*()ñ";
    var prevImageData;
    document.body.appendChild(canvas);
    canvas.width = 500;
    canvas.height = 300;
    fontsArray.unshift('"Font That Doesnt Exists ' + Math.random() + '"');

    for (var i = 0; i < fontsArray.length; i++) {
        var fontName = fontsArray[i].trim();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.font = '16px ' + fontName + ', monospace';
        ctx.fillText(testString, 10, 100);
        var idata = ctx.getImageData(0, 0, canvas.width, canvas.height); 
        var data = idata.data
        if (prevImageData) {
            for (var j = 0; j < data.length; j += 3) {
                if (prevImageData[j + 3] !== data[j + 3]) {
                    document.body.removeChild(canvas);
                    return fontName;
                }
            }
        }
        prevImageData = data;
    }

    document.body.removeChild(canvas);
    return 'monospace';
}
Run Code Online (Sandbox Code Playgroud)

所以要用你做:

renderedfont(document.body);
// Arial
Run Code Online (Sandbox Code Playgroud)

如果您将此用于另一种方言(例如日语),您可能希望将testString变量更改为该方言中最常见的字符.