自适应方案PxToRem
# 自适应方案PxToRem
使用 rem 做自适应布局的核心原理是利用 rem 单位相对于根元素(<html>)的字体大小,使得整个页面的布局、尺寸能够相应调整,从而实现自适应设计。
# 什么是rem
rem 是一种相对单位,指的是相对于根元素(<html>)的 font-size 大小。相比 em(相对于父元素的字体大小),rem 更加一致,因为它总是相对于整个文档的根元素。
例如,假设根元素的 font-size 为 16px,那么:
- 1rem = 16px
- 2rem = 32px
- 0.5rem = 8px
通过动态调整根元素的字体大小,你可以控制整个页面中 rem 单位的相对大小。
# 为什么用 rem 实现自适应?
px 是固定单位,不会随着屏幕大小或分辨率的变化而调整。因此在不同设备(比如手机、平板、桌面)上,固定的 px 单位可能会导致界面不够灵活。
而 rem 是相对单位,基于根元素的字体大小。当我们通过 JavaScript 或 CSS 媒体查询调整根元素的 font-size 时,所有使用 rem 单位的元素都会根据新的 font-size 自动调整尺寸,达到自适应效果。
# rem 自适应的实现原理
# 设置 <html> 根元素的 font-size
为了使整个页面自适应不同设备的宽度,通常需要根据设备的视口宽度动态设置 <html> 的font-size。这个字体大小将成为 rem 的基准。例如,假设设计稿的宽度是 375px,基准 font-size 设为 16px:
- 在小屏设备上,比如宽度为
320px,我们可以通过 JavaScript 或媒体查询将font-size调小。 - 在大屏设备上,比如宽度为
1440px,我们可以将font-size调大。
# 根据视口宽度调整font-size
通过监听设备的视口宽度变化,可以动态设置根元素的 font-size。这种方法可以用来自动适应不同屏幕大小。
JavaScript 动态设置示例:
function setRem() {
const baseSize = 16; // 设计稿的基准像素值
const baseWidth = 375; // 设计稿的基准宽度(例如375px)
const screenWidth = document.documentElement.clientWidth || window.innerWidth;
// 根据当前屏幕宽度计算根元素的 font-size
const fontSize = (screenWidth / baseWidth) * baseSize;
// 设置根元素的 font-size
document.documentElement.style.fontSize = `${fontSize}px`;
}
// 初始化调用
setRem();
// 监听窗口变化
window.addEventListener('resize', setRem);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
在上面的代码中:
baseSize是设计稿中设定的根元素的基准字体大小(通常是16px)。baseWidth是设计稿的宽度,例如设计稿宽度为375px(移动端设计稿)。screenWidth是当前设备的屏幕宽度,我们根据屏幕宽度与设计稿宽度的比例来动态调整根元素的字体大小。
当屏幕宽度变化时,根元素的 font-size 会动态变化,页面中所有使用 rem 单位的元素都会跟随调整,达到自适应效果。
# 在 CSS 中使用 rem
在 CSS 中,用 rem 单位来代替 px,可以实现动态调整元素尺寸。例如:
.container {
width: 10rem; /* 等价于设计稿中160px宽 */
height: 5rem; /* 等价于设计稿中80px高 */
font-size: 1.2rem; /* 等价于设计稿中的19.2px字体 */
}
2
3
4
5
6
假设根元素的 font-size 是 16px,那么上述 CSS 样式中的 10rem 就等同于 160px。当根元素的 font-size 随着屏幕大小变化时,所有 rem 单位的尺寸也会相应变化。
如果项目已经写了很多,批量转换很难,后面会说一个插件自动转换postcss-pxtorem,安装及配置
第一步:安装 craco-postcss:
npm install @craco/craco craco-postcss --save-dev
第二步:然后在 craco.config.js 中添加 postcss-pxtorem 配置:
const postcssPxToRem = require('postcss-pxtorem');
module.exports = {
style: {
postcss: {
plugins: [
postcssPxToRem({
rootValue: 16, // 根元素字体大小,1rem = 16px
unitPrecision: 5, // 转换后保留的小数点位数
propList: ['*'], // 允许转换的属性,例如['font', 'font-size', 'line-height', 'letter-spacing']
selectorBlackList: [], // 不进行转换的类名
replace: true, // 是否替换原来的px,还是生成备用的rem
mediaQuery: false, // 是否在媒体查询中转换px
minPixelValue: 2 // 小于2px的不转换
})
]
}
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
第二步(附):如果你已经弹出配置或在使用 Webpack: 你可以直接在 postcss.config.js 文件中配置:
module.exports = {
plugins: [
require('postcss-pxtorem')({
rootValue: 16, // 设计稿的基准像素值
unitPrecision: 5, // 精度
propList: ['*'], // 哪些属性需要转换
replace: true,
mediaQuery: false,
minPixelValue: 2
})
]
};
2
3
4
5
6
7
8
9
10
11
12
13
配置完成后,当你运行构建工具时(例如使用 npm run build 或 npm start),所有的 px 单位都会自动转换为 rem 单位。
# 具体实现步骤
选择设计稿的基准宽度和基准字体大小
- 例如,设计稿的基准宽度为
375px,基准字体大小为16px。
- 例如,设计稿的基准宽度为
动态调整根元素的
font-size- 可以通过 JavaScript、媒体查询、或
vw单位等方式来动态设置根元素的font-size。
- 可以通过 JavaScript、媒体查询、或
在 CSS 中使用
rem单位代替px- 将设计稿中的
px换算成rem。例如,如果设计稿中一个元素的宽度是160px,可以使用10rem(160px ÷ 16px = 10rem)。
- 将设计稿中的
调整自适应逻辑
- 根据不同设备的宽度,调整根元素的
font-size,从而实现整个页面自适应。
- 根据不同设备的宽度,调整根元素的
# 5. 媒体查询优化(可选)
除了动态调整根元素的 font-size 外,还可以配合媒体查询来适应不同屏幕。例如:
@media (max-width: 768px) {
html {
font-size: 14px; /* 小屏幕上的基准font-size */
}
}
@media (min-width: 1200px) {
html {
font-size: 18px; /* 大屏幕上的基准font-size */
}
}
2
3
4
5
6
7
8
9
10
11
12
通过这种方式,可以为不同的屏幕宽度设置不同的基准 font-size,进而更细致地控制页面的响应式布局。
# 总结
原理:
rem是相对于根元素的字体大小,因此通过动态设置<html>的font-size,可以让所有使用rem的元素根据视口宽度自动调整尺寸。自适应实现步骤:
- 设定设计稿的基准宽度和
font-size。 - 使用 JavaScript 或媒体查询动态调整根元素的
font-size。 - 在 CSS 中用
rem单位替代px。
- 设定设计稿的基准宽度和
通过这种方式,可以构建一个在不同设备上都能灵活调整的响应式布局,适合从移动端到桌面端的多种屏幕尺寸。
# 等比缩放方案
当然也可以用整体缩放的形式做自适应 页面等比自适应git (opens new window)