大声地读出来我们移动端适配的核心
!!!移动端适配的核心目标是让同一网站在不同尺寸、不同分辨率的移动设备上都能提供良好的视觉和交互体验。
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
- `width=device-width`:让视口宽度等于设备宽度。
- `initial-scale=1.0`:初始缩放比例为1。
- `maximum-scale=1.0, user-scalable=no`:禁止用户缩放(根据需求可选)。
1、移动端响应式布局的REM适配脚本
1.1 adapt 函数 - 获取默认字体大小
function adapt(designWidth, rem2px) {
var d = window.document.createElement('p')
d.style.width = '1rem' // 创建一个宽度为1rem的元素
d.style.display = "none" // 隐藏该元素,不影响页面显示
var head = window.document.getElementsByTagName('head')[0]
head.appendChild(d) // 将元素添加到head中
var defaultFontSize = parseFloat(window.getComputedStyle(d, null).getPropertyValue('width'))
return defaultFontSize // 返回浏览器默认的1rem对应的像素值
};
1.2 adapt 立即执行函数
!(function (doc, win, designWidth, rem2px) {
// 参数说明:
// doc = document, win = window
// designWidth = 750 (设计稿宽度)
// rem2px = 100 (1rem应该等于多少设计稿像素)
var docEl = doc.documentElement, // html根元素
defaultFontSize = adapt(designWidth, rem2px), // 调用adapt获取默认字体大小
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize', // 判断设备支持的事件
```
```
recalc = function () {
var clientWidth = win.innerWidth ||
doc.documentElement.clientWidth ||
doc.body.clientWidth // 获取视口宽度
if (!clientWidth) return // 如果获取失败则退出
if (clientWidth < 750) {
// 核心计算公式:
docEl.style.fontSize = clientWidth / designWidth * rem2px / defaultFontSize * 100 + '%'
} else {
// 屏幕宽度≥750px时,固定根字体大小为625%
docEl.style.fontSize = '625%'
}
}
2、移动端使用vw单位进行适配
2.1 纯CSS vw方案(推荐)
/* 移动端REM适配 - vw方案 */
html {
/* 设计稿750px,1rem = 100px 的换算公式 */
font-size: 13.333333vw; /* 100 / 750 * 100 = 13.333333 */
}
/* 大屏限制 - 超过750px时固定根字体大小 */
@media screen and (min-width: 750px) {
html {
font-size: 100px; /* 750px宽度时,13.333333vw = 100px */
}
}
/* 可选:小屏最小字体限制,避免过小 */
@media screen and (max-width: 320px) {
html {
font-size: 42.666667px; /* 320px宽度时,13.333333vw ≈ 42.67px */
}
}
body {
/* 设置最大宽度,居中显示 */
max-width: 750px;
margin: 0 auto;
}
2.2 CSS + 少量JS(兼容性更好)
!(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in win ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth || win.innerWidth;
if (!clientWidth) return;
// 使用vw单位,JS作为fallback
if (clientWidth < 750) {
// vw方案:13.333333vw
docEl.style.fontSize = (clientWidth / 750 * 100) + 'px';
} else {
// 大屏固定
docEl.style.fontSize = '100px';
}
};
// 现代浏览器直接使用CSS vw,老旧浏览器使用JS计算
if (!win.CSS || !CSS.supports || !CSS.supports('width', '1vw')) {
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
}
})(document, window);
```
// 对应的css代码
```
/* 现代浏览器使用vw */
html {
font-size: 13.333333vw;
}
@media screen and (min-width: 750px) {
html {
font-size: 100px;
}
}
/* JS会覆盖这个样式,所以不需要担心重复 */
.no-vw html {
font-size: 16px; /* 默认值,会被JS覆盖 */
}
3 PostCSS插件自动转换(工程化推荐)
// postcss.config.js
module.exports = {
plugins: {
'postcss-px-to-viewport': {
viewportWidth: 750, // 设计稿宽度
viewportHeight: 1334, // 设计稿高度
unitPrecision: 6, // 转换精度
viewportUnit: 'vw', // 转换单位
selectorBlackList: ['.ignore', '.hairlines'], // 忽略选择器
minPixelValue: 1, // 最小转换值
mediaQuery: false // 媒体查询中的px是否转换
}
}
}