根据 W3C 标准

Note. It is recommended that implementations that use OpenType or TrueType fonts use the metrics "sTypoAscender" and "sTypoDescender" from the font's OS/2 table for A and D (after scaling to the current element's font size). In the absence of these metrics, the "Ascent" and "Descent" metrics from the HHEA table should be used.

字体的 A 和 D 两部分是根据 OS/2 表中 sTypoAscendersTypoDescender 或者 HHEA 表中的 AscentDescent 来计算的. 下面用了一个工具来计算字体的这四个属性:

const { Font } = require('fonteditor-core');
const { readFileSync } = require('fs');

function info(font) {
    if (/\.(ttf|otf|woff|eot)$/.test(font)) {
        const type = RegExp.$1;
        const buffer = readFileSync(font);
        const data = Font.create(buffer, { type }).get();
        console.log(`\x1b[41m\x1b[37m[${font}] information\x1b[0m`);
        [
            'OS/2.sTypoAscender',
            'OS/2.sTypoDescender',
            'hhea.ascent',
            'hhea.descent'
        ].forEach(function log(property) {
            const [ prop1, prop2 ] = property.split('.');
            console.log(`\x1b[32m${property}:\x1b[0m   ${data[prop1][prop2]}`);
        });
    } else {
        throw new Error('Unknown font type!');
    }
}

IconFont.CN 下载下来的字体有一个基线设置, 通过定义一个能兼容绝大部分中文字体的基线来使得保持图标和文字的对齐. 具体信息可以看这里.

我所用的工具 svgicons2svgfont -> svg2ttf -> fonteditor-core 这个流程走下来, 所设定的基线和下端部是重合的, 使得图标的表现类似于一张图片. 工具生成的这种吧, 能够把图标当作图片处理, 有时候比对齐两个未知字体来的方便.

至于大小问题, ICONFONT 的大小通过 font-size 控制. font-size 大小决定了 ICONFONT 的 EM 盒的大小(等比于 SVG 文件的 viewBox). 所以如果 SVG 图标里的路径没有撑满画布, 那渲染出来的字体从视觉上也不会严格等于 font-size.

总结: 明确 ICONFONT 的基线和大小是熟练运用 ICONFONT 布局的基础. 之前对这块没有作细节性研究, 所以 ICONFONT 在项目里用的不多. 经过此番探索, 终于又有了一个新的选择.


残阳映枫红
6.1k 声望638 粉丝