码迷,mamicode.com
首页 > 移动开发 > 详细

移动入门 -- 适配

时间:2015-09-17 23:14:22      阅读:424      评论:0      收藏:0      [点我收藏+]

标签:

适配要达到何种效果?

在不同尺寸的手机设备上,页面要能够良好的展示, 不会出现错位变形(自适应), 或者保持统一效果的等比缩放。

设计稿尺寸

第一个问题就是选用多大的设计稿尺寸,如果按照320px的设计稿切图,在retina屏幕下,图片会失真。因为在retina屏幕上以 ipone4(320*480)为例,其实际像素点个数为 640*960。

贴一张图帮助理解

技术分享

如上图所示,普通屏幕(左图)和 retina屏幕(右图)1个css像素所对应的物理像素是不一致的。

在普通屏幕下, 1个css像素 对应 1个物理像素 (1:1)

在 retina 屏幕下,1个css像素 对应 4个物理像素 (1:4)

理论上来说,一个图片上的像素对应一个物理像素,图片才能得到完美展示。

在普通屏幕下没有问题,但是在 retina 屏幕下就会出现图片像素点不够,从而导致图片模糊。

贴一张图帮助理解

技术分享

如上图:对于dpr=2的retina屏幕而言,1个位图像素对应于4个物理像素,由于单个位图像素不可以再进一步分割,所以只能就近取色,从而导致图片模糊(注意上述的几个颜色值)。

因此,对于图片失真问题,解决办法就是采用 两倍大小的图片

但是如果在普通屏幕下,也采用 两倍图片,会怎么样呢?

技术分享

如左图,1个物理像素对应4个图片像素,结果是因此色差。

综上:处理图片在高清屏下1倍大小的图片的失真和普通屏下2倍图片色差的问题,应该准备两套图片,通过媒体查询或者来引入相应的图片url

 

retina下,border:1px问题

由于在retina屏幕上1个css像素对应2个物理像素,也就是说它的最小显示单元为0.5个css像素,如果我们设置如下css

border: 1px solid #000;

在普通屏和retina屏幕上的效果是这样的

技术分享

也就是说,我们无法写出只占一个物理像素的边框样式,因为设置0.5px 在某些系统中会被当成0px。

网上的解决办法是

.scale{
    position: relative;
}
.scale:after{
    content:"";
    position: absolute;
    bottom:0px;
    left:0px;
    right:0px;
    border-bottom:1px solid #ddd;
    -webkit-transform:scaleY(.5);
    -webkit-transform-origin:0 0;
}

:after 来偏移出另外的0.5像素,  这种 hack 不够通用,无法处理圆角等.

另外一种是处理方案是 对于 dpr=2 的屏幕添加如下meta标签

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

设置 viewport 的初始缩放比例为 0.5, 这样整个页面的 1px 边框都会变成 0.5px, 适用于所有场景

但是缩放整个页面也会带来一定的问题:

1、字体大小也会被缩放,在普通屏和高清屏下无法显示一致

2、页面布局也会被缩放

适配布局

网上有很多种布局方案,这里只写一致认为比较好的方案,rem布局

原理: 根据不同手机尺寸和 dpr 动态改变根节点<html>的 font-size 大小,页面其他元素以此为基准进行计算

直接贴代码

var docEl = document.documentElement,
    metaEl = document.querySelector(‘meta[name="viewport"]‘),
    styleEl = document.createElement(‘style‘),
    dpr = win.devicePixelRatio || 1,
    rem = docEl.clientWidth * dpr / 10,
    scale = 1 / dpr;

// 动态是指 viewport 的缩放比例
metaEl.setAttribute(‘content‘, ‘width=device-width, initial-scale=‘ + scale + ‘, maximum-scale=‘ + scale + ‘, minimum-scale=‘ + scale + ‘, user-scalable=no‘);

// 设置data-dpr属性, 留作 css hack 之用
docEl.setAttribute(‘data-dpr‘, dpr);

// 动态写入样式
docEl.firstElementChild.appendChild(styleEl);
styleEl.innerHTML = ‘html{ font-size: ‘+ rem +‘px !important; }‘;

计算 rem 说明

1. 乘以 dpr ,规避缩放对布局和字体大小的影响

2. 除以16,我也不知道,据说为了换算出一个较小的基准值,也可以设置为10,或者任何你想要设置的值

通过计算的html的font-size为:

iphone3gs: 320px / 10 = 32px

iphone4/5: 320px * 2/ 10 = 64px

iphone6: 375px * 2 / 10 =  75px

如何在css编码中还原视觉稿的真实宽高?

对于宽度为 640px的设计稿, 如果一个div的宽高为 300*320px 如何转换成rem

用 sass 封装一个 mixin

// 例如 toRem(height, 300)
$ppr: 640px / 10 * 1rem;  // pixel per rem
@mixin toRem($property, $values...){
    $max: length($values);
    $remValues: ‘‘;
    @for $i from 1 through $max{
        $value: nth($values, $i) / $ppr;
        $remValues: #{$remValues + $value};
        @if $i < $max{
            $remValues: #{$remValues + " "};
        }
    }
    #{$property}: $remValues;
}

所以对于宽高为 300*320px 的div,可以这样写

@include toRem(width, 300px);
@include toRem(height, 320px);

得到的css代码为

width: 4.6875rem;
height: 5rem;

字体大小问题

不同的dpr会导致不同的缩放比例,字体也会被缩放,由于字体不能使用rem,所以需要对不同的dpr屏幕应用不同的字体大小,也可以封装一个mixin,我还不知道如何封装,等我知道了再来补全 ^_^

 

参考网站: 移动端高清,多屏适配移动端页面使用rem布局

 

移动入门 -- 适配

标签:

原文地址:http://www.cnblogs.com/walle2/p/4817706.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!