前端项目统一适配规范(团队可直接落地)

前端项目统一适配规范(团队可直接落地)


做移动端 H5 开发,最头疼的不是写业务代码,而是——适配。

机型碎片化、iOS 安全区域、1px 细线、安卓软键盘… 每个坑都得踩一遍。更要命的是:团队里每个人踩坑的方式不一样,代码风格各异,后期维护成本直接拉满。

这篇文章是移动端适配系列的收尾篇,把前面 rem/vw 方案、安全区域、1px 细线的所有内容,整合成团队可直接落地的规范文档

复制粘贴就能用,不废话。


一、团队适配规范:选 rem 还是 vw

结论先行

场景
推荐方案
新项目 vw

(更简单,浏览器原生支持)
微信/支付宝小程序 rpx

(微信)或 upx(uni-app)
老项目或组件库 rem

(统一基准方便管理)
PC 端后台系统
固定 px + %

rem vs vw 深度对比

对比项
rem
vw
换算方式
手动换算或 postcss
插件自动转
基准设置
JS 动态设置或 postcss
插件自动算
浏览器支持
所有浏览器
IE9+,几乎全支持
代码可读性
需要基准计算
直接写设计稿 px
维护成本
基准改了要全改
插件配置一次搞定
适用场景
组件库、多项目统一基准
新项目、快速开发

团队选择建议

移动端 H5 项目 → vw

优点:插件自动转换,设计稿 px 值直接写缺点:依赖构建工具

多端小程序(uni-app)→ upx

优点:微信/支付宝/抖音全端兼容缺点:H5 端表现略有差异

需要统一基准的组件库 → rem

优点:所有项目使用同一基准,便于统一管理缺点:基准改了要全改

二、统一 CSS 重置模板

以下模板是移动端 H5 专用,直接复制到项目就能用。

