0
点赞
收藏
分享

微信扫一扫

移动适配 viewport方案

勇敢乌龟 2022-04-30 阅读 18

viewport适配方案

  • vw:是 viewport’s width 的简写,1vw 等于 window.innerWidth 的 1%;

  • vh:和 vw 类似,是 viewport’s height 的简写,1vh 等于 window.innerHeihgt 的 1%;

  • vmin:vmin 的值是当前 vw 和 vh 中较小的值;

  • vmax:vmax 的值是当前 vw 和 vh 中较大的值;

    .logo {
      font-size: 10vw; // 1vw = 750px * 1% = 7.5px
    }
    

1. meta标签

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

2. px 自动转换为 vw

2.1 安装插件

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

2.2 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,   // 横屏时使用的视窗宽度
    },
  },
};

2.3 效果展示

.hello {
  color: #333;
  font-size: 28px;
}

在这里插入图片描述

3. 标注不需要转换的属性

  • /* 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;
}

4. Retina 屏问题

考虑 Retina 屏场景,可能对图片的高清程度、1px 等场景有需求,所以我们预留判断 Retina 屏坑位。 相关方案如下:在入口的 html 页面进行 dpr 判断,以及 data-dpr 的设置;然后在项目的 css 文件中就可以根据 data-dpr 的值根据不同的 dpr 写不同的样式类;

4.1 index.html文件

// index.html 文件
<script>
    const dpr = devicePixelRatio >= 3? 3: devicePixelRatio >= 2? 2: 1;
    document.documentElement.setAttribute('data-dpr', dpr);
</script>

4.2 样式文件

[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);
}

postcss-px-to-viewport插件无法对行内样式进行单位转换,因此需要手动计算,或使用className的方式操作。

5. 1px 的问题

5.1 transform: scale(0.5)

可以使用 transform: scale(0.5) 进行 X、Y 轴的缩放,如下示例所示

.class1 {
  height: 1px; 
  transform: scaleY(0.5);
}

5.2 推荐方案,伪元素

.calss1 {
  position: relative;
  &::after {
    content:"";
    position: absolute;
    bottom:0px;
    left:0px;
    right:0px;
    border-top:1px solid #666;
    transform: scaleY(0.5);
  }
}

5.3 box-shadow

不好看

  .class1 {
    box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
  }

5.4 其他方案 不推荐

  • viewport: 将页面进行缩小处理;
  • border-image:切个 1px 图片来模拟;
  • background-image:切个 1px 图片来模拟;
  • linear-gradient:通过线性渐变,来实现移动端 1px 的线;
  • svg:基于矢量图形(svg) 在不同设备屏幕特性下具有伸缩性。

6. 图片高清问题

根据不同dpr配置不同图片

[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);
}

7. iPhoneX 适配方案

7.1 meta标签中设置网页在可视窗口的布局方式

	<meta name="viewport" content="viewport-fit=cover">

7.2 fixed 完全吸底元素场景的适配

{
    padding-bottom: constant(safe-area-inset-bottom); /* 兼容 iOS < 11.2 */
    padding-bottom: env(safe-area-inset-bottom); /* 兼容 iOS >= 11.2 */
}

7.3 fixed 非完全吸底元素场景的适配

{
  margin-bottom: constant(safe-area-inset-bottom);
  margin-bottom: env(safe-area-inset-bottom);
}
举报

相关推荐

0 条评论