用 svg 辅助页面文字自适应
前言
我们知道,在前端开发的过程中,最让人脑壳疼的就是页面的适配了。之所以说让人脑壳痛,倒不是说页面适配多么的困难。他不困难,就是做起来很很繁琐,特别是对于要移动端和 pc 端均要适配的页面,那处理起来就让人更头疼了。
最近在做页面适配的时候,发现对于全设备(包括移动端和 pc 端)适配的时候,vw 和 vh 布局是一个很不错的方式(后面我们统一称呼维 vw 布局)。
虽然不能保证在所有的屏幕尺寸都能达到理想的效果,但是,至少能够等比例的缩放,比百分比布局要好一点。
vw 布局的几个小问题
但是做前端就是这样,你必须承认很难有那种百分百完美的布局方案,即使是这个所谓的 vw 布局,照样有他不完美的地方。
比如我现在就总结一下,我发现的 vw 布局存在的几个问题,当然问题肯定不止这几个,应该肯定还有一些我没有发现的小问题吧。
- 首先一个不完美的地方就是浏览器的兼容性,这点可以说是无解的,不在我们次此的讨论范围里面。
- 其次有一个影响非常大的一个问题是,chrome 浏览器 12 px 字体大小的限制,会导致屏幕尺寸过小时,这个缩放策略失效了。按道理来说,这个问题应该算是一个通用的问题,不只 vw 布局的时候会遇到。
- 当屏幕宽高比变化的非常大的时候,排出来的效果并不太好。比如设计稿设计的是采用 1920*1080 的,但是你非得用在竖屏的 iPhone X 上,后者的尺寸为 375 * 812,即使是横屏使用,宽高比也超过了 2 了,那样效果当然没有设计稿上的好了。但是 vw 特点是,可以保持设计搞布局的统一,不用针对不同尺寸的屏幕,设计多套不同的设计稿。
而我今天分享的这篇文章,想要讨论的主题是,应该通过什么方案,去解决 chrome 浏览器字体 12 px 的限制,导致 vw 布局失效的问题。
解决 chrome 12 px 限制的几种方案
想要解决 chrome 浏览器 12 px 字体限制的方案有好几种,这里我稍微的总结一下吧:
- 通过设置 -webkit-text-size-adjust 属性,但是这个属是历史解决方案,在新版的 chrome 上就不支持了,具体可以参考 mdn 相关页面:https://developer.mozilla.org/zh-CN/docs/Web/CSS/text-size-adjust
- 通过 scale css 属性解决这个问题,这个方法可行性很高,但是在针对 vw 布局,就不太好用了。因为本身我外面容器的尺寸就是在变化的,所以,我还得通过 js 去动态的计算尺寸,去动态的算出 scale 值,再设置进去,这样做就太麻烦了。
- 就是我们标题中的方案,通过 svg 去辅助页面的文字的自适应。
- 通过 canvas 辅助页面文字的自适应。
svg 辅助文字自适应的详细思路
针对 vw 布局,我选择采用的方案是我们上文提到的第三种方案——通过 svg 去辅助页面文字的自适应。
主要做法就是,将文字包裹在 svg 标签里面,然后让 svg 标签自适应其父容器的大小。
这是我目前认为,配合 vw 布局最有效的方案,而且,在兼容性方面来说也有不俗的表现。
先说说,我为什么不采用 canvas 辅助的方案。
我们知道,canvas 和 svg 比较类似,也是一种兼容矢量缩放的方式,用在这里,也不是不可以,但是我总感觉没有 svg 来的那么优雅。
因为 canvas 元素的宽高,不能用用 css 去设置 100%,它也不能自动重绘。这样就导致了,我们每次窗口尺寸再变化的时候,必须要通过 js 去动态的调整 canvas 元素的大小,而且在调整了 canvas 元素的尺寸以后,必须要手动的去重绘 canvas 里面的内容,这样就会引起一系列的麻烦。
相反呢,svg 用在这个场景下感觉比较轻量级,能够缩放自适应,感觉还是更胜一筹的。
下面就来介绍一下,具体应该如何操作,才能实现 svg 辅助页面文字自适应。
1. 传统 px 方式
首先,父容器必须要弄成 vw 布局。
如果不了解 vw 布局的童鞋,可以去看看 css 标准文档:https://drafts.csswg.org/css-values-3/#viewport-relative-lengths。
image.pnghtml 部分是这样的:
<div id="wapper">
<span id="span1">just a test!</span>
<span id="span2">我是测试文字</span>
</div>
css 部分是这样的:
#wapper {
width: 300px;
height: 100px;
background: #999;
}
span {
width: 300px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
font-size: 22px;
}
这样写,没问题,但是缺点是不能自适应,所以在手机屏幕上,这样的显示效果就不太理想了。
image.png2. vw 布局方式
我们看看如果采用了 vw,会是什么样的效果。
当然这里换算成 vw 的过程中有个技巧,屏幕总的宽度是 100 vw ,高度是 100vh。因此加入你的设计稿是 1920 * 1080 的,那么这里我们就应该这么算。
// 宽度
300 / 1920 * 100 = 15.625 vw
// 高度
100 / 1080 * 100 = 9.259 vh
...
照着这个换算规律,我们改下 css 样式的写法:
#wapper {
width: 15.625vw;
height: 9.259vh;
background: #999;
}
span {
width: 15.625vw;
height: 4.6296vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.1458vw;
}
然后在预览一下在手机上的效果:
image.png当然我这里没有用真机测试,但是具体效果差别应该也不太大。
3. chrome 调试移动端页面
我们可以打开 chrome 浏览器的控制台,开启移动设备模拟调试模式,然后选择 responsive,开始拖动改变可视区域尺寸看下效果。
image.png4. 可视区域尺寸过小存在问题
你会发现,当可视区域的尺寸非常小的时候,chrome 文字因为 12px 大小限制就会挤到一坨了,布局非常难看:
image.png但是如果你换用 Firefox 浏览器,你会发现,效果会好很多:
image.png在 pc 上虽然感觉好像看不清楚,但是在移动端,这个尺寸的屏幕,这样的效果,还是不错的。最重要的,这是自适应的页面,一套代码,pc 端和移动端都适用,写起来多么的方便。
5. 添加 svg 辅助文字自适应,突破 12 px 限制
既然 chrome 浏览器效果不理想,就引出了我们这篇文章想要解决的问题,突破 12 px 的限制。
下面我们来调整下 html 代码:
<div id="wapper">
<span id="span1">
<svg width="100%" height="100%">
<text dy=".3em" x="50%" y="50%" fill="#fff" text-anchor="middle">just a test!</text>
</svg>
</span>
<span id="span2">
<svg width="100%" height="100%">
<text dy=".3em" x="50%" y="50%" fill="#fff" text-anchor="middle">我是测试文字</text>
</svg>
</span>
</div>
然后再重新运行页面:
image.png可以看到,我们的 chrome 浏览器,12 px 字体的限制,就这么被我们无情的突破了。
这个效果,刚好正是我们想要的效果。
如果不了解 svg 的童鞋,可以上 mdn 学习一下:https://beta.developer.mozilla.org/zh-CN/docs/Web/SVG。
可以看到,我们的 svg 标签可以采用 css 的 width 和 height 属性,能通过 100% 这种百分比的方式来自适应布局。我们让他来适应我们的 父标签,这样就可以完美的布局我们的文字了。
总结
当然,这种文字自适应的布局方式不一定适合你的应用场景,要结合具体情况去看。
svg 确实是一个强有力的工具,它矢量的特性,刚好介于 html 标签和 canvas 之间。当然对于 svg,我也是处于初学者的水平,以后再用的过程中,如果有什么心得,我也会分享出来,跟大家一起学习的。