移动端适配方案

移动端适配的是什么?
我们讨论的是网页适配多种尺寸屏幕,让网页效果看起来和设计师的设计稿一样。也就是同一套代码在不同分辨率的手机上跑时,页面元素间的间距,留白,以及图片大小会随着变化,在比例上跟设计稿一致。
下面会详细讨论viewport和css像素px中的细节,先只谈适配的结论:

  • 网页在viewport中布局,viewport被分成一个个小方块,一个CSS像素占一个方块。
  • 在设置了viewport宽度等于设备宽度的情况下,在不同大小的屏幕上,1个CSS像素所占屏幕的物理尺寸是一样大的。既然1个CSS像素在不同屏幕上物理尺寸一样大,那px肯定不能做为适配的方法了。
  • 长度单位rem是相对于html标签的font-size来计算的。例如html标签设置font-size:36px,同时div设置width:1.2rem。那么这个div的宽度就是1.2rem=36px*1.2=43.2px

使用js根据屏幕的大小动态设置html标签的font-size,随着html标签font-size的值变化,div的1.2rem换算成px的值也跟着变化,即实现了div随屏幕大小变化而变化。

rem

业内比较流行的做法(参考阿里的flexible),有以下要点:

  • 设置viewport为设备宽度
  • 将viewport分成10rem,并计算出1rem在当前浏览器的像素值,把它赋予html标签的font-size(分成10rem只是为了方便计算而已)
  • 写CSS代码时,遇到要适配的地方,比如width,margin,padding等,就不要再用px了,改成用rem。

现有设计师提供宽度为400px的设计稿,其中某个图片的宽度设计为20px,那么,CSS的写法就是img{width: 0.5rem;},怎么得出这个结果的呢?

  • 设计稿的宽度视同手机宽度,即假设有一个viewport为400px的手机
  • 将它分成10rem,每个rem为40px;
  • 那么图片宽度20px自然就是0.5rem;

岂不是意味着,每次写到尺寸的地方,都要先在草稿纸上把设计师给的px换算成rem?别急,sublime text 3有一款插件可以帮助你进行这个换算,你只需要输入20px,它会自动帮你换算成 0.5rem,插件地址

px

在CSS的世界里px是原子操作,我们无法定义边框的宽度是0.5px,最小都是1px。然而,在高清屏上,border-width:1px;并不是最小边框。浏览器可以显示的最小粒度比CSS中的1px还要小。
那么CSS中的1px是什么?浏览器是怎么渲染它的?
网页在一个叫viewport的东西里渲染,可以理解为画布,画布被分成 N x M 个小方格,1个CSS像素,就是其中的一个小方格。
viewport又是什么?
网页在viewport上渲染,可以想像在PS上画东西时,上面也有个画布,这个画布分割了 N x M 个方格,N是它的宽度,M是它的高度。宽高都可以任意设置,所以说viewport是虚拟的。假设设置宽度是400,那么浏览器显示区域的横向将被分为400份,CSS的1px占的宽度就是显示区域的 1/400。如果是980,那就是1/980。1px是指viewport中的一个小方格,而viewport宽度是可以任意设置的。

viewport

那么,怎么合理设置viewport的宽度?
viewport的宽度可以是数字和字符串”device-width”。device-width指设备宽度。
当取值为数字时,指不论是什么手机屏幕,viewport都被分为那么多份。
当取值为device-width时,指的是手机屏幕的viewport宽度被设置为跟手机宽度一样。那这个宽度怎么算的呢?
先理清几个非常关键的术语概念:

  • 物理像素:买手机的时候会有一个 nm 的分辨率,那是屏幕的nm个呈像的点,一个点(小方格)为一个物理像素。它是屏幕能显示的最小粒度
  • CSS像素:就是CSS里的Px,上面已经讲了是viewport中的一个小方格。
  • 像素密度:即dpi或ppi,屏幕每英寸所占的物理像素点。

例如:某台安卓手机,分辨率是 1920*1080,屏幕对象线是5英寸。那么在这台手机上1个CSS像素,占了多少个物理像素?
第一步:勾股定理算出对角线的分辨率,即 √(1920²+1080²)≈2203px
第二步:算出dpi。对角线的分辨率/对角线英寸 = 2203/5≈440dpi
第三步:得出转换系数。根据上面的图片,安卓手机440dpi,属于XXHDPI,转换系数是3
因此这台手机中,1个CSS像素 = 3*物理像素。即1个CSS像素占了3个物理像素。
这个转换系数,也等同于dpr,设备像素比。
因为很明显device-width的宽度值单位是CSS像素。所以当viewport设置为device-width时,此时它是手机横向分辨率 / 转换系数。即:device-width = 手机横向物理像素 / 转换系数。
该台安卓手机的device-width是1080/3 = 360,即viewport的宽度是 360CSS像素。而viewport设置为固定的数字有可能会破坏这种转换关系,都是建议设置viewport宽度为device-width,这样1个CSS像素就尽最大可能刚好占dpr个物理像素点。

iPhone1px

为什么会出现比border-width:1px更细的边框?
屏幕能够显示的最小粒度是1个物理像素,而当viewport宽度设置为device-width时,1个CSS像素占用的物理像素是由转换系数决定的。所以,像iPhone6这样的高清屏上,转换系数为3,border-width:1px,这个边框占了3个物理像素。如果能让某个border的宽度为1个物理像素,那么它就比1个CSS像素要细。
让1个CSS像素占用一个物理像素有这几个方法:

  • viewport的scale。在viewport的属性里,除了设置宽高的width和height外,还有缩放比例scale。当scale为1时,页面大小正常,但scale为0.5时,页面被缩小了1倍,本来1个CSS像素宽度占2个物理像素宽度,缩小后的border-width:1px就只占1个物理像素。优点:不用为border写很多样式代码,跟原来一样border:1px solid #D5D5D6即可,而且可以轻松设置圆角 border-radius。缺点:整个页面缩小了,副作用就是字体,图片,其他元素的尺寸边距等等都同比例缩小了。这种情况,使用上面的rem方案即可。
  • 方法二:transform scale。方法一是缩放整个页面,在CSS3标准里,可以缩放某个元素。例如某个div.border-top,为它设置如下样式,使该DIV的顶部有一个边框。在该DIV后面添加一个高度为1px的内容,并且缩小dpr倍,这里就是缩小成原来的1/2。优点是整个页面不用缩放,缺点是border代码较多,无法实现border-radius圆角
    .border-top{position: relative;border-top: none !important;}
    .border-top:after {
        content: " ";
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 1px;
        background-color: #D5D5D6;
        -webkit-transform-origin: 0 0;
        -ms-transform-origin: 0 0;
        transform-origin: 0 0;
        -webkit-transform: scaleY(0.5);
        -ms-transform: scaleY(0.5);
        transform: scaleY(0.5);
    }

vh

尺寸(width、height、margin、padding等等)相关的适配,除了使用rem以外,还可以使用CSS3的vh和vw。

  • vw代表viewport宽度的1%,即viewport宽度被划分为100份,1vw代表1份的宽度。
  • vh是高度。规律跟vw一样。
  • vmin是vh和vw中较小者;vmax是vh和vw中较大者

当我们要实现九宫格的时候,只需要:

   img {
       display: inline-block;
       width: 33vm;
       height: 33vm;
       margin-right: 0.33vm;
   }

那么vw、vh的兼容性如何呢?移动端安卓4.3自带浏览器不支持。那么,安卓4.3及以下操作系统在国内的市场份额是多少呢?友盟的统计结果是约31%,量较大。所以较为稳妥的方案还是rem。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值