移动端适配方案

移动端适配

方案 1:rem + html font-size

方案 2:vw

rem + html font-size

rem 是相对于 html 元素的 font-size 来设置的单位,通过在不同屏幕尺寸下动态修改 html 元素的 font-size 可达到适配效果

在开发中,我们只需要考虑两个问题:

  1. 针对不同的屏幕尺寸设置不同的 html font-size

  2. 将元素尺寸单位转为 rem

动态设置 html font-size

方法一:通过媒体查询设置 html font-size

思路:通过媒体查询根据不同屏幕尺寸设置不同的 html font-size

缺点:① 如果动态改变屏幕尺寸,不能实时更新、 ② 只能针对某个尺寸范围设置 html font-size

css 复制代码
@media screen and (min-width: 320px) {
    html {
        font-size: 20px;
    }
}

@media screen and (min-width: 375px) {
    html {
        font-size: 24px;
    }
}

@media screen and (min-width: 414px) {
    html {
        font-size: 28px;
    }
}

@media screen and (min-width: 480px) {
    html {
        font-size: 32px;
    }
}

.box {
    width: 5rem;
    height: 5rem;
    background-color: blue;
}

方法二:通过 JS 设置 html font-size

思路:通过监听屏幕尺寸的变化动态修改 html font-size

一般会将 html font-size 设置为屏幕宽度的 1/10,方便计算

js 复制代码
function setRemUnit() {
    const htmlEl = document.documentElement;
    const htmlFontSize = htmlEl.clientWidth / 10;
    htmlEl.style.fontSize = htmlFontSize + 'px';
}
setRemUnit();
window.addEventListener('resize', setRemUnit);

px 与 rem 的单位换算

假设原型图中屏幕宽度为 375px,现有一宽度为 100px 的 div。我们想将 100px 转成对应的 rem 值:

  1. 根元素 html 的 font-size = 375px / 10 = 37.5px (37.5px 即为 "基准字体大小")

  2. 元素的 rem 值 = 100px / 37.5px

手动计算

编写 scss 函数:

scss 复制代码
$baseFontSize: 37.5px; // 基准字体大小
@function pxToRem($pxValue) {
    @return $pxValue / $baseFontSize * 1rem;
}

使用 scss 函数编写样式:

scss 复制代码
.example {
    font-size: pxToRem(24px); // 将 24px 转换为对应的 rem 值
    margin: pxToRem(16px) pxToRem(8px); // 将 16px 和 8px 转换为对应的 rem 值
}

工程化自动计算

安装 postcss-pxtorem 依赖包、配置 webpack.config.js 文件:

bash 复制代码
npm install postcss-pxtorem -D
js 复制代码
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const postcssPxToRem = require('postcss-pxtorem');

const stylesHandler = MiniCssExtractPlugin.loader;
const postcssLoader = {
    loader: 'postcss-loader',
    options: {
        postcssOptions: {
            plugins: [
                postcssPxToRem({
                    rootValue: 37.5, // 基准字体大小, 默认 16
                    propList: ['*'], // 转换的属性, 默认 ['font', 'font-size', 'line-height', 'letter-spacing']
                }),
            ],
        },
    },
};

const config = {
    // ...
    module: {
        // ...
        rules: [
            // ...
            {
                test: /\.css$/i,
                use: [stylesHandler, 'css-loader', postcssLoader],
            },
        ],
    },
};

正常编写样式,px 会自动转换为 rem:

css 复制代码
.example {
    font-size: 24px; /* 将转换为 0.64rem */
    margin: 16px 8px; /* 将转换为 0.43rem 0.21rem */
}

vw 单位

100vw 相当于整个视口的宽度 innerWidth,1vw 相当于视口宽度的 1%,将 px 转换为 vw 即可完成适配

vw 相对于 rem 的优势:不需要考虑 html font-size 的问题

事实上,rem 作为一种过渡的方案,它利用的也是 vw 的思想

px 与 vw 的单位转换

假设原型图中屏幕宽度为 375px,有一宽度为 100px 的 div。我们需要将 100px 转成对应的 vw 值:

  1. 1vw = 375px / 100 = 3.75px
  2. 元素的 vw 值 = 100px / 3.75px

手动计算

编写 scss 函数:

scss 复制代码
$baseWidth: 375px; // 设计稿宽度
@function pxToVw($pxValue) {
    @return $pxValue / $baseWidth * 100vw;
}

使用 scss 函数编写样式:

scss 复制代码
.example {
    width: pxToVw(100px); // 将 100px 转换为对应的 vw 值
    margin: pxToVw(16px) pxToVw(8px); // 将 16px 和 8px 转换为对应的 vw 值
}

工程化自动计算

安装 postcss-px-to-viewport-8-plugin 依赖包、配置 webpack.config.js 文件:

bash 复制代码
npm install postcss-px-to-viewport-8-plugin -D
js 复制代码
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const postcssPxToViewport = require('postcss-px-to-viewport-8-plugin');

const stylesHandler = MiniCssExtractPlugin.loader;
const postcssLoader = {
    loader: 'postcss-loader',
    options: {
        postcssOptions: {
            plugins: [
                postcssPxToViewport({
                    viewportWidth: 375, // 设计稿宽度, 默认 320
                }),
            ],
        },
    },
};

const config = {
    // ...
    module: {
        // ...
        rules: [
            // ...
            {
                test: /\.css$/i,
                use: [stylesHandler, 'css-loader', postcssLoader],
            },
        ],
    },
};

正常编写样式,px 会自动转换为 vw:

css 复制代码
.example {
    width: 100px; /* 将转换为 26.67vw */
    margin: 16px 8px; /* 将转换为 4.27vw 2.13vw */
}
相关推荐
WooaiJava7 分钟前
AI 智能助手项目面试技术要点总结(前端部分)
javascript·大模型·html5
R1nG8639 分钟前
多线程安全设计 CANN Runtime关键数据结构的锁优化
开发语言·cann
初次见面我叫泰隆10 分钟前
Qt——5、Qt系统相关
开发语言·qt·客户端开发
亓才孓15 分钟前
[Class的应用]获取类的信息
java·开发语言
开开心心就好23 分钟前
AI人声伴奏分离工具,离线提取伴奏K歌用
java·linux·开发语言·网络·人工智能·电脑·blender
爱喝白开水a27 分钟前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
Never_Satisfied27 分钟前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
董世昌4127 分钟前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
3GPP仿真实验室1 小时前
【Matlab源码】6G候选波形:OFDM-IM 增强仿真平台 DM、CI
开发语言·matlab·ci/cd
devmoon1 小时前
在 Polkadot 上部署独立区块链Paseo 测试网实战部署指南
开发语言·安全·区块链·polkadot·erc-20·测试网·独立链