[react]Next.js之自适应布局和高清屏幕适配解决方案

序言

阅读前首先了解即将要用到的两个包的作用

1.postcss-pxtorem

  • 自动将 CSS 中的 px 单位转换为 rem 单位
  • 按照设计稿尺寸直接写 px 值,由插件自动计算 rem 值

2.amfe-flexible

  • 动态设置根元素的 font-size(即 1rem 的值)
  • 根据设备屏幕宽度和 DPR 调整页面缩放比例
  • 解决 1px 边框问题

工作流程

1.单独使用 postcss-pxtorem

  • CSS源码 → postcss-pxtorem转换 → 固定rem值的CSS → 浏览器渲染(无动态调整)

2.单独使用 amfe-flexible

  • 浏览器加载 → amfe-flexible执行 → 动态计算html的font-size → 开发者手动用JS计算rem值 → 页面渲染

3.搭配一起使用

  • 设计稿(1440px) → postcss-pxtorem(÷144) → CSS(rem) → 浏览器 → amfe-flexible动态计算 → 实际渲染

一: css文件的px自动转rem

1. 安装

$ npm i postcss-pxtorem -D

2. 配置文件

javascript 复制代码
// 修改根目录的postcss.config.mjs文件 ESM版
// 如果你的文件是postcss.config.js(CJS版), 自行百度教程
const config = {
  // 注意:你的项目是plugins: ["@tailwindcss/postcss"], 没关系可以改成下面的对象结构
  plugins: {
    "@tailwindcss/postcss": {}, 
    // 新增 postcss-pxtorem
    "postcss-pxtorem": {
      rootValue: 144, // 设计稿宽度/10 [注意: 如果不搭配amfe-flexible使用, 那么填写16即可, 因为1rem = 16px]
      propList: ["*", "!font*", "!font-size"], // 忽略字体相关属性,字体不需要rem
      exclude: /node_modules/i, // 排除 node_modules 文件
      minPixelValue: 2, // 小于 2px 不转换
      mediaQuery: false, // 不转换媒体查询中的 px
      selectorBlackList: ["html"], // 黑名单,不转换的选择器 [注意: 如果不搭配amfe-flexible使用, 这行可以注释]
    },

    // 可选的 autoprefixer(推荐添加, 让项目兼容性更好, 记得安装包npm i autoprefixer -D)
    autoprefixer: {
      overrideBrowserslist: ["last 2 versions", "> 1%"],
    },
  },
};

export default config;

二: 动态设置html的font-size

现在百度存在最多的是lib-flexible的教程(已停止维护), 今天开始新项目就用amfe-flexible吧

1. 安装

$ npm i amfe-flexible -S

2. 新建文件

javascript 复制代码
// 新建 AmfeFlexible.tsx , 与layout.tsx平级
'use client';

import { useEffect } from 'react';

export default function AmfeFlexible() {
  useEffect(() => {
    if (typeof window !== 'undefined') {
      import('amfe-flexible');
    }
  }, []);

  return null;
}
复制代码
// src目录下新建 @types\amfe-flexible\index.d.ts , 与app文件夹同级
declare module 'amfe-flexible' {
    const flexible: {
      init: (options?: {
        designWidth?: number;
        designHeight?: number;
        maxWidth?: number;
        minWidth?: number;
      }) => void;
    };
    export default flexible;
  }

3. 配置文件

javascript 复制代码
// 配置src/app下的 layout.tsx ,以下代码已精简, 新增内容已标注
import { AntdRegistry } from "@ant-design/nextjs-registry";
import zhCN from "antd/locale/zh_CN";
import { ConfigProvider } from "antd";
// 新增
import AmfeFlexible from "./AmfeFlexible";



export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="zh">
      <head>
        //新增
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
        />
      </head>
      <body>
        //新增
        <AmfeFlexible />
        <ConfigProvider locale={zhCN}>
          <AntdRegistry>{children}</AntdRegistry>
        </ConfigProvider>
      </body>
    </html>
  );
}

题外话

如果你web项目用tailwind, 那么上面的方案就行不通了, 目前我能想到的解决方案就是让ui设计的时候px尽量为@4的倍数.

因为tailwind的默认间距是0.25, 0.25*4=1, 在tailwind项目中, 如标题高度是64px, 这时候除以4, 得到16, 那么h-16 就写好了, 这样方便我们进行换算(如果你有自动转换方法一定要留言告诉我!)

可能会有人说用h-64px就好了, 但是不符合我适配多端的需求, 如果只有响应式的需求就用tailwind的sm, md, lg, xl, 2xl就好, ui出多尺寸设计图.

相关推荐
PYB39 小时前
【Web·JS·基础】函数的使用和展运算符...objs
前端·javascript
默_笙10 小时前
🚥 给 RAG 装一台心电监护仪:LangSmith 全链路观测(上)
前端·javascript
变与不变80612 小时前
js同步和异步难点重点详解
开发语言·javascript·ecmascript
Dovis(誓平步青云)12 小时前
多个链接不等于多份证据,新闻核验看板怎样合并来源
java·服务器·前端·javascript·人工智能·pdf·电脑
Dovis(誓平步青云)13 小时前
几个方案来回选不定?做一个随时切换的候选推荐页
android·java·服务器·开发语言·javascript·数据库·智能化
可乐鸡翅yeah_14 小时前
fmp4 碎片 MP4 格式 HLS 流,和传统 TS 分片有什么不一样
开发语言·javascript·ios·音视频·safari·m3u8·m3u8在线播放
ss27315 小时前
AI全栈实战 | 2.3-01 组件库实战:Element Plus 怎么搭出专业界面,过度封装为什么成维护负担
前端·javascript·elementui·vue
福兮说16 小时前
URL 编码的七个坑:c++ 传到后端变空格、%25 套娃、截断 emoji 直接报错
开发语言·前端·javascript·node.js·url
小的时候可菜了16 小时前
JS 异步的本质:从单线程到 thenable(一条进化链)
开发语言·前端·javascript
可乐鸡翅yeah_16 小时前
hls.js 配置 loadStartPosition,点播起始播放位置踩坑
开发语言·javascript·网络协议·ecmascript·m3u8在线