移动端适配页面快速搭建

6,798 阅读5分钟

遥想去年入前端坑的时候,就很快遇到了移动端页面的开发,天(er)真(bi)的我立马上去量设计稿,然后撸起袖子就是干!可是打开调试一看乱套了,先不说布局上的问题,就是大小看起来也不太对啊,太大了!然后就去问老司机,他说尺寸你要除以2才行,我心里挺郁闷的,为啥啊。。当时项目紧,就先这么搞,然后加上百分比布局,完成了第一次的开发任务。。。

但是!这只是叫完成,我非常不喜欢心里有梗的感觉,我觉得这事儿没这么简单,而且随着后期开发的进行,有一天设计mm给我说你这个线好粗啊,能不能再细点儿,我心中一万个不(cao)情(ni)愿(ma)飞过,我这已经是1px了啊。。。

还有最关键的我发现用百分比布局有个极大的缺陷,就是当你感知设计的==设计意图==的时候,(我们的设计师同学们的==设计意图==有多重要,我觉得好的设计师一定是设计意图非常犀利的),有些设计元素并不是单纯的左对齐,右对齐,或者和某个元素有某种视觉上的联系。也就是说,这个时候百分比布局就要头疼了,这个元素到底是百分之多少呢,用尺子量一下,可以啊,可是你把设备屏幕放大或者缩小看看,哭还是不哭?。。。。

是的,没错,我哭了。。。

痛定思痛~我觉得开始调研,开始搞一个让我以后开发再也不哭的方案,之后的一个星期内我调研了当时所有的开发方案,那个时候不光调研还一边理解了一些新的概念来辅助我进行改革,那时候我才知道了尼玛为啥我要除以2,知道了设备分辨率,设备像素,css像素,页面视口,em和rem等等玩意儿。最终我选择了flexible.js这个库来帮助我做这件事儿,其实这个库代码很短,完全可以理解,代码可以去github上瞅一瞅,其实简单说,它利用==动态读取设备宽度并结合设备的像素比 =》动态改变html的font-size大小 + 页面缩放比例 =》影响以rem为单位的元素的最终呈现==。嗯嗯就是这么回事儿。

所以呢,要快速搭建移动页面适配还是需要一步一步准备好的:

  • 第一步:搭建页面基本模板,引入flexible.js

    <!DOCTYPE html>
    <html lang="en">
      <head>
          <meta charset="utf-8">
          <meta content="yes" name="apple-mobile-web-app-capable">
          <meta content="yes" name="apple-touch-fullscreen">
          <meta content="telephone=no,email=no" name="format-detection">
          <script type="text/javascript" src="./flexible.min.js"></script>
    
      </head>
    
      <body>
      </body>
    </html>
  • 第二步:准备scss工具函数,帮助还原设计稿时自动换算px到rem(这意味着你对着设计稿就可以直接撸!设计稿是多少px你就写多少px,完全无痛开发,和你开发pc端写死px赶脚一模一样)

@charset "utf-8";
/*
    @author xiao
    @des: APP端基础方法
    @使用心得:
        -适配方案参考淘宝开源库lib.flexible
        -布局rem动态适配
        -字体dpr动态适配
        -和文字相关的布局用px写死比较好。。。因为用rem会和没有用rem布局的字体有错位
        -目前市面上有三种代表的适配方案:
            1. 直接750设计稿除以2适配所有机型,布局采用百分比:代表网站 拉勾网
            2. 动态改变html font-size基准,所有元素以rem适配:代表网站 小米网
            3. 动态改变html font-size基准,所有除字体相关元素以外的rem适配,字体只按分辨率适配:代表网站 淘宝网
 */

/**
 * 基本思想描述:
 * 多屏适配布局问题
 * 移动端布局,为了适配各种大屏手机,目前最好用的方案莫过于使用相对单位rem。
 * 基于rem的原理,我们要做的就是: 针对不同手机屏幕尺寸和dpr动态的改变根节点html的font-size大小(基准值)。
 * 这里我们提取了一个公式(rem表示基准值)
 * rem = document.documentElement.clientWidth * dpr / 10
 * 说明:
 * 1)乘以dpr,是因为页面有可能为了实现1px border页面会缩放(scale) 1/dpr 倍(如果没有,dpr=1)。
 * 2)除以10,是为了取整,方便计算(理论上可以是任何值)
 * 所以就像下面这样,html的font-size可能会:
 * iPhone3gs: 320px / 10 = 32px
 * iPhone4/5: 320px * 2 / 10 = 64px
 * iPhone6: 375px * 2 / 10 = 75px
 * iPhone6plus: 414 * 3 / 10 = 124.2px
 */

/*
    px转换成rem
 */
@function px2rem($px, $base-font-size: 75px) {
    @if (unitless($px)) {
        //@warn "Assuming #{$px} to be in pixels, attempting to convert it into pixels for you";
        @return px2rem($px + 0px); // That may fail.
    } @else if (unit($px) == rem) {
        @return $px;
    }
    @return ($px / $base-font-size) * 1rem;
}

/*  
    默认已iPhone6的750为基准开发
    font-size 不推荐转换成rem
    原因:我们不希望文本在Retina屏幕下变小,
    另外,我们希望在大屏手机上看到更多文本,
    以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,所以我们不希望出现13px和15px这样的奇葩尺寸。
    注意设计稿是2x屏幕, 所以1x屏幕需要除以2
 */
@mixin font-dpr($font-size){
    font-size: $font-size / 2;

    [data-dpr="2"] & {
        font-size: $font-size;
    }

    [data-dpr="3"] & {
        font-size: $font-size * 1.5;
    }
}

/**
 *  为了和字体适配一样的非字体元素准备的转化方法    
 */
@mixin px-dpr($property, $size, $others:""){

    #{$property}: $size / 2 #{$others};

    [data-dpr="2"] & {
        #{$property}: $size #{$others};
    }

    [data-dpr="3"] & {
        #{$property}: $size * 1.5 #{$others};
    }
}

需要注意的就是,一般设计稿都是以750像素宽设计的,所以$base-font-size默认是75,如果你们的设计稿不是这个750,相应的$base-font-size也应该进行修改。

  • 第三步:开撸!
.box {
  width: px2rem(14);
  height: px2rem(14);
}

使用上应该没有什么问题了,就是有时可能页面缩放会导致一些问题,比如echarts使用时缩放页面会导致其显示不正常,这时候在头上加入:

<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">

flexible就不会再缩放,也就牺牲了1px和高清图片的问题,影响不大,其他问题我暂时还没遇到过,总之,快速搭建完成后,在移动端适配上你就不用再费任何精力了~看着设计稿还原就好啦~!