rem是css3引入的相对长度单位,它的计算基准是html根元素的font-size属性值,1rem等于根元素字体大小。在html5开发中,使用rem布局可以让页面元素尺寸跟随根字体大小动态变化,天然适配不同屏幕宽度的设备,避免传统px固定单位带来的适配问题。

rem单位的核心计算规则
rem的取值完全由html根元素的font-size决定,假设根元素字体大小设置为16px,那么1rem就等于16px,2rem等于32px,以此类推。如果后续修改根元素的font-size为20px,那么1rem就会自动变为20px,所有使用rem定义尺寸的元素都会同步缩放。
我们可以通过下面的代码验证这个规则:
/* 设置根元素字体大小为16px */
html {
font-size: 16px;
}
/* 1rem = 16px,盒子宽度为16px */
.box-small {
width: 1rem;
height: 1rem;
background: #f00;
}
/* 2rem = 32px,盒子宽度为32px */
.box-large {
width: 2rem;
height: 2rem;
background: #0f0;
}
动态设置根字体大小的常用方案
要实现响应式布局,核心是根据屏幕宽度动态计算根元素的font-size值,让rem单位能跟随屏幕尺寸自动调整。目前最常用的方案是通过js监听屏幕宽度变化,动态设置根字体大小。
方案一:基于设计稿宽度的等比缩放
假设设计稿宽度为750px,设计稿中根字体大小设置为75px,那么1rem等于75px,设计稿上的元素尺寸除以75就能得到对应的rem值。我们可以根据当前屏幕宽度和设计稿宽度的比例,动态计算根字体大小:
// 设计稿宽度
const designWidth = 750;
// 设计稿对应的根字体大小
const designFontSize = 75;
function setRootFontSize() {
// 获取当前屏幕宽度
const currentWidth = document.documentElement.clientWidth;
// 计算根字体大小:当前宽度 / 设计稿宽度 * 设计稿根字体大小
const fontSize = currentWidth / designWidth * designFontSize;
// 设置根元素字体大小,限制最小和最大值避免极端情况
document.documentElement.style.fontSize = Math.min(Math.max(fontSize, 32), 100) + 'px';
}
// 初始执行一次
setRootFontSize();
// 监听窗口大小变化重新计算
window.addEventListener('resize', setRootFontSize);
方案二:基于视口宽度的css方案
如果不想使用js,也可以通过css的calc函数和视口单位vw来设置根字体大小,vw是视口宽度的1%,这种方式不需要js监听,兼容性也足够覆盖大部分现代浏览器:
/* 假设设计稿宽度750px,1vw = 7.5px,要让设计稿75px对应1rem,即75px = 10vw */
html {
font-size: 10vw;
}
/* 限制最大屏幕宽度下的根字体大小,避免大屏上元素过大 */
@media screen and (min-width: 750px) {
html {
font-size: 75px;
}
}
rem布局的实际使用示例
下面是一个完整的html5页面示例,使用js动态设置根字体大小,实现响应式布局:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>rem布局示例</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 头部区域,高度2rem,内边距0.5rem */
.header {
width: 100%;
height: 2rem;
padding: 0.5rem;
background: #1677ff;
color: #fff;
font-size: 0.8rem;
line-height: 1rem;
}
/* 内容区域,外边距0.5rem,内边距0.5rem */
.content {
margin: 0.5rem;
padding: 0.5rem;
background: #f5f5f5;
font-size: 0.7rem;
}
/* 列表项,高度1.2rem,边框0.02rem */
.list-item {
height: 1.2rem;
line-height: 1.2rem;
border-bottom: 0.02rem solid #eee;
font-size: 0.7rem;
}
</style>
</head>
<body>
<div class="header">rem布局示例页面</div>
<div class="content">
<div class="list-item">列表项1</div>
<div class="list-item">列表项2</div>
<div class="list-item">列表项3</div>
</div>
<script>
const designWidth = 750;
const designFontSize = 75;
function setRootFontSize() {
const currentWidth = document.documentElement.clientWidth;
const fontSize = currentWidth / designWidth * designFontSize;
document.documentElement.style.fontSize = Math.min(Math.max(fontSize, 32), 100) + 'px';
}
setRootFontSize();
window.addEventListener('resize', setRootFontSize);
</script>
</body>
</html>
rem布局的注意事项
- 不要给根元素设置过小的
font-size,避免部分浏览器的最小字体限制导致计算偏差,建议根字体大小不低于12px。 - 行内元素或者文本相关的尺寸,也可以结合
em单位使用,em基于父元素字体大小,和rem的基准不同,适合局部相对调整。 - 如果项目中同时使用了px和rem单位,要注意两者的转换关系,避免布局错乱,建议统一使用rem作为布局单位,px仅用于边框等不需要缩放的细节。
- 在pc端适配时,要设置根字体大小的最大值,避免屏幕过宽时元素尺寸过大影响阅读体验。
rem布局本质是等比缩放方案,适合对比例要求严格的移动端页面,如果需要更灵活的适配,可以结合flex布局、grid布局一起使用,满足更复杂的布局需求。