小程序中使用 iconfont 与传统 BOM 环境类似,只是小程序更为封闭,微信团队针对性地做了一些定制化处理,今天我们聊一下小程序场景下应用 iconfont 的方案。

小程序应用 iconfont

全局引入字体

我目前的做法是在项目的 app.wxss 中引入 iconfont 文件,可以全局生效。问题是组件无法继承这个全局字体,解决方案下文会提。

另一种方案比较复杂,先将字体文件转为 base64,在全局样式中引入 base64,这种方案毫无优势可言,仅仅为了方案而方案,对于开发者以及后续维护很不友好。

线上字体文件管理,将 iconfont 文件放线上 CDN,通过线上地址引入。当然,如果使用阿里的矢量图库生成 iconfont,会默认提供一份线上的版本,

再说说如何管理字体源文件,如果线上 icon 变动较为频繁,并且内部都是定制化的 icon,推荐将 icon 源文件托管在 iconmoon` 类似的线上服务中,方便后续维护更新,源文件更新后,生成新的字体文件,再将新的字体更新到线上 CDN。(这也是我们目前的做法)

组件怎么办 ?

小程序官方为了防止组件样式被外层样式污染,规定了一些条件

  • 组件和引用组件的页面不能使用id选择器(#a)、属性选择器([a])和标签名选择器,请改用class选择器。
  • 组件和引用组件的页面中使用后代选择器(.a .b)在一些极端情况下会有非预期的表现,如遇,请避免使用。
  • 子元素选择器(.a>.b)只能用于 view 组件与其子节点之间,用于其他组件可能导致非预期的情况。
  • 继承样式,如 font 、 color ,会从组件外继承到组件内。
  • 除继承样式外, app.wxss 中的样式、组件所在页面的的样式对自定义组件无效。

解释一下这个条件对我们的影响是,

  • 组件不能继承 app.wxss 中的全局样式
  • 组件中引入字体文件时,不能使用属性选择器

每个组件单独引入一份字体文件的代价太大,而且还需要对现有字体中的属性选择器进行改造。这时候我们发现了一个新特性,小程序在 2.2.3 版本后开始支持 addGlobalClass 选项,激活后组件可以继承 app.wxss 中的样式。

到这里,组件使用的 iconfont 的问题基本已经解决,唯一需要注意的是,为了避免样式污染问题,后续新的组件样式类名都必须有一套自己的命名空间。

啰嗦两句


日常工作学习,遇到新技术或新生态,需要多思考,从技术角度而言,小程序不完全是新技术,并不是和 web 技术完全隔离,网络上搜索信息时,对于别人的观点需要有实践,有自己的思考,当下网上关于小程序的分享,大部分内容粗糙不堪,很多人甚至不明白为什么用 base64 格式引入字体都不能说清楚就在网上分享,基础的 web 知识都没弄清楚,却把小程序当作技术研究,有些本末倒置了。

我很多次表述过,小程序是生态的一环,所以我更趋向去分享一些业务技巧,以及一些 hack 方式去解决当下,官方还没解决的问题。