@font-face是CSS3中的一个模块,他主要是把自己定义的Web字体嵌入到你的网页中,@font-face这个功能早在IE4就已经支持。指定的字体可以从远程服务器或者用户本地安装的字体加载,语法规则:
@font-face {
font-family: <YourWebFontName>;
src: <source> [<format>][,<source> [<format>]]*;
[font-weight: <weight>];
[font-style: <style>];
}
参数说明:
1、YourWebFontName:自定义的字体名称,最好是使用你下载的默认字体。
2、source:自定义的字体的存放路径,可以是相对路径也可以是绝路径;
3、format:自定义的字体的格式,主要用来帮助浏览器识别,其值主要有以下几种类型:truetype,opentype,truetype-aat,embedded-opentype,avg等;
4、weight和style:weight定义字体是否为粗体,style主要定义字体样式,如斜体。
浏览器兼容:
TureTpe(.ttf)格式: Windows和Mac的最常见的字体,是一种RAW格式,因此他不为网站优化,可以任意缩放和旋转不会出现锯齿,支持这种字体的浏览器有:IE9+,Firefox3.5+,Chrome4+,Safari3+,Opera10+,iOS Mobile Safari4.2+
OpenType(.otf)格式:.otf字体被认为是一种原始的字体格式,是可缩放性的电脑字体类型,是微软与Adobe共同开发用来替代TrueType的新字形,其内置在TureType的基础上,所以也提供了更多的功能,支持这种字体的浏览器有:
Firefox3.5+,Chrome4.0+,Safari3.1+,Opera10.0+,iOS Mobile Safari4.2+
Web Open Font Format(.woff)格式:.woff字体是Web字体中最佳格式,专门为了We设计的字体格式标准,他是一个开放的TrueType/OpenType的压缩版本,并针对网络使用进行了优化,同时也支持元数据包的分离,支持这种字体的浏览器有:
IE9+,Firefox3.5+,Chrome6+,Safari3.6+,Opera11.1+
Embedded Open Type(.eot)格式: 微软开发的IE专用嵌入字体格式,可以从TrueType创建此格式字体,支持这种字体的浏览器有:IE4+
SVG(.svg)格式:.svg字体是基于SVG字体渲染的一种格式,其中.svgz是使用了Gzip压缩的SVG字体,但 IE 或 Firefox 从不支持它,并且现在 Chrome 也放弃了对它的支持。因此,它的用途很有限,本指南中有意将其忽略。支持这种字体的浏览器有:
Chrome4+,Safari3.1+,Opera10.0+,iOS Mobile Safari3.2+
我们可以根据项目需求来判定使用哪种字体,一般其实.ttf格式就可以满足需求,但如果项目想要兼容多种低版本浏览器,这就意味着在@font-face中我们至少需要.woff,.eot两种格式字体,甚至还需要.svg等字体达到更多种浏览版本的支持。Paul Irish写了一个独特的@font-face语法叫Bulletproof @font-face,让各多的浏览器支持,可以写成:
@font-face {
font-family: 'YourWebFontName';
src: url('YourWebFontName.eot'); /* IE9 Compat Modes */
src: url('YourWebFontName.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('YourWebFontName.woff') format('woff'), /* Modern Browsers */
url('YourWebFontName.ttf') format('truetype'), /* Safari, Android, iOS */
url('YourWebFontName.svg#YourWebFontName') format('svg'); /* Legacy iOS */
}
查阅网上资料,可以在Webfonts,Typekit,Kernest,Google Web Fonts,Kernest,Dafont,Niec Web Type,寻找自己需要的字体,可根据需求自行瞎子啊,但个人推荐使用字客网。
注意:字体下载时,如果是应用于商业项目一定要注意一下版权问题,避免不必要的商业纠纷。
字体下载往往会只有其中一种格式字体,当我们需要.eot,.woff,.ttf,.svg字体格式。我给大家推荐一款好用的工具fontsquirrel,点这里进入到下面这个界面吧。
以项目中Let’s go Digital Regular 字体为例,使用场景为vue-cli4,style-resources-loader预加载
function addStyleResource(rule) {
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [
path.resolve(__dirname, './src/styles/fonts.less'),
]
});
}
使用这种形式,因为业务场景,.ttf格式便可以满足需求,在引入文件地址时会有路径问题,因为style-resources-loader使用绝对路径导致,所以这里我们采用这种方式来引入:
@font-face {
font-family: 'LetsgoDigital-Regular';
src: url('~@/assets/fonts/digital-regular.ttf') format('truetype');
}
最终页面上效果:
当项目中需要引入很多自定义字体时,会发现字体库体积很大,比如常用的PingFangSC-Regular字体库就有14M,因此压缩是必不可少的。
推荐使用font-spider,也可以使用Fontmin,相对于font-spider而言比较方便的是有一个客户端操作界面。
font-spider的工作原理是这样的: 中文字体文件之所以很大,是因为英语只有26个字母,而中文的汉字有好多好多个,所以文件相对来说就会大很多。font-spider就是从你的css文件的@font-face入手,去查找字体,然后遍历你的html文件,通过分析本地 CSS 与 HTML 文件获取 WebFont 中没有使用的字符,并将这些字符数据从字体中删除以实现压缩,同时生成跨浏览器使用的格式。
注意:这种是把fonts.html中没有引用的字体删除,从而达到压缩的效果!!!!!如果是整个中文包压缩,这种方式就很不适用了!!!
在vue中使用时,可创建一个fonts.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
@font-face {
font-family: 'lcdd';
src: url('./src/assets/fonts/pingfangsc-regular.ttf');
src: url('./src/assets/fonts/pingfangsc-regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
.test {
font-family: 'lcdd';
}
</style>
</head>
<body>
<h2 class="test">12345678.980%</h2>
</body>
1.安装font-spider :npm install font-spider -g
2.进入fonts.html所属文件夹下,执行font-swiper fonts.html
3.生成.font-spider存储之前未压缩字体,压缩后字体仅有4k
压缩后:
压缩前:
虽然有压缩的功能,但必须提供出所有使用过的字体,而且我想的是我的项目中就默认一个好看的字体。
这样就遇到一个问题,在第一次加载的时候,浏览器就会用一些时间来加载这个字体文件。
而在加载完成之前,页面就会空白,也就是FOIT(Flash of Invisible Text)
FOUT(Flash of Unstyled Text)大意就是在字体加载完成前,浏览器会显示font-family
的顺序字体
当加载完成后,才会替换成定义的字体,设置如下:
@font-face {
...
font-display: swap;
...
}
这样设置之后依旧会有字体闪动的效果,只是初始由白屏变为了默认字体,体验依旧不好,不推荐。
FontFaceObserver
判断字体加载完添加loading动画,使用fontfaceobserver,安装:npm i fontfaceobserver
b.
// css 中 @font-face 已定义好
import FontFaceObserver from 'fontfaceobserver'
loadfont(){
console.time("字体加载用时")
var ooo = new FontFaceObserver('Regular')
ooo.load().then(() =>{
document.getElementById('index').style.fontFamily = 'Regular'
console.timeEnd("字体加载用时")
})
},
同时可以结合通过 HTTP 缓存优化字体重复使用
字体资源通常是不会频繁更新的静态资源。因此,它们非常适合较长的 max-age 到期 - 确保您为所有字体资源同时指定了条件 ETag 标头和最佳 Cache-Control 策略。
无需在 localStorage 中或通过其他机制存储字体,其中的每一种机制都有各自的性能缺陷。 浏览器的 HTTP 缓存与 Font Loading API 或 webfontloader 内容库相结合,实现了最佳并且最可靠的机制来向浏览器提供字体资源。
阿里iconfont相信大家都是用过,这里不对注册等流程做过多赘述,直接说一下使用方式。
单个图标用户可以自行选择下载不同的格式使用,包括png,ai,svg。此种方式适合用在图标引用特别少,以后也不需要特别维护的场景。比如设计师用来做demo原型、前端临时做个活动页、下载图标做PPT等。在项目中不推荐使用此种方式
unicode是字体在网页端最原始的应用方式,特点是:
注意:新版iconfont支持多色图标,这些多色图标在unicode模式下将不能使用,如果有需求建议使用symbol的引用方式
第一步:拷贝项目下面生成的font-face
@font-face {font-family: 'iconfont';
src: url('iconfont.eot');
src: url('iconfont.eot?#iefix') format('embedded-opentype'),
url('iconfont.woff') format('woff'),
url('iconfont.ttf') format('truetype'),
url('iconfont.svg#iconfont') format('svg');
}
第二步:定义使用iconfont的样式
.iconfont{
font-family:"iconfont" !important;
font-size:16px;font-style:normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
第三步:挑选相应图标并获取字体编码,应用于页面
"iconfont">3;
font-class是unicode使用方式的一种变种,主要是解决unicode书写不直观,语意不明确的问题。
但一定要注意命名空间的问题,否则一上线引发了各种雪崩问题。与unicode使用方式相比,具有如下特点:
使用步骤如下:
第一步:拷贝项目下面生成的fontclass代码:
//at.alicdn.com/t/font_8d5l8fzk5b87iudi.css
第二步:挑选相应图标并获取类名,应用于页面:
<i class="iconfont icon-xxx">i>
svg
的symbol
提供了类似于雪碧图的功能,让svg
的使用变得更简单,也可以满足做图标系统的需求,这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 这种用法其实是做了一个svg的集合,与上面两种相比具有如下特点:
font-size
,color
来调整样式。使用步骤如下:
第一步:拷贝项目下面生成的symbol代码:
//at.alicdn.com/t/font_8d5l8fzk5b87iudi.js
第二步:加入通用css代码(引入一次就行):
<style type="text/css">
.icon {
width: 1em; height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
第三步:挑选相应图标并获取类名,应用于页面:
<svg class="icon" aria-hidden="true">
<use xlink:href="#icon-xxx">use>
svg>
上面的方式使用的iconfont官方推荐的方式引用的。这种方式有很多缺陷,比如
他是通过js来生成svg的代码,icon映射关系不明了,是以下面形式展示
做不到按需加载,不能根据我们使用了那些 svg 动态的生成 svg-sprite
自定义性差,通常导出的svg包含大量的无用信息,例如编辑器源信息、注释等。通常包含其它一些不会影响渲染结果或可以移除的内容。
重点!!!!添加方式很不友好,icon更新需要每次重新生成iconfont.js,很麻烦
所以,我们可以借助 svg-sprite-loader 来实现按需加载。 svg-sprite-loader 它是一个 webpack loader ,可以将多个 svg 打包成 svg-sprite
。根据导入的 svg 文件自动生成 symbol 标签并插入 html。
svg-sprite-loader优点:
但是我们发现vue-cli
默认情况下会使用 url-loader
对svg进行处理,会将它放在/img
目录下,所以这时候我们引入svg-sprite-loader
会引发一些冲突。参考文章vue-cli3中webpack 相关配置,其中配置了include和exclude,请参考文章vue-cli3中webpack 相关配置。本来只添加svg-sprite-loader就行了,但是svg也是图片的一种,所以file-loader也会对其进行处理,所以就会冲突,解决的办法就是,在项目中新建一个文件icons,使用file-loader编译svg的时候不编译icons里面的图标。
// vue.config.js
const path = require('path')
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg')
// 清除已有的所有 loader。
// 如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。
svgRule.uses.clear()
svgRule
.test(/\.svg$/)
.include.add(path.resolve(__dirname, './src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
const fileRule = config.module.rule('file')
fileRule.uses.clear()
fileRule
.test(/\.svg$/)
.exclude.add(path.resolve(__dirname, './src/icons'))
.end()
.use('file-loader')
.loader('file-loader')
}
}
配置完成之后,可以检查一下配置是否生效:
vue inspect:控制台会显示你的webpack所有的配置
vue inspect --rules 显示所有的rule配置规则
vue inspect --rule svg (我们在上面配置了svg)
<icon-svg icon-class="icon-geren-copy" /> // 使用方式
import '@/icons/icon-Shapecopy.svg'; // 引入方式
通过上面的方式,每次引入图标都需要
import '@/icons/icon-Shapecopy.svg';
import引入我们需要的图标,很麻烦,这里我们可以使用自动导入所有图标。之后我们就要使用到 webpack 的 require.context。简单的说就是可以正则匹配引入相应的文件模块。例如:
require.context("./test", false, /.test.js$/);
这行代码就会去 test 文件夹(不包含子目录)下面的找所有文件名以 .test.js 结尾的文件能被 require 的文件。
require.context有三个参数:
直接上配置代码:
import Vue from 'vue';
import IconSvg from '@/components/icon/icon-svg.vue';
Vue.component('icon-svg', IconSvg);
const requireAll = (requireContext) => requireContext.keys().map(requireContext);
const req = require.context('../../icons', false, /\.svg$/)
requireAll(req);
通过这种方式我们使用图标时就不需要import啦~ 是不是很方便?
这里附上SVG在线压缩合并工具与SVG Sprites还原与管理在线工具。另外附上好用的工具svgo 官方文档 张鑫旭大大的文章。
写到这里我产生了一个疑问,为什么一定要用svg?png与iconfont字体他不香吗?这里做一下简单的介绍,更多延伸可以参考:这篇文章
先说一下与icon font对比:
所以,根据我的理解简单的说,svg更适合做图标,因为它更加高清且支持多色。
大众点评评论数据抓取 反爬虫措施有css文字映射和字体库反爬虫。
大众点评的反爬虫手段有那些?比如:封ip,封账号,字体库反爬虫,css文字映射,图形滑动验证码。
目前很多主流网站其实用到的很少,极为典型的就是大众点评,这里只做一下简单的介绍。具体的一些内容可参考文献:css反爬虫。目前反爬虫大概为两类,第一种是svg引用的方式,第二种是字体库反爬虫。
字体加密其实是将一种特定的字体库来代替浏览器本身的字体库显示的过程。用凯撒加密的方式将明文(下图的原文)替换为密文(下图的阴书),加密的密钥(也就是下图字验)就是上面font-face
声明的自定义字体,加密好之后,HTML源码中是密文,使用自定义字体作为密钥进行CSS解密,渲染在页面上的就是解密后的正常的明文了。
这一种对应文本为空,只能通过 class 属性区分,点击检查,可以看到右边属性中有一个 background-image url ,这个以 svg 为后缀的文件是一种可伸缩矢量图形,通过他来对应字体。然后在svg中找到对应的文字。但这种方式现在已经被摒弃掉了,目前已经没有网站在使用了。
字体库反爬虫是大众点评目前在使用的手段,主要在页面上展示的效果如下:
我们可以从对应资源中查找字体资源
然后通过工具FontCreator 打开该字体文件。
由于大众点评对相应的 unicode 码进行了处理,所以就只能使用一些识图的 api 或者工具,识别出其中的内容,并保存构造相应的字典。因为大众点评的字体文件会更新,所以建议可以保存到 reids 中,方便处理。
因为这种方式少数注重数据的网站会采用,这里就不详细赘述了。如果以数据为核心资产的项目,可以尝试使用这种加密方式。
参考文献:https://www.w3cplus.com/content/css3-font-face
https://developer.mozilla.org/zh-CN/docs/Web/CSS/@font-face
https://segmentfault.com/a/1190000019262268
https://juejin.im/post/59bb864b5188257e7a427c09