css,不止“突破浏览器12px限制”

1,785 阅读6分钟

之前写过一篇文章「小tips:如何摆脱浏览器下12px的限制」,不少人觉得“有点东西”。文中提到的“transform: scale()”方法也是利用了CSS中 transform 的特点,可以说兼顾了效果和性能。 但是它必须考虑height甚至在“动态多行”效果时要用 JS 辅助的特点也很是让人头疼。

其实还可以用两种方法解决这个限制:

SVG解决文字12px限制

SVG 本质上你可以看成是一张图片,给图片设置width:100%就能够跟随容器尺寸拉伸,SVG 也是如。并且由于 SVG 是矢量的,因此,再怎么拉伸我们的文字效果都是清晰细腻的 —— 这种方法的原理就在于此!

SVG 中<text><tspan>元素可以用来呈现文本,嵌套关系为<text> -> <tspan>,个人觉得和HTML中的<p> -> <span>关系类似。 拿开篇文章中的案例来说,用 svg 可以这么写:

<div class="mmcce-text" 
    v-for="(item, index) in couponInfo.thresholdStr" 
    :key="index" 
    :index="index"
>
	<svg width="600" height="80" viewBox="0 0 600 80">
    	<text font-family="'PingFang SC','Microsoft Yahei'" font-size="60" x="0" y="1em">{{item}}</text>
	</svg>
</div>

简单来说就是先绘制一张大图,然后再缩小。反正也不会失真。 所以在css中规定好类 .mmcce-text 的样式后直接对 svg 设置自适应父元素即可:

svg {
    width: 100%;
}

也能达到一样的效果。

CSS新特性:size-adjust

早上吃早餐时偶然打开 MDN,发现有一个新特性很有趣:size-adjust,和它配套使用的是 unicode-range —— 用来规定哪些字符遵循 size-adjust 的规则。

它们都被使用在 @font-face 特性中。 还是拿之前的例子。但是我们要注意一点:对于和入前文案例中说的“后端吐出动态数据”一样的场景中,就大可不必使用unicode-range了,毕竟也没啥用。

@font-face {
    font-family: smallHeight;
    src: url(‘/assets/font/PingFangSC-Light.ttf‘),
       url('/assets/font/PingFangSC-Light.woff'),
       url('/assets/font/PingFangSC-Light.eot');
    size-adjust: 50%;
    unicode-range: U+5143;
}

它设置的是文字缩小到font-size值的百分之多少!因为它改变的是字体文件底层的字形显示,不受 12px 尺寸的限制

其它场景应用

这玩意的另一个场景就需要搭配 unicode-range 了。比如在电商页面中,前置的“¥”或者后置的“元”、“小数点及后两位数字”的缩小,都可以利用这两个特性完成:

@font-face {
    font-family: miaoshaJia;
    src: url(‘/assets/font/PingFangSC-Light.ttf‘),
       url('/assets/font/PingFangSC-Light.woff'),
       url('/assets/font/PingFangSC-Light.eot');
    size-adjust: 50%;
    unicode-range: U+5143;
}

/** 使用 */
.price {
    font-family: miaoshaJia;
    font-size: 24px;
    color: red;
}

unicode-range: U+5143; 的意思就是“设置元这个字符的大小匹配 size-adjust 规则”。U+5143 就是“元”的Unicode编码。

否则就只能用两个标签或者 :first-letter 了... css里面暂时还没有诸如 「last-letter」这样的伪类设计。所以总的来说比较“不简洁”。

src中引入的字体

这玩意就需要下载专门的字体库了。比如上面用的就是常用而美观的“苹方字体”。一般来说如果是静态文案使用这种方法完全用不了这么大的字体库,这么说来,这种方案反而对于项目加载是一种“拖累”?

其实不然,我们可以使用比如“字蛛”来提取所需要的几个/几十个文字将他们压缩打成一个新的包,这个包的大小往往只有原来的好多分之一。然后再去引入新的包使用就好。 微店-活动页

笔者曾在公司内部分享时就对这种方式做过详细而自以为成熟的解说。随后开始被我司在一些“艺术字”等场景中开始代替图片使用和探索...

不过,唯一有些疑惑的是我曾经在不知道哪看到过这样的写法:src: local('PingFang SC'); ,遂查找资料,未果,作罢。

苹方字体是ios9上的默认中文字体,苹方黑体不仅字型优美,并且能提升在手机、电脑屏幕上的清晰度和易读性。包含6种字重,分别是苹方黑体常规体、中等、细体、特粗体、特细体、粗体,可以很不错地满足日常设计和阅读的需要。 放上“苹方字体库”:PingFang(腾讯微云免密下载链接,速度嘎嘎快)

支持度

只是,这个css特性的支持程度还不乐观。比如Safari就完全不支持,即使如 Chrome 也仅仅在92版本往后开始支持。仍任重而道远: jianrong


结语,亿点点想法

夏天快到了,天气回暖万物复苏,最是好时光。我非常提倡多出去走走欣赏一些美好的事物,顺便提升一下自己的美感(这一条针对我自己)。但要注意防护哦! 话说天气一回暖疫情又严重了起来,祈祷,我还想回学校毕个业呢,真的是。然后互联网圈子似乎断崖式下跌,还是要稳住啊😦提升自己! 近来很是巴适,有春风、朋友、美酒和烧烤。还实现了摸鱼的梦想。我就知道这个公司我来对了...

回到文章内容。 svg作为一个矢量图,其在系统支持下能最大程度发挥GPU的性能,提升整体渲染效率,而且展示效果也优于常见图片格式,其非常适合在 icon 等场景使用。 毕竟我们都知道,一般图片格式如 PNG、JPEG 都无法被 GPU 直接读取(位图基本都经历了采样、量化、编码的过程),需要先经过 CPU 解码后再上传到 GPU 使用,解码后的数据以 RGB(A) 存储,正常状态下是无压缩的。那么大的图,啧啧。而矢量图在输入时根本不需要采样和量化,最重要的是,减少了文件请求,渲染几乎是无延时的。这就节省了一部分时间,直接起飞~ 大众点评详情页基本所有的大小数字都是svg做的,也是...离谱!

不管是单一的说图片,还是说页面、css的优化。最主要的无非:“跳过”CPU或GPU介入。在游戏中大放光彩的“纹理压缩技术”其优势之一就是“无需CPU解码能够直接被GPU读取和渲染”!

倒是font-face不能滥用。浏览器对于这种“利器”的加载策略也不是完全放手的那种。浏览器加载 Web Fonts 时按顺序会有三个时期:

  • 阻塞期(Block Period)。在此期间如果字体没有加载完成,那么浏览器会使用 font-family 指定的字体列表中的后备字体(Fallback)进行渲染,但是显示为空白,也就是对于用户是不可见的。在此期间字体加载完成之后才能正常显示该字体
  • 交换期(Swap Period)。跟阻塞期类似,但是在这个时期内,它会在字体加载时,先用后备字体渲染文本并显示出来(而不是显示空白),在此期间字体加载完成之后才能正常的显示该字体
  • 失败期(Failure Period)。如果字体加载失败,则使用后备字体显示文本

虽说可以用font-display 跳过阻塞期(swap值),但终究是“后置改变”的。如果碰上很拉胯的网络又没有做好前置处理,就很糟糕。