在移动端开发中,页面布局的自适应是一个重要的问题。不同的设备屏幕尺寸和分辨率要求我们的页面能够灵活地适应各种环境,确保用户获得良好的体验。在CSS中,rem
单位是一个相对单位,它是相对于根元素(html
)的字体大小的。通过动态地设置根元素的字体大小,我们可以方便地实现页面的自适应布局。本文将介绍如何使用flexible.js
来实现基于rem
单位的移动端页面自适应布局,并给出一个相关的例子。
一、flexible.js
的原理与功能
flexible.js
是一个自执行函数,它主要用于处理移动端页面的适配问题。它的核心原理是根据设备的屏幕宽度动态地设置根元素的font-size
,使得1rem
等于屏幕宽度的某个分数(例如1/24)。这样,通过修改元素的rem
值,我们可以方便地根据屏幕宽度调整元素的大小。
除了设置rem
单位外,flexible.js
还具备以下功能:
- 设置
body
的字体大小,以适应不同设备的像素比。 - 监听页面大小变化,当页面大小改变时重新计算并设置
rem
单位。 - 处理页面从浏览器缓存中恢复显示时的情况,确保页面布局正确。
- 检测设备是否支持绘制0.5px的边框,并据此给根元素添加特定的类,以便在CSS中为这类设备提供特定的样式。
二、使用示例
HTML代码(index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flexible Rem Example</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<header>
<h1>Welcome to My Website</h1>
</header>
<main>
<article>
<h2>Article Title</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. ...</p>
</article>
</main>
<footer>
<p>Footer Content</p>
</footer>
</div>
<script src="flexible.js"></script>
</body>
</html>
CSS代码(styles.css)
/* 设置全局字体大小和行高 */
body {
font-size: 16px; /* 实际大小由 flexible.js 中的 setBodyFontSize 函数动态设置 */
line-height: 1.5;
}
/* 使用 rem 单位定义布局 */
.container {
width: 100%;
max-width: 750rem; /* 假设设计稿宽度为 750px */
margin: 0 auto;
padding: 2rem;
box-sizing: border-box;
}
header {
height: 10rem; /* 头部高度 */
background-color: #f5f5f5;
}
main {
margin-top: 2rem; /* 主内容区上边距 */
}
article {
margin-bottom: 2rem; /* 文章间距 */
}
footer {
height: 8rem; /* 底部高度 */
background-color: #f5f5f5;
}
/* 根据需要添加更多样式 */
/* 如果页面支持 0.5px 边框,则添加特定样式 */
.hairlines .some-element {
border: 0.5px solid #ccc;
}
JavaScript代码(flexible.js)
(function flexible(window, document) {
var docEl = document.documentElement;
var dpr = window.devicePixelRatio || 1;
// adjust body font size
function setBodyFontSize() {
if (document.body) {
document.body.style.fontSize = 12 * dpr + "px";
} else {
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit() {
var rem = docEl.clientWidth / 24;
docEl.style.fontSize = rem + "px";
}
setRemUnit();
// reset rem unit on page resize
window.addEventListener("resize", setRemUnit);
window.addEventListener("pageshow", function(e) {
if (e.persisted) {
setRemUnit();
}
});
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement("body");
var testElement = document.createElement("div");
testElement.style.border = ".5px solid transparent";
fakeBody.appendChild(testElement);
docEl.appendChild(fakeBody);
if (testElement.offsetHeight === 1) {
docEl.classList.add("hairlines");
}
docEl.removeChild(fakeBody);
}
})(window, document);
HTML文件定义了一个简单的页面结构,CSS文件使用rem
单位来定义页面的布局样式。JavaScript文件flexible.js
被引入并在页面加载时执行,它根据设备的屏幕大小动态地设置根元素的font-size
,从而实现了页面的自适应布局。
三、flexible.js
详解
flexible.js
用于处理移动端页面的适配问题,特别是解决不同设备屏幕大小和分辨率下的页面布局和字体大小问题。它主要利用了 rem
单位来实现页面的自适应布局,并通过设置 body
的字体大小来影响整个页面的字体大小。
代码功能:
1.获取设备像素比:
var dpr = window.devicePixelRatio || 1;
获取设备的像素比,用于后续判断是否需要启用高清屏适配。
2.设置 body 字体大小:
function setBodyFontSize() {
if (document.body) {
document.body.style.fontSize = 12 * dpr + "px";
} else {
document.addEventListener("DOMContentLoaded", setBodyFontSize);
}
}
setBodyFontSize();
根据设备的像素比设置 body
的字体大小。如果 body
已经存在,则直接设置;否则,等待文档加载完成后设置。
3.设置 rem 单位:
function setRemUnit() {
var rem = docEl.clientWidth / 24; // 把屏幕划分成不同等份 1rem
docEl.style.fontSize = rem + "px";
}
setRemUnit();
设置根元素的 font-size
,使得 1rem
等于屏幕宽度的 1/24。这样,通过修改元素的 rem
值,可以方便地根据屏幕宽度调整元素的大小。
4.监听页面大小变化:
window.addEventListener("resize", setRemUnit);
当页面大小变化时,重新计算并设置 rem
单位,确保页面元素的大小能够自适应屏幕大小。
5.处理页面恢复显示:
window.addEventListener("pageshow", function(e) {
if (e.persisted) {
setRemUnit();
}
});
当页面从浏览器缓存中恢复显示时,重新设置 rem
单位,确保页面布局正确。
6.检测 0.5px 支持:
if (dpr >= 2) {
// ... 检测并设置 hairlines 类 ...
}
在高分辨率(dpr >= 2
)的设备上检测是否支持绘制 0.5px 的边框,并据此给根元素添加 hairlines
类,以便在 CSS 中为这类设备提供特定的样式。
通过动态设置 rem
单位和 body
字体大小,可以方便地实现页面的自适应布局和字体大小调整。这对于确保网页在不同设备上都能有良好的用户体验至关重要。同时,检测 0.5px 的支持情况也是为了在高清屏设备上提供更精细的视觉效果。