前端项目统一适配规范(团队可直接落地)
做移动端 H5 开发,最头疼的不是写业务代码,而是——适配。
机型碎片化、iOS 安全区域、1px 细线、安卓软键盘… 每个坑都得踩一遍。更要命的是:团队里每个人踩坑的方式不一样,代码风格各异,后期维护成本直接拉满。
这篇文章是移动端适配系列的收尾篇,把前面 rem/vw 方案、安全区域、1px 细线的所有内容,整合成团队可直接落地的规范文档。
复制粘贴就能用,不废话。
一、团队适配规范:选 rem 还是 vw
结论先行
|
|
|
|---|---|
| 新项目 | vw
|
| 微信/支付宝小程序 | rpx
|
| 老项目或组件库 | rem
|
| PC 端后台系统 |
|
rem vs vw 深度对比
|
|
|
|
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
团队选择建议
移动端 H5 项目 → vw
优点:插件自动转换,设计稿 px 值直接写缺点:依赖构建工具
多端小程序(uni-app)→ upx
优点:微信/支付宝/抖音全端兼容缺点:H5 端表现略有差异
需要统一基准的组件库 → rem
优点:所有项目使用同一基准,便于统一管理缺点:基准改了要全改
二、统一 CSS 重置模板
以下模板是移动端 H5 专用,直接复制到项目就能用。
/* ========== 1. CSS Reset ========== */* {margin: 0;padding: 0;box-sizing: border-box;}/* ========== 2. 全局字体设置 ========== */html {font-size: calc(100vw / 3.75); /* vw 方案基准 */-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;-webkit-text-size-adjust: 100%;text-size-adjust: 100%;}body {font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Arial, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;font-size: 0.14rem; /* 设计稿 14px */line-height: 1.5;color: #333;background-color: #f5f5f5;}/* ========== 3. 禁止默认行为 ========== */html, body {overflow-x: hidden; /* 禁止横向溢出 */width: 100%;min-height: 100%;}a {text-decoration: none;color: inherit;}button {border: none;outline: none;background: none;cursor: pointer;}input, textarea {outline: none;border: none;resize: none;}/* ========== 4. 图片和媒体 ========== */img, svg, video {display: block;max-width: 100%;}img {width: 100%;height: auto;}/* ========== 5. 安全区域适配 ========== */body {/* 兼容旧版 iOS */padding-top: constant(safe-area-inset-top);padding-bottom: constant(safe-area-inset-bottom);/* 兼容新版 iOS */padding-top: env(safe-area-inset-top);padding-bottom: env(safe-area-inset-bottom);}/* ========== 6. iOS 滑动惯性 ========== */body {-webkit-overflow-scrolling: touch;}/* ========== 7. 1px 细线工具类 ========== */.scale-bottom::after {content: '';display: block;height: 1px;background: #eee;transform: scaleY(0.5);}.scale-top::before {content: '';display: block;height: 1px;background: #eee;transform: scaleY(0.5);}
⚠️ 避坑指南
-
box-sizing: border-box必须全局设置,不然 padding 会撑大盒子 -
overflow-x: hidden必须加,不然横向滚动条会出来捣乱 -
-webkit-font-smoothing加了字体渲染更清晰,特别是苹果设备上
三、全局适配公共样式
公共样式文件(common.css)
/* ========== 全局适配公共样式 ========== *//* 安全区域 - 顶部 */.safe-top {padding-top: env(safe-area-inset-top);padding-left: env(safe-area-inset-left);padding-right: env(safe-area-inset-right);}/* 安全区域 - 底部 */.safe-bottom {padding-bottom: env(safe-area-inset-bottom);padding-left: env(safe-area-inset-left);padding-right: env(safe-area-inset-right);}/* 固定顶部导航 */.fixed-header {position: fixed;top: 0;left: 0;right: 0;padding-top: env(safe-area-inset-top);background: #fff;z-index: 100;}/* 固定底部按钮 */.fixed-footer {position: fixed;bottom: 0;left: 0;right: 0;padding-bottom: env(safe-area-inset-bottom);background: #fff;box-shadow: 0 -1px 10px rgba(0,0,0,0.1);z-index: 100;}/* 固定底部 TabBar */.fixed-tabbar {position: fixed;bottom: 0;left: 0;right: 0;height: calc(50px + env(safe-area-inset-bottom));padding-bottom: env(safe-area-inset-bottom);background: #fff;border-top: 1px solid #eee;z-index: 100;}/* 页面主体 - 顶部导航用 */.page-with-header {padding-top: calc(44px + env(safe-area-inset-top));min-height: 100vh;}/* 页面主体 - 底部按钮用 */.page-with-footer {padding-bottom: calc(60px + env(safe-area-inset-bottom));}/* 页面主体 - 两边都有 */.page-with-both {padding-top: calc(44px + env(safe-area-inset-top));padding-bottom: calc(60px + env(safe-area-inset-bottom));}/* 1px 下边框 */.border-bottom {position: relative;}.border-bottom::after {content: '';position: absolute;left: 0;right: 0;bottom: 0;height: 1px;background: #eee;transform: scaleY(0.5);transform-origin: bottom;}/* 1px 上边框 */.border-top {position: relative;}.border-top::before {content: '';position: absolute;left: 0;right: 0;top: 0;height: 1px;background: #eee;transform: scaleY(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-size: 0.12rem; } /* 12px */.text-sm { font-size: 0.12rem; } /* 12px */.text-base { font-size: 0.14rem; } /* 14px */.text-lg { font-size: 0.16rem; } /* 16px */.text-xl { font-size: 0.18rem; } /* 18px */.text-2xl { font-size: 0.2rem; } /* 20px *//* 间距 */.mt-1 { margin-top: 0.1rem; }.mt-2 { margin-top: 0.2rem; }.mt-3 { margin-top: 0.3rem; }.mb-1 { margin-bottom: 0.1rem; }.mb-2 { margin-bottom: 0.2rem; }.mb-3 { margin-bottom: 0.3rem; }.p-1 { padding: 0.1rem; }.p-2 { padding: 0.2rem; }.p-3 { padding: 0.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 { flex: 1; }/* 居中 */.text-center { text-align: center; }/* 圆角 */.rounded { border-radius: 0.08rem; } /* 8px */.rounded-lg { border-radius: 0.16rem; } /* 16px */.rounded-full { border-radius: 50%; }
四、直接可复制的项目初始化模板
方案一: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')({viewportWidth: 375, // 设计稿宽度viewportHeight: 812, // 设计稿高度unitPrecision: 5, // 精度viewportUnit: 'vw',fontViewportUnit: 'vw',selectorBlackList: ['.ignore', '.hairlines'], // 不转换的选择器minPixelValue: 1,mediaQuery: false})]}}})
/* 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 --><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-top: constant(safe-area-inset-top);padding-top: env(safe-area-inset-top);}.safe-area-bottom {padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom);}/* 固定底部按钮 */.fixed-bottom {position: fixed;bottom: 0;left: 0;right: 0;padding-bottom: constant(safe-area-inset-bottom);padding-bottom: env(safe-area-inset-bottom);}
方案三:纯 H5 项目(最简单的,无需构建工具)
<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 */* { margin: 0; padding: 0; box-sizing: border-box; }html {font-size: calc(100vw / 3.75);-webkit-font-smoothing: antialiased;}body {font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Arial, sans-serif;font-size: 0.14rem;line-height: 1.5;color: #333;background-color: #f5f5f5;overflow-x: hidden;/* 安全区域 */padding-top: env(safe-area-inset-top);padding-bottom: env(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-width: 100%[ ] -webkit-overflow-scrolling: touch
禁止项 🚫
[ ] 禁止用 px 写移动端具体尺寸(除非固定不变的值)[ ] 禁止 fixed 元素不加安全区域[ ] 禁止横向 overflow-x 未设置[ ] 禁止字体大小使用奇数
写在最后
适配这件事,说难不难,说简单也不简单。
关键在于:团队统一规范,一次性搞定,以后不再踩坑。
这篇文章的模板都是经过实战验证的,复制粘贴就能用。建议把公共样式文件做成团队模板库,新项目直接套用,省时省力。
如果觉得有用,欢迎转发给团队同学,一起告别适配噩梦。




