页面自适应/响应式方法

154 阅读1分钟

修改页面基础font-size,使得rem根据不同设备进行变化

// 举例nuxt 里在中间件里自执行该方法 
((doc, win) => {
  const docEl = doc.documentElement;
  const resizeEvt = ('orientationchange' in window ? 'orientationchange' : 'resize');
  const recalc = () => {
    let clientWidth = docEl.clientWidth;
    if (clientWidth <= 1024) {
      clientWidth = 1024;
    }
    if (!clientWidth) {
      return; 
    }
    // 将html节点的font-size设置为页面clientWidth(布局视口)的某个比列,即1rem就等于页面布局视口的某个比列
    // docEl.style.fontSize = 100 * (clientWidth / 1440) + 'px';
    docEl.style.fontSize = 100 + 'px';
  };
  if (!doc.addEventListener) {
    return; 
  }
  win.addEventListener(resizeEvt, recalc, false);
  doc.addEventListener('DOMContentLoaded', recalc, false);
  /* eslint-enable no-undef */
})(document, window);

px 自动转换为 vw

安装插件

npm install postcss-px-to-viewport --save-dev

webpack 配置

module.exports = {
  plugins: {
    // ...
    'postcss-px-to-viewport': {
      // options
      unitToConvert: 'px',    // 需要转换的单位,默认为"px"
      viewportWidth: 750,     // 设计稿的视窗宽度
      unitPrecision: 5,       // 单位转换后保留的精度
      propList: ['*', '!font-size'],        // 能转化为 vw 的属性列表
      viewportUnit: 'vw',     // 希望使用的视窗单位
      fontViewportUnit: 'vw', // 字体使用的视窗单位
      selectorBlackList: [],  // 需要忽略的 CSS 选择器,不会转为视窗单位,使用原有的 px 等单位
      minPixelValue: 1,       // 设置最小的转换数值,如果为 1 的话,只有大于 1 的值会被转换
      mediaQuery: false,      // 媒体查询里的单位是否需要转换单位
      replace: true,          // 是否直接更换属性值,而不添加备用属性
      exclude: undefined,     // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
      include: /\/src\//,     // 如果设置了include,那将只有匹配到的文件才会被转换
      landscape: false,       // 是否添加根据 landscapeWidth 生成的媒体查询条件
      landscapeUnit: 'vw',    // 横屏时使用的单位
      landscapeWidth: 1125,   // 横屏时使用的视窗宽度
    },
  },
};

标注不需要转换的属性

 /* px-to-viewport-ignore-next —> 下一行不进行转换 */
 /* px-to-viewport-ignore —> 当前行不进行转换 */
 
/* example input: */
.class {
  /* px-to-viewport-ignore-next */
  width: 10px;
  padding: 10px;
  height: 10px; /* px-to-viewport-ignore */
}

/* example output: */
.class {
  width: 10px; 
  padding: 3.125vw;
  height: 10px;
}

行内样式

当你需要写行内样式的代码(style)时,postcss-px-to-viewport插件无法进行px单位无法转换,需要手动计算vw。 可以通过js添加、修改、删除 className 的方式进行处理

根据不同设备,图片高清的问题

图片高清的问题:

  • 适用普通屏的图片在 retina 屏中,图片展示就会显得模糊;
  • 适用 retina 屏的图片在普通屏中,图片展示就会缺少色差、没有锐利度,并且浪费带宽;

所以如果对性能、美观要求很高的场景,需要根据 dpr 区分使用对应的图片,css 写法如下:

[data-dpr="1"] .hello {
  background-image: url(image@1x.jpg);

[data-dpr="2"] .hello {
  background-image: url(image@2x.jpg);
}
  
[data-dpr="3"] .hello {
  background-image: url(image@3x.jpg);
}