在网页开发过程中,不同设备显示css字体大小不一致是常见的问题,尤其是移动端设备屏幕尺寸和像素密度差异较大时,固定像素的字体单位会导致显示效果偏差。使用rem单位可以很好地统一不同设备上的字体显示比例,解决适配难题。

为什么会出现字体大小显示不一致
造成css字体大小在不同设备显示不一致的原因主要有以下几点:
- 设备屏幕像素密度不同,同样的px单位在高清屏上显示会更小
- 部分设备默认设置了系统字体缩放比例,会影响网页字体的最终显示大小
- 没有正确设置视口标签,导致移动端设备以默认缩放比例渲染页面
- 使用了固定像素px作为字体单位,无法根据设备屏幕尺寸动态调整
rem单位的基本原理
rem是css3引入的相对长度单位,它的取值是相对于根元素html的font-size值来计算的。比如根元素html的font-size设置为16px,那么1rem就等于16px,2rem就等于32px。只要我们根据不同设备的屏幕尺寸动态调整根元素的font-size值,所有使用rem作为单位的字体大小就会按比例缩放,从而实现不同设备上的显示一致性。
使用rem统一字体比例的实现步骤
1. 设置视口标签
首先需要在html的head部分添加视口标签,确保移动端设备以正确的比例渲染页面,避免默认的缩放行为影响字体显示。代码如下:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
2. 动态设置根元素字体大小
我们可以通过js监听屏幕尺寸变化,根据设计稿的宽度和当前屏幕宽度,动态计算并设置html的font-size值。通常设计稿的宽度是750px,我们约定设计稿上75px对应1rem,这样计算起来更方便。代码如下:
// 设置根元素字体大小的函数
function setRootFontSize() {
// 设计稿宽度,根据实际设计稿调整
const designWidth = 750;
// 设计稿上1rem对应的px值,这里设置为75,即75px=1rem
const remPerPx = 75;
// 获取当前屏幕宽度
const screenWidth = document.documentElement.clientWidth || window.innerWidth;
// 计算根元素字体大小,公式为 屏幕宽度 / 设计稿宽度 * 设计稿上1rem对应的px值
const rootFontSize = (screenWidth / designWidth) * remPerPx;
// 设置html的font-size,限制最小和最大值避免极端情况
document.documentElement.style.fontSize = Math.min(Math.max(rootFontSize, 12), 100) + 'px';
}
// 页面加载时执行一次
setRootFontSize();
// 监听窗口大小变化,重新设置根元素字体大小
window.addEventListener('resize', setRootFontSize);
// 监听页面显示时重新设置,处理从后台切回的情况
window.addEventListener('pageshow', function(e) {
if (e.persisted) {
setRootFontSize();
}
});
3. 使用rem设置字体大小
完成根元素字体大小的动态设置后,我们就可以在css中使用rem单位来定义字体大小了。比如设计稿上标题字体是30px,按照75px=1rem的约定,30px就是30/75=0.4rem。示例代码如下:
/* 重置默认样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
/* 备用字体设置 */
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
/* 使用rem设置默认字体大小 */
font-size: 0.4rem;
line-height: 1.5;
}
/* 标题字体大小 */
h1 {
font-size: 0.6rem;
}
h2 {
font-size: 0.5rem;
}
/* 小字提示文本 */
.tip-text {
font-size: 0.32rem;
color: #666;
}
注意事项
- 如果使用js动态设置根元素字体大小,建议放在head标签内执行,避免页面加载时出现字体大小跳动的情况
- 部分旧版本浏览器不支持rem单位,可以添加px单位的降级写法,比如
font-size: 16px; font-size: 0.4rem;,支持的浏览器会优先使用rem值 - 如果项目中使用构建工具,也可以通过postcss的插件自动将px转换为rem,减少手动计算的工作量
- 不要在根元素html上直接写死font-size为固定值,否则无法实现动态适配的效果
纯css实现rem适配的方案
如果不想使用js,也可以通过css的媒体查询结合vw单位来实现根元素字体大小的动态设置,vw是相对于视口宽度的单位,1vw等于视口宽度的1%。示例代码如下:
html {
/* 设计稿宽度750px,1vw=7.5px,要让75px=1rem,即75/7.5=10vw */
font-size: 10vw;
}
/* 限制最大屏幕宽度下的根元素字体大小,避免大屏上字体过大 */
@media screen and (min-width: 750px) {
html {
font-size: 75px;
}
}
这种方案不需要js参与,但是兼容性略差于js方案,且无法精确控制最小和最大字体大小,开发者可以根据项目需求选择合适的实现方式。