移动端自适应方案优缺点概述

314 阅读1分钟

device-width

<meta name="viewport" content=`width=${设计稿宽度}, initial-scale=${clientWidth/设计稿宽度}, user-scalable=no`>

简单粗暴缺点很明显:

  • 影响媒体查询

  • 字体大小无法单独设置

rem

方案:

动态调节根节点font-size的方法:

  • 根据clientWidth动态设置
  • 与vw结合

优点:

  • 灵活,可以设置最大值、最小值

缺点:

  • 在微信等环境中app等字体大小设置会影响根节点字体大小

vw

方案:

缺点:

  • 无法设置最大值、最小值的边界

calc() + clamp()

clamp(Min, Val, Max) 等价于 max(Min ,min(Max, Val))

原理:

 `calc(Val / ${设计稿宽度} * clamp(MIN,100vw,MAX))`

优点:

  • vw 进阶版支持最大值、最小值

缺点:

postcss插件没找到,自己实现了一个跟 postcss-px-to-viewport 参数差不多的

方案:

配置新增的maxViewportWidthminViewportWidth 属性就能实现px to clamp的转化

补充

字体大小建议单独的适配:

@media screen and (min-width: 320px) {
    :root {--fontSize: 16px}
}

@media screen and (min-width: 481px) and (max-width:640px) {
    :root {--fontSize: 18px}}

@media screen and (min-width: 641px) {
    :root {--fontSize: 20px}}

React-Native

function px2dp(uiElementPx: number): number { 
 return (uiElementPx * deviceWidthDp) / uiWidthPx;
}

function sheetCreate<T extends NamedStyles<T> | NamedStyles<any>>(  styles: T | NamedStyles<T>, ): T { 
   styles = {...styles};  
   type G = keyof (ViewStyle & TextStyle & ImageStyle);  
   let list: G[] = [
        'width',
        'height',
        'marginTop',
        'marginBottom',
        'marginLeft',
        'marginRight',
         ...
      ];  
  for (let outKey in styles) { 
       for (let innerKey in styles[outKey]) {
          let value = styles[outKey][innerKey] as number;  
          if (list.includes(innerKey as any) && typeof value === 'number') {
            styles[outKey][innerKey] = px2dp(value) as any; 
          }
       }
   }  
    return StyleSheet.create(styles);  
}