随着移动互联网的普及,越来越多的用户开始在手机、平板等移动设备上访问互联网,因此,在开发 SPA(Single Page Application,单页应用) 应用时,如何应对不同设备的屏幕适配问题成为了一个不可忽视的挑战。
问题分析
在进行移动端屏幕适配时,一般分为以下两种方式:
固定布局:利用媒体查询(
@media
)设置不同屏幕宽度下的样式,缺点是需要针对每一个屏幕宽度进行样式的设置,工作量较大。弹性布局:利用百分比和弹性盒子布局(flexbox)等方式,使布局能够随着屏幕宽度的变化而自适应,通常适用于宽度在 320px-768px 之间的移动端屏幕,但无法应对高度变化的问题。
解决方案
在 SPA 应用中,我们可以使用响应式布局的方式进行屏幕适配。
场景一:利用 rem 进行适配
在进行屏幕适配时,我们可以使用 rem(Root EM,根元素 em)单位来进行样式设置。rem 单位相对于根元素 html 的字号大小,特点是能够自适应页面缩放以及适应不同设备像素密度的问题。
首先,需要设置根元素 html 的字号大小。我们可以利用 JavaScript 获取文档宽度,计算出合适的字号大小,放到根元素 html 中:
var rootEle = document.documentElement; var clientWidth = rootEle.clientWidth; rootEle.style.fontSize = clientWidth / 7.5 + "px"; // 根据不同屏幕设置字号
在进行开发时,我们可以设定 1rem = 100px ,这样我们就可以通过计算单位转换来达到样式适配的目的。
例如,设置 body 元素的字号大小为 16px,则可以通过以下方式设置宽高及字号大小:
-- -------------------- ---- ------- ---- - ---------- ----- - ---- - ------ ----- -- --- ----- -- ------- ----- -- --- ----- -- ---------- ------- -- --- ---- -- -
使用 rem 来进行屏幕适配,能够自适应各种屏幕大小,但并不支持所有的浏览器,需要兼容处理。
场景二:利用 vw 进行适配
在不支持 rem 的浏览器中,我们可以使用 vw(Viewport Width,视窗宽度)单位来进行适配。vw 单位是指视口宽度的 1/100 ,与 rem 类似,能够自适应页面缩放以及适应不同设备像素密度的问题。
我们同样需要设置根元素 html 的字号大小为 1vw ,即 1vw = 1px 。对于不支持 viewport 的旧设备,我们可以使用媒体查询来解决:
-- -------------------- ---- ------- ---- - ---------- ---- - ------ ------ --- ----------- ------ - ---- - ---------- ------ - - ------ ------ --- ----------- ------ - ---- - ---------- ------ - -
在进行开发时,我们同样需要设定一些基准值,例如:
.box { width: 50vw; /* 相当于占用视口宽度的一半 */ height: 20vw; /* 相当于占用视口宽度的 1/5 */ margin: 2vw; /* 相当于占用视口宽度的 2% */ }
使用 vw 来进行屏幕适配,能够自适应各种屏幕大小,支持更多的浏览器,但因为 vw 跟随视口大小的变化而变化,可能会带来部分兼容性问题。
最佳实践
以上两种方案在实际开发中都有适用的情况,因此我们可以根据实际需求进行选择。
最佳实践中,我们可以根据屏幕宽度选择适配方案,在移动端设备上使用 rem 进行适配,在 PC 设备上使用 vw 进行适配。
例如设置移动端字号大小:
var rootEle = document.documentElement; var clientWidth = rootEle.clientWidth; rootEle.style.fontSize = clientWidth / 7.5 + "px"; // 根据不同屏幕设置字号
设置 PC 端字号大小:
html { font-size: 10vw; }
总结
在 SPA 应用中进行屏幕适配,是一个需要细心处理的问题。我们可以通过响应式布局的方式进行适配,利用 rem 和 vw 单位进行样式设置,从而达到自适应各类设备的目的。
需要注意的是,在进行开发时,我们需要使用百分比及弹性盒子布局等方法,以使布局可以随着屏幕宽度变化而自适应。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64fa984cf6b2d6eab317faa1