Skip to content

postcss移动端适配

TIP

是不是还在用固定 px 写移动端页面?用 vw 可以更好的适配移动端,包括 vw、rem、flex 布局和 viewport 配置,页面在各种移动设备上都能完美展示

WARNING

1vw = 视口宽度的 1%

优势

  • 直接基于视口尺寸,无需额外计算
  • 支持所有现代浏览器
  • 可以实现元素的等比例缩放
  • 与 viewport 布局配合使用效果更佳

缺点

  • 部分复杂布局需要配合 calc () 使用
  • 字体大小使用 vw 可能导致可读性问题

vw适配方案

安装命令

js
yarn add postcss-px-to-viewport@1.1.1 -D
yarn add postcss-px-to-viewport@1.1.1 -D

创建postcss.config.js文件

js
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375, // 设计稿宽度
      viewportHeight: 667, // 设计稿高度
      unitPrecision: 5, // 转换后的vw精度
      viewportUnit: 'vw', // 转换单位
      selectorBlackList: ['ignore', 'tab-bar', 'tab-bar-item'], // 不需要转换的类名
      minPixelValue: 1, // 小于等于1px不转换
      mediaQuery: false, // 是否转换媒体查询中的px
      exclude: [/node_modules/], // 排除node_modules目录
    },
    
    // 自动添加浏览器前缀
    'autoprefixer': {
      overrideBrowserslist: ['last 2 versions', 'iOS >= 8', 'Android >= 4.4']
    }
  }
}
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375, // 设计稿宽度
      viewportHeight: 667, // 设计稿高度
      unitPrecision: 5, // 转换后的vw精度
      viewportUnit: 'vw', // 转换单位
      selectorBlackList: ['ignore', 'tab-bar', 'tab-bar-item'], // 不需要转换的类名
      minPixelValue: 1, // 小于等于1px不转换
      mediaQuery: false, // 是否转换媒体查询中的px
      exclude: [/node_modules/], // 排除node_modules目录
    },
    
    // 自动添加浏览器前缀
    'autoprefixer': {
      overrideBrowserslist: ['last 2 versions', 'iOS >= 8', 'Android >= 4.4']
    }
  }
}

rem适配方案

安装命令

js
yarn add postcss-pxtorem -D
yarn add postcss-pxtorem -D

创建postcss.config.js文件

js
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-pxtorem': {
      rootValue: 37.5, // 设计稿宽度的1/10(假设设计稿是375px)
      unitPrecision: 5,
      propList: ['*'], // 需要转换的属性,*表示所有属性
      selectorBlackList: [],
      replace: true,
      mediaQuery: false,
      minPixelValue: 0,
    }
  }
}
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-pxtorem': {
      rootValue: 37.5, // 设计稿宽度的1/10(假设设计稿是375px)
      unitPrecision: 5,
      propList: ['*'], // 需要转换的属性,*表示所有属性
      selectorBlackList: [],
      replace: true,
      mediaQuery: false,
      minPixelValue: 0,
    }
  }
}

添加 JS 动态设置根字体大小

js
// 在入口文件main.js中添加
function setRemUnit() {
  const docEl = document.documentElement;
  const width = docEl.clientWidth;
  docEl.style.fontSize = width / 10 + 'px'; // 1rem = viewport宽度的1/10
}

// 监听窗口大小变化
window.addEventListener('resize', setRemUnit);

// 初始化
setRemUnit();
// 在入口文件main.js中添加
function setRemUnit() {
  const docEl = document.documentElement;
  const width = docEl.clientWidth;
  docEl.style.fontSize = width / 10 + 'px'; // 1rem = viewport宽度的1/10
}

// 监听窗口大小变化
window.addEventListener('resize', setRemUnit);

// 初始化
setRemUnit();

混合使用 vw 和 rem

TIP

1.布局尺寸:使用 vw

2.字体大小:使用 rem

3.固定尺寸:使用 px(添加忽略注释)

js
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375,
      unitPrecision: 5,
      viewportUnit: 'vw',
      selectorBlackList: ['font-size'], // 字体大小不转换为vw
      minPixelValue: 1,
    },
    'postcss-pxtorem': {
      rootValue: 16, // 基准字体大小
      propList: ['font-size'], // 只转换字体大小
    }
  }
}
// postcss.config.js
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      viewportWidth: 375,
      unitPrecision: 5,
      viewportUnit: 'vw',
      selectorBlackList: ['font-size'], // 字体大小不转换为vw
      minPixelValue: 1,
    },
    'postcss-pxtorem': {
      rootValue: 16, // 基准字体大小
      propList: ['font-size'], // 只转换字体大小
    }
  }
}

按需加载资源

js
// 根据屏幕尺寸加载不同资源
function loadResponsiveResources() {
  const width = window.innerWidth;
  if (width < 768) {
    // 加载移动端资源
  } else {
    // 加载桌面端资源
  }
}
// 根据屏幕尺寸加载不同资源
function loadResponsiveResources() {
  const width = window.innerWidth;
  if (width < 768) {
    // 加载移动端资源
  } else {
    // 加载桌面端资源
  }
}
方案优点缺点适用场景
vw简单直接,无需 JS 计算字体大小控制不便简单移动端页面
rem可通过 JS 动态调整需要额外 JS 代码复杂响应式设计
vw + rem结合两者优点配置稍复杂大型项目
混合方案灵活应对各种场景学习成本高复杂项目

程序员小洛文档