图标字体化是解决 Retina 等的比较好的方法;本文也不在这里说如何去做,网上面的文章一大堆;具体来说说使用图标中,用户在自定义样式的文件中通过下面一条语句直接让 font-icon 显示为一个方框(Chrome下),带给用户的体验特别不好;

* {font-family: '微软雅黑' !important;}

虽然 Chrome 取消了 Custom.css 文件来自定义字体,但是 Chrome 应用商店里面还是有通过插件来实现同样功能的,所以下面就说说如何发现和解决这个问题;

怎么发现

大家说,这不是直接看到就不对了么,也可以看用户反馈,但是这样只是知道有这个问题,知道这问题后有多少用户受到影响,怎么做打点统计呢?其实这里核心是可以通过 DOM 上面 getComputedStyle 这个方法来检测的,去取设置了 font-icon 的元素的 getComputedStyle 的 font-family,正常情况下,会返回我们设置的 font-family,异常就是返回用户自己设置的 "微软雅黑" 等等,Demo 如下代码;

var el = document.getElementsByClassName('font-icon')[0],
    styles = getComputedStyle(el);
if (styles.fontFamily !== 'fontIconFamily') {
    console.log('font-icon 错误');
    // TODO 服务器发送统计;
}

浏览器对相应 API 的实现是不相同的,所以利用如下兼容方案

function getStyle(el, styleProp) {
    var value;
    if (el.currentStyle) {
        value = value.currentStyle[styleProp];
    } else if (window.getComputedStyle) {
        value = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
    }
    return value;
}
如何修复

发现问题了,如何修复这个问题呢?

常规思路上,用户定义的,而且是 important 声明的,优先级已经很好了,貌似直接没有办法再比这优先级再高了。

但是,在使用 Web Font 中发现,在 Web fonts 和用户本地 font 同名的情况下会优先使用 Web fonts,这样的话,思路就出来了,可以来个 "釜底抽薪",直接指定 "微软雅黑" 等字体为相应 Web Fonts,操作起来还需要配合 unicode-range,只复写特定的范围,再配合 Webkit 等 hack,就可以解决了,代码如下:

@media screen and (-webkit-min-device-pixel-ratio:0) {
    @font-face{
    font-family:'微软雅黑';
    unicode-range:U+E000-E020;
    src:url('/webfonts/fontsname.eot');
    src:url('/webfonts/fontsname.eot?#iefix') format('eot'),
        url('/webfonts/fontsname.woff') format('woff'),
        url('/webfonts/fontsname.ttf') format('truetype'),
        url('/webfonts/fontsname.svg#font') format('svg');
    }
}

同样,可以将常见的几种被强制的字体都用这样的方法来覆写,我至今只发现会强制微软雅黑的。

这里提供一种这种方法不太优雅的;但是作为 hack 本来就不是优雅的方法;所以最后,送给那些强迫症患者,要想强制指定微软雅黑,不是一句 font-family: '微软雅黑' !important; 就粗暴解决的,所以再推荐一篇我之前写的文章:浏览器中替换宋体为微软雅黑较完美方案,虽然说,Chrome 停止支持 Custom.css,但是自己也可以写插件来实现;