背景
师兄有个领导看板大屏的需求,代码开发完毕,在实地测试的时候遇到字体超出原定位置界限的问题。为什么实地测试的时候才暴露出来呢?开发时候是在mac电脑上的,而实际落地是在windows上,通过大屏展示。
推测原因如下:
- 开发环境的苹果电脑与生产环境windows电脑硬件条件不一致
- 大屏显示器设置未调对(如分辨率等)
- 开发环境的苹果电脑中的字体在生产环境的windows中不存在
当时现场查看的时候,我就想这个问题的该如何迅速解决,毕竟UED同学指出字体超出边界的问题很影响体验,而大屏是展示给领导看的,务必不能出现样式上的重大瑕疵。当场师兄和其他人员约定到时候再调整大屏设置,同时寻找合适的字体以解决大屏显示样式问题(即使在开发过程中样式对不上设计稿也没关系,只求最终落地在大屏上能够合适展示)。
讨论中,总结出以下解决方案:
- 在连接大屏的电脑安装合适的字体
- 提前上传合适字体,在代码中设置使用
其中第1种方案成本最小,由于是公司内部的大屏,沟通成本较小。但是推广起来不方便,毕竟如果把大屏应用到其他公司,沟通成本、操作成本会大大提高。第2种方案,虽然开发起来需要一定代码量,但是对开发人员更易掌控,可以做到代码复用。而其实,两种方法都需要不断尝试,实地查看效果后才能选择到合适的字体。
demo制作流程
技术选型
早对font-face自定义字体有所耳闻,先去查看了一下mdn文档,发现基本用法还是比较简单的。再去caniuse上查看了一下兼容性,发现也还行,能兼容到IE11,如图。虽然可以让客户下载最新的浏览器,毕竟一个公司只有若干块大屏,成本不高,但是能多兼容一点也还是安心点,后面的字体选择也是基于这样的考虑。
当开始我找到的是otf格式的,制作完成了demo后给师兄核验,发现它的IE11兼容性不够好,如图,所以切换到woff格式。
至于这个demo,总的来说是利用font-face属性,通过font-family设置相应的自定义字体名,src指定网络加载的url地址,最后可以通过在类中设置font-family指定字体,就可以实现加载网络字体了。但是第一版代码有bug,贴出来让大家看看,能发现几个错误?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
font-face {
font-family: "DIN Alternate";
src: url("./assets/fonts/DIN-RegularAlternate-2.otf") format("otf"),
}
.myFont{
font-family: "DIN Alternate",serif;
}
.myFont-2{
}
.myFont-3{
font-family: Microsoft YaHei UI;
}
</style>
</head>
<body>
<div class="myFont">我是字体</div>
<div class="myFont-2">我是字体2</div>
<div class="myFont-3">我是字体3</div>
</body>
</html>
错误是如何发现的呢?是在第二天UED同学送来字体,师兄让我用新字体设置查看效果,我设置对照试验,调试了好久才发现这两个标点的错误,如图。
小知识点
demo原本的目的是为了实现使用合适的较小字体,以便真正的业务代码在大屏上显示时字体不超出范围。所以调试的时候我会关注由我们设置在代码中的自定义字体是否真的生效了,如图为在windows上生效效果。
逐字匹配规则
第一眼看到右下角的这些标志字符我感觉很神奇,它到底是怎么计算的呢?通过再次仔细查看文档,发现是逐字匹配的逻辑,如图。
发现这个规则后,我继续写了个demo验证。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
@font-face {
font-family: "myFont";
src: url('../assets/fonts/ROBOTO/Roboto-Black.woff') format('woff');
}
.font-1 {
font-family: "myFont", serif;
}
.font-2 {
font-family: "Microsoft YaHei UI";
}
</style>
</head>
<body>
<!-- <div class="font-1">你好啊--123456</div> -->
<!-- 中文渲染为Songti SC ,本地资源-->
<!-- <div class="font-1">你好啊</div> -->
<!-- 破折号渲染为Roboto Bk,网络资源 -->
<div class="font-1">--</div>
<!-- 数字渲染为Roboto Bk ,网络资源-->
<!-- <div class="font-1">123456</div> -->
<!-- <div class="font-2">你好啊--123456</div> -->
<!-- <div class="font-3">你好啊--123456</div> -->
</html>
当比如我指定Roboto-Black字体格式,对“你好啊--123456”中,“你好啊”使用的是Songti SC,“--123456”使用的是Roboto-Black。这是因为Roboto-Black不包含中文,所以英文字符串“--123456”会应用Roboto-Black格式,而中文字符串“你好啊”会选择默认字体即Songti SC。大家可以根据清除注释尝试一下,不同电脑的默认字体也是不同的。比如公司用来显示大屏那台windows上的默认字体是Sim Sun。注意使用src:url加载相应字体成功后,不管本地有没有该字体,计算样式右下角呈现的字体都会显示“网络资源”,这也是可以验证相应字体是否加载成功的标志。比如DIN Alternate这个字体我电脑上本地就有,通过该方法加载也是显示”网络资源“而不是”本地文件“。
资源推荐
在完成demo过程中,除了以上的mdn和caniuse,还发现了两个字体工具。
- 字体天下,可提供字体下载服务:www.fonts.net.cn/font-search…
- 在线字体转换服务:everythingfonts.com/otf-to-woff
我使用的过程是在字体天下找到字体后,发现格式不满足开发要求,所以去搜了字体转换服务。上面那个字体转换挺方便的,右上角可以搜索功能,比如搜关键词“otf woff”等,然后中间输入框上方同意字体使用条款,之后"Pick Font File"上传待转换字体,再点击“Convert”,过一会就可以拿到目标字体的下载包了。找了好多字体转换工具,有些是网站,需要注册才能使用的,有些是npm包,需要下载运行命令的。综合对比下来,还是这个在线转换的最方便。毕竟只有这么一种字体需要测试,后续如果有许多需求的话考虑使用npm包批量操作。如果大家有好的字体转换网站不妨评论区分享喽,快乐分享后翻倍哦。
总结
demo制作过程中发现了自己对bug有不敏感的问题,师兄之前提到过demo的破绽点,即呈现的字体和指定的字体不一致,但是我没有仔细对照正确的最终效果,无视了提早发现bug的机会,直到今天字体的需求确认后才有机会发现bug。经过多轮对比验证,发现是标点的问题,有的地方多了,有的地方少了,小小的错误直接导致大量无效排查时间。需要以此立木为凭,举一反三,减少低级错误带来的效率损耗。gitee仓库