1. 为什么移动端适配这么难做前端开发的朋友应该都深有体会移动端适配简直就是个磨人的小妖精。我刚开始接触移动端开发时经常遇到这样的场景在iPhone 6上看着挺完美的页面换到iPhone 12上就变得乱七八糟在安卓机上测试没问题到了iOS上又出现各种错位。最崩溃的是现在市面上光是安卓机型就有上千种不同的屏幕尺寸和分辨率。传统的px单位在移动端完全不够用。举个例子如果你给一个按钮设置了固定宽度100px在375px宽的iPhone 6上看着还行但在414px宽的iPhone 8 Plus上就显得太小到了828px宽的iPhone 11上更是小得可怜。这就是为什么我们需要更智能的适配方案。2. remflexible.js方案原理2.1 rem单位的基本概念remroot em是CSS3新增的相对单位它相对于根元素html的字体大小。比如html { font-size: 16px; }那么1rem就等于16px2rem就是32px以此类推。这种相对单位的妙处在于只要改变根元素的字体大小整个页面的尺寸都会跟着等比缩放。2.2 flexible.js的工作原理flexible.js是淘宝团队开源的一个移动端适配解决方案它的核心思想很简单把屏幕宽度分成10份设置html的font-size为屏幕宽度的1/10所有尺寸都用rem表示比如在750px的设计稿上html字体大小设为75px750/10一个150px宽的按钮就是2rem150/75当页面在375px宽的设备上打开时html字体大小自动变为37.5px375/10按钮宽度仍然是2rem但实际显示为75px2×37.5正好是设计稿尺寸的一半3. 完整实现步骤3.1 准备工作首先需要下载flexible.js可以直接从GitHub获取// 引入flexible.js script srcflexible.js/script然后在HTML头部添加viewport设置meta nameviewport contentwidthdevice-width, initial-scale1.0, maximum-scale1.0, minimum-scale1.0, user-scalableno3.2 设计稿转换技巧假设我们拿到的设计稿宽度是750px设置html的基准font-size为75px750/10在设计稿上量得的尺寸除以75得到rem值比如设计稿上一个按钮宽度150px → 150/752rem字体大小24px → 24/750.32rem为了提高开发效率可以使用VS Code插件px to rem设置基准值为75这样输入px值时会自动转换为rem。3.3 实际项目中的CSS编写来看一个实际的CSS例子/* 基准设置 */ html { font-size: 75px; /* 750px设计稿的基准 */ } body { max-width: 10rem; /* 相当于750px */ margin: 0 auto; font-size: 0.32rem; /* 相当于24px */ } /* 组件样式 */ .button { width: 2rem; /* 150px */ height: 0.8rem; /* 60px */ line-height: 0.8rem; font-size: 0.32rem; border-radius: 0.4rem; /* 30px */ }4. 常见问题与解决方案4.1 1px边框问题在高清屏上直接设置1px边框会显得很粗。解决方案.border { position: relative; } .border::after { content: ; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px; background: #ddd; transform: scaleY(0.5); }4.2 图片适配对于需要适配不同屏幕的图片可以使用多倍图方案.logo { width: 1rem; height: 1rem; background-image: url(logo2x.png); background-size: 1rem 1rem; }4.3 字体大小限制为了防止字体在小屏幕上过小可以设置最小字体body { font-size: 0.32rem; min-font-size: 12px; }5. 与其他方案的对比5.1 与vw/vh方案的比较vw视窗宽度单位也是一个不错的适配方案但存在以下问题兼容性略差特别是低版本安卓计算不如rem直观无法设置最大/最小限制5.2 与媒体查询的比较媒体查询需要为不同断点编写多套样式维护成本高。而remflexible.js只需要一套样式就能适配所有屏幕。5.3 与百分比布局的比较百分比布局在处理嵌套元素时计算复杂而且无法很好地控制字体大小等属性。rem方案则更加灵活统一。6. 实战案例电商首页适配让我们看一个实际的电商首页适配案例。假设设计稿宽度750px主要包含以下元素顶部搜索栏轮播图导航图标商品列表6.1 HTML结构div classsearch-bar input typetext placeholder搜索商品 /div div classbanner !-- 轮播图内容 -- /div div classnav-icons !-- 8个导航图标 -- /div div classproduct-list !-- 商品列表 -- /div6.2 CSS关键代码.search-bar { height: 0.88rem; padding: 0 0.3rem; } .banner { height: 3.6rem; } .nav-icons { display: flex; flex-wrap: wrap; } .nav-icon { width: 1.875rem; /* 750/4/10 */ height: 1.875rem; } .product-item { width: 3.6rem; margin-bottom: 0.3rem; }6.3 实际效果在不同设备上测试iPhone 6375px所有元素等比缩小一半iPhone 8 Plus414px元素尺寸自动调整华为Mate 30392px完美适配7. 性能优化建议7.1 减少重排重绘使用rem时要注意/* 不好的写法 */ .box { width: calc(2rem - 0.5rem); } /* 好的写法 */ .box { width: 1.5rem; }7.2 合理使用缓存对于不常变化的元素可以设置固定rem值减少JavaScript计算// 在flexible.js中 if (screenWidth 768) { docEl.style.fontSize 75px; }7.3 图片懒加载结合rem实现响应式图片懒加载const lazyLoad new LazyLoad({ elements_selector: .lazy, callback_loaded: function(el) { el.style.width el.getAttribute(data-width) rem; } });8. 进阶技巧8.1 多主题适配通过修改html字体大小实现主题切换function setTheme(theme) { const docEl document.documentElement; if (theme large) { docEl.style.fontSize 85px; } else { docEl.style.fontSize 75px; } }8.2 横竖屏适配监听orientationchange事件window.addEventListener(orientationchange, function() { flexible.rem2px(document.documentElement); });8.3 与Flexbox结合rem与flex布局是天作之合.product-list { display: flex; flex-wrap: wrap; justify-content: space-between; } .product-item { width: 3.6rem; margin-bottom: 0.3rem; }在实际项目中我发现这套方案特别适合内容型页面和电商网站。刚开始使用时需要适应rem的计算方式但熟悉之后开发效率会大幅提升。特别是在迭代过程中只需要调整设计稿尺寸就能快速适配新机型再也不用为各种屏幕尺寸发愁了。