移动端屏幕大小不一,要使网页能自适应不同尺寸的手机屏幕,而且还要尽可能开发便捷,目前使用最多的还是rem大法,相对比较成熟,而新兴的vw方案也可以一试。
本文主要介绍了rem和vw两种方案的使用配置方式。
首先移动端要设置好视口,使视口的宽度等于设备屏幕宽度,同时浏览器识别后就认为该网页是移动端网页,也就不再有点击延迟的问题了:
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, maximum-scale=1.0, minimum-scale=1.0">
css中rem单位的计算是基于根字体大小,也就是html标签元素的font-size,未设置font-size时默认字体大小是16px,假设根字体大小就是16px,那比如2rem就等于2 * 16 = 32 px。
如果所有涉及尺寸的css单位都用rem来写,那实际尺寸就取决于根字体大小是多少了,那如果根据手机屏幕宽度和设计图宽度的比例去动态改变根字体大小,就能实现实际屏幕呈现出和设计图一致的效果。
var sizeUI = 375 // 定义设计图尺寸
var remBase = 37.5 // 定义基准值
var docEl = document.documentElement // 获取html元素
setRemUnit() // 执行函数
function setRemUnit () {
var docFontSize = docEl.clientWidth / sizeUI * remBase // 计算得到根字体大小
docEl.style.fontSize = docFontSize + 'px' // 设置根字体大小
}
document.querySelector('body').style.fontSize = 16 / docFontSize + 'rem'
window.addEventListener('resize', setRemUnit) // 触发示例:屏幕旋转
window.addEventListener('pageshow', function (e) {
// 触发示例:有页面缓存功能的浏览器的前进后退
if (e.persisted) setRemUnit()
})
var docEl = document.documentElement
function handleRemAdapt () {
var currentFontSize = parseInt(docEl.style.fontSize)
var temp = currentFontSize
for (var i = 0; i < 100; i++) {
// 只遍历100次,够用了
var realFontSize = parseInt(window.getComputedStyle(docEl).fontSize)
var differ = realFontSize - currentFontSize
if (Math.abs(differ) >= 1) {
if (differ > 0) {
temp--
} else {
temp++
}
docEl.style.fontSize = temp + 'px'
} else {
break
}
}
}
;(function (window, document) {
var sizeUI = 375 // 定义设计图尺寸
var remBase = 37.5 // 定义基准值
var docEl = document.documentElement
var bodyEl = document.querySelector('body')
setRemUnit()
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function (e) {
if (e.persisted) setRemUnit()
})
function setRemUnit () {
var docFontSize = docEl.clientWidth / sizeUI * remBase
docEl.style.fontSize = docFontSize + 'px'
bodyEl.style.fontSize = 16 / docFontSize + 'rem'
handleRemAdapt()
}
function handleRemAdapt () {
var currentFontSize = parseInt(docEl.style.fontSize)
var temp = currentFontSize
for (var i = 0; i < 100; i++) {
var realFontSize = parseInt(window.getComputedStyle(docEl).fontSize)
var differ = realFontSize - currentFontSize
if (Math.abs(differ) >= 1) {
if (differ > 0) {
temp--
} else {
temp++
}
docEl.style.fontSize = temp + 'px'
} else {
break
}
}
}
})(window, document)
<head>
<script src="./flexible.js">script>
head>
import './flexible.js'
对于webpack项目,利用插件可以做到webpack编译打包时自动将px单位转rem,这样开发时只需要写px不用再计算,非常方便。
npm i postcss-plugin-px2rem -D
module.exports = {
plugins: {
autoprefixer: {
},
'postcss-plugin-px2rem': {
rootValue: 37.5, // 基准值,和flexible.js里的保持一致
selectorBlackList: ['noRem'],
minPixelValue: 2
}
}
}
如果rem方案使用的得心应手了,再看vw方案就很简单了,vw单位在移动端兼容性已经没问题了,其他方面还需要在项目中实践检验。
vw是视口单位,是视口宽度等分100份后所占的份数,1vw就相当于屏幕宽度的1%,所以使用vw单位在不同屏幕尺寸下能天然的自适应。
vw方案相比rem方案无需封装引入js文件,将设计图尺寸下的元素大小转换为vw就能直接使用,简单很多。
webpack项目中可以 利用插件进行自动转换,和上述px自动转rem类似。
npm i -D postcss-px-to-viewport
module.exports = {
plugins: {
autoprefixer: {
},
'postcss-plugin-px2rem': {
viewportWidth: 375, // 设计图尺寸
minPixelValue: 2
}
}
}