REM 是移动端屏幕适配的常见方案,可以选用淘宝开源的 flexible,只是用起来稍微有一点麻烦,我一般采用更加简洁的方案,动态去计算 html 跟标签的 font-size,监听屏幕的尺寸变化及时响应,兼顾用户修改系统字体时的处理等其它细节。
采用 VW 方案去适配也是一个好办法,只是兼容性不太好,需要根据具体场景去选择。
开始使用
- 压缩后,放置到 head 标签的尾部,直接 script 标签嵌入,保证最先执行,避免用户感知到页面跳动;
-
建议加如下代码,将默认字体大小重置为 16px,避免在 js 未执行时,样式、字体混乱:
html, body {font-size: 16px;}
- 字体需不需要使用 rem 单位?看产品、设计师的定位吧,通常建议不要对字体使用 rem 单位(牵扯到布局还是应该采用 rem 单位),尤其是大段的文章;
代码
<script>
/*
* REM 适配:* 1. 动态设置 html 标签 font-size;* 2. 动态设置 html 标签 data-dpr、data-img-rate 属性;* 3. 用户调整系统字体大小时,避免页面样式错乱;* 4. 计算公式:* 750 的设计稿,量图的大小 / 100 => rem 数值
*/
(function (document, window) {
var docEl = document.documentElement,
user_webset_font, // 用户设置的浏览器的字体大小 (兼容 ie)
rate = 1, // 用户设置的字体大小和默认 16px 的比例系数
resizeEvent = 'orientationchange' in window ? 'orientationchange' : 'resize';
if (docEl.currentStyle) {user_webset_font = docEl.currentStyle['fontSize'];
} else {user_webset_font = getComputedStyle(docEl, false)['fontSize'];
}
// 用户调整系统字体大小或浏览器字体大小时,需要做兼容。rate = parseFloat(user_webset_font) / 16;
/**
* 设置 html 标签 font-size
*/
var resetRootFontSize = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
if (clientWidth >= 1080) {docEl.style.fontSize = 200 / rate + 'px';} else {
// 750 设计稿
docEl.style.fontSize = 100 * (clientWidth / 750) / rate + 'px';
// 375 设计稿
// docEl.style.fontSize = 100 * (clientWidth / 375) / rate + 'px';
}
}
/**
* 设置 html 的 data-dpr/data-img 属性(供选用而设置)。*/
var resetDpr = function () {if (!window.devicePixelRatio) return;
// 屏幕像素比大于等于 3, 采用 3 倍图, 否则使用 2 倍图.
var imgRate = window.devicePixelRatio >= 3 ? 3 : 2;
docEl.setAttribute('data-dpr', window.devicePixelRatio);
docEl.setAttribute('data-img-rate', imgRate);
}
// 直接执行,不放到 DOMContentLoaded 事件执行,否则页面能感知到跳动
resetRootFontSize();
resetDpr();
if (!window.addEventListener) return;
window.addEventListener(resizeEvent, function () {resetRootFontSize();
resetDpr();}, false)
})(document, window);
</script>