/* ========== 1. CSS Reset ========== */* {  margin0;  padding0;  box-sizing: border-box;}
/* ========== 2. 全局字体设置 ========== */html {  font-sizecalc(100vw / 3.75); /* vw 方案基准 */  -webkit-font-smoothing: antialiased;  -moz-osx-font-smoothing: grayscale;  -webkit-text-size-adjust100%;  text-size-adjust100%;}
body {  font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Arial, 'PingFang SC''Hiragino Sans GB''Microsoft YaHei', sans-serif;  font-size0.14rem/* 设计稿 14px */  line-height1.5;  color#333;  background-color#f5f5f5;}
/* ========== 3. 禁止默认行为 ========== */htmlbody {  overflow-x: hidden; /* 禁止横向溢出 */  width100%;  min-height100%;}
a {  text-decoration: none;  color: inherit;}
button {  border: none;  outline: none;  background: none;  cursor: pointer;}
inputtextarea {  outline: none;  border: none;  resize: none;}
/* ========== 4. 图片和媒体 ========== */imgsvgvideo {  display: block;  max-width100%;}
img {  width100%;  height: auto;}
/* ========== 5. 安全区域适配 ========== */body {  /* 兼容旧版 iOS */  padding-topconstant(safe-area-inset-top);  padding-bottomconstant(safe-area-inset-bottom);  /* 兼容新版 iOS */  padding-topenv(safe-area-inset-top);  padding-bottomenv(safe-area-inset-bottom);}
/* ========== 6. iOS 滑动惯性 ========== */body {  -webkit-overflow-scrolling: touch;}
/* ========== 7. 1px 细线工具类 ========== */.scale-bottom::after {  content'';  display: block;  height1px;  background#eee;  transformscaleY(0.5);}
.scale-top::before {  content'';  display: block;  height1px;  background#eee;  transformscaleY(0.5);}

⚠️ 避坑指南

  1. box-sizing: border-box 必须全局设置,不然 padding 会撑大盒子

  2. overflow-x: hidden 必须加,不然横向滚动条会出来捣乱

  3. -webkit-font-smoothing 加了字体渲染更清晰,特别是苹果设备上


三、全局适配公共样式

公共样式文件(common.css)

/* ========== 全局适配公共样式 ========== */
/* 安全区域 - 顶部 */.safe-top {  padding-topenv(safe-area-inset-top);  padding-leftenv(safe-area-inset-left);  padding-rightenv(safe-area-inset-right);}
/* 安全区域 - 底部 */.safe-bottom {  padding-bottomenv(safe-area-inset-bottom);  padding-leftenv(safe-area-inset-left);  padding-rightenv(safe-area-inset-right);}
/* 固定顶部导航 */.fixed-header {  position: fixed;  top0;  left0;  right0;  padding-topenv(safe-area-inset-top);  background#fff;  z-index100;}
/* 固定底部按钮 */.fixed-footer {  position: fixed;  bottom0;  left0;  right0;  padding-bottomenv(safe-area-inset-bottom);  background#fff;  box-shadow0 -1px 10px rgba(0,0,0,0.1);  z-index100;}
/* 固定底部 TabBar */.fixed-tabbar {  position: fixed;  bottom0;  left0;  right0;  heightcalc(50px + env(safe-area-inset-bottom));  padding-bottomenv(safe-area-inset-bottom);  background#fff;  border-top1px solid #eee;  z-index100;}
/* 页面主体 - 顶部导航用 */.page-with-header {  padding-topcalc(44px + env(safe-area-inset-top));  min-height100vh;}
/* 页面主体 - 底部按钮用 */.page-with-footer {  padding-bottomcalc(60px + env(safe-area-inset-bottom));}
/* 页面主体 - 两边都有 */.page-with-both {  padding-topcalc(44px + env(safe-area-inset-top));  padding-bottomcalc(60px + env(safe-area-inset-bottom));}
/* 1px 下边框 */.border-bottom {  position: relative;}.border-bottom::after {  content'';  position: absolute;  left0;  right0;  bottom0;  height1px;  background#eee;  transformscaleY(0.5);  transform-origin: bottom;}
/* 1px 上边框 */.border-top {  position: relative;}.border-top::before {  content'';  position: absolute;  left0;  right0;  top0;  height1px;  background#eee;  transformscaleY(0.5);  transform-origin: top;}
/* 文字超出省略 */.text-ellipsis {  overflow: hidden;  text-overflow: ellipsis;  white-space: nowrap;}
.text-ellipsis-2 {  display: -webkit-box;  -webkit-box-orient: vertical;  -webkit-line-clamp: 2;  overflow: hidden;  text-overflow: ellipsis;}

全局工具类(utils.css)

/* ========== 全局工具类 ========== */
/* 文字颜色 */.text-primary { color#007aff; }.text-secondary { color#666; }.text-placeholder { color#999; }.text-white { color#fff; }
/* 文字大小 */.text-xs { font-size0.12rem; }   /* 12px */.text-sm { font-size0.12rem; }   /* 12px */.text-base { font-size0.14rem; } /* 14px */.text-lg { font-size0.16rem; }   /* 16px */.text-xl { font-size0.18rem; }   /* 18px */.text-2xl { font-size0.2rem; }   /* 20px */
/* 间距 */.mt-1 { margin-top0.1rem; }.mt-2 { margin-top0.2rem; }.mt-3 { margin-top0.3rem; }.mb-1 { margin-bottom0.1rem; }.mb-2 { margin-bottom0.2rem; }.mb-3 { margin-bottom0.3rem; }.p-1 { padding0.1rem; }.p-2 { padding0.2rem; }.p-3 { padding0.3rem; }
/* 布局 */.flex { display: flex; }.flex-center { display: flex; align-items: center; justify-content: center; }.flex-between { display: flex; align-items: center; justify-content: space-between; }.flex-col { display: flex; flex-direction: column; }.flex-1 { flex1; }
/* 居中 */.text-center { text-align: center; }
/* 圆角 */.rounded { border-radius0.08rem; }    /* 8px */.rounded-lg { border-radius0.16rem; } /* 16px */.rounded-full { border-radius50%; }

四、直接可复制的项目初始化模板

方案一:Vite + Vue3 项目(H5 最推荐)

# 创建项目npm create vite@latest my-h5 -- --template vue
# 安装适配相关依赖npm install postcss postcss-px-to-viewport postcss-px-to-viewport-rotate postcss-aspect-ratio-mini postcss-write-svg postcss-viewport-units -D
// vite.config.jsimport { defineConfig } from 'vite'import vue from '@vitejs/plugin-vue'
export default defineConfig({  plugins: [vue()],  css: {    postcss: {      plugins: [        // vw 适配插件        require('postcss-px-to-viewport')({          viewportWidth375, // 设计稿宽度          viewportHeight812, // 设计稿高度          unitPrecision5, // 精度          viewportUnit'vw',          fontViewportUnit'vw',          selectorBlackList: ['.ignore''.hairlines'], // 不转换的选择器          minPixelValue1,          mediaQueryfalse        })      ]    }  }})
/* src/styles/reset.css - 完整重置模板 */@import './reset.css';@import './common.css';@import './utils.css';
// src/main.jsimport { createApp } from 'vue'import App from './App.vue'import './styles/reset.css'import './styles/common.css'import './styles/utils.css'
createApp(App).mount('#app')
<!-- index.html --><!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, viewport-fit=cover">  <meta name="apple-mobile-web-app-capable" content="yes">  <meta name="apple-mobile-web-app-status-bar-style" content="black">  <meta name="format-detection" content="telephone=no">  <title>项目名称</title></head><body>  <div id="app"></div>  <script type="module" src="/src/main.js"></script></body></html>

方案二:uni-app 项目(小程序 + H5)

// pages.json{  "globalStyle": {    "navigationBarTextStyle": "black",    "navigationBarTitleText": "项目名称",    "navigationBarBackgroundColor": "#ffffff",    "backgroundColor": "#f5f5f5",    "app-plus": {      "titleNView": {        "autoBackButton": true,        "buttonsWithSefArea": true      },      "safeArea": "auto"    }  }}
/* uni-app H5 适配:不需要 postcss,用 rpx 天然适配 */
/* global.css */page {  background-color#f5f5f5;}
/* 安全区域 */.safe-area-top {  padding-topconstant(safe-area-inset-top);  padding-topenv(safe-area-inset-top);}.safe-area-bottom {  padding-bottomconstant(safe-area-inset-bottom);  padding-bottomenv(safe-area-inset-bottom);}
/* 固定底部按钮 */.fixed-bottom {  position: fixed;  bottom0;  left0;  right0;  padding-bottomconstant(safe-area-inset-bottom);  padding-bottomenv(safe-area-inset-bottom);}

方案三:纯 H5 项目(最简单的,无需构建工具)

<!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, viewport-fit=cover">  <title>移动端 H5 模板</title>  <style>    /* CSS Reset */    * { margin0padding0box-sizing: border-box; }
    html {      font-sizecalc(100vw / 3.75);      -webkit-font-smoothing: antialiased;    }
    body {      font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Arial, sans-serif;      font-size0.14rem;      line-height1.5;      color#333;      background-color#f5f5f5;      overflow-x: hidden;      /* 安全区域 */      padding-topenv(safe-area-inset-top);      padding-bottomenv(safe-area-inset-bottom);      -webkit-overflow-scrolling: touch;    }  </style></head><body>  <div id="app"></div></body></html>

五、团队规范落地建议

1. 规范文档维护

  • 把 reset.css / common.css / utils.css 放到团队组件库

  • 每次新项目直接复制,不需要重写

  • 有更新时统一升级版本号

2. ESLint + Prettier 配置

// .eslintrc.json{  "rules": {    "no-mixed-spaces-and-tabs": "warn",    "no-unused-vars": "error"  }}

3. Git Hooks 检查

推荐使用 husky + lint-staged,提交前自动检查代码规范,避免不同人写出不同风格的适配代码。

4. Code Review 重点

新人 PR 必查项:

  • [ ] 是否引入了适配基础样式(reset.css)

  • [ ] 固定定位元素是否加了安全区域

  • [ ] 字体大小是否为偶数(避免奇数导致模糊)

  • [ ] 是否有遗漏的 px 单位


六、适配规范速查清单

📋 复制到 Notion/Confluence,团队成员每次上线前自查

必选项 ✅

[ ] viewport meta 加 viewport-fit=cover[ ] CSS Reset 引入[ ] rem/vw 适配方案确定并配置[ ] 安全区域适配(iPhone X 及以上)[ ] 禁止横向溢出(overflow-x: hidden)

建议项 ⚡

[ ] 公共工具类(安全区域、1px 边框)[ ] PostCSS 插件配置[ ] 图片 max-width100%[ ] -webkit-overflow-scrolling: touch

禁止项 🚫

[ ] 禁止用 px 写移动端具体尺寸(除非固定不变的值)[ ] 禁止 fixed 元素不加安全区域[ ] 禁止横向 overflow-x 未设置[ ] 禁止字体大小使用奇数

写在最后

适配这件事,说难不难,说简单也不简单。

关键在于:团队统一规范,一次性搞定,以后不再踩坑。

这篇文章的模板都是经过实战验证的,复制粘贴就能用。建议把公共样式文件做成团队模板库,新项目直接套用,省时省力。

如果觉得有用,欢迎转发给团队同学,一起告别适配噩梦。

 

分享到: 文章二维码
© 版权声明

暂无评论

您必须登录才能参与评论!
暂无评论...