首页 > 技术文章 > 使用Flexible实现手淘H5页面的终端适配

sybboy 2017-02-27 16:41 原文

曾几何时为了兼容IE低版本浏览器而头痛,以为到Mobile时代可以跟这些麻烦说拜拜。可没想到到了移动时代,为了处理各终端的适配而乱了手脚。对于混迹各社区的偶,时常发现大家拿手机淘宝的H5页面做讨论——手淘的H5页面是如何实现多终端的适配?

那么趁此Amfe阿里无线前端团队双11技术连载之际,用一个实战案例来告诉大家,手淘的H5页面是如何实现多终端适配的,希望这篇文章对大家在Mobile的世界中能过得更轻松。

目标

拿一个双11的Mobile页面来做案例,比如你实现一个类似下图的一个H5页面:

Flexible实现手淘H5页面的终端适配

目标很清晰,就是做一个这样的H5页面。

DEMO

请用手机扫下面的二维码

DEMO

痛点

虽然H5的页面与PC的Web页面相比简单了不少,但让我们头痛的事情是要想尽办法让页面能适配众多不同的终端设备。看看下图你就会知道,这是多么痛苦的一件事情:

Flexible实现手淘H5页面的终端适配

点击这里查看更多终端设备的参数。

再来看看手淘H5要适配的终端设备数据:

Flexible实现手淘H5页面的终端适配

看到这些数据,是否死的心都有了,或者说为此捏了一把汗出来。

手淘团队适配协作模式

早期移动端开发,对于终端设备适配问题只属于Android系列,只不过很多设计师常常忽略Android适配问题,只出一套iOS平台设计稿。但随着iPhone6,iPhone6+的出现,从此终端适配问题不再是Android系列了,也从这个时候让移动端适配全面进入到“杂屏”时代。

Flexible实现手淘H5页面的终端适配

上图来自于paintcodeapp.com

为了应对这多么的终端设备,设计师和前端开发之间又应该采用什么协作模式?或许大家对此也非常感兴趣。

而整个手淘设计师和前端开发的适配协作基本思路是:

  • 选择一种尺寸作为设计和开发基准
  • 定义一套适配规则,自动适配剩下的两种尺寸(其实不仅这两种,你懂的)
  • 特殊适配效果给出设计效果

还是上一张图吧,因为一图胜过千言万语:

Flexible实现手淘H5页面的终端适配

在此也不做更多的阐述。在手淘的设计师和前端开发协作过程中:手淘设计师常选择iPhone6作为基准设计尺寸,交付给前端的设计尺寸是按750px * 1334px为准(高度会随着内容多少而改变)。前端开发人员通过一套适配规则自动适配到其他的尺寸。

根据上面所说的,设计师给我们的设计图是一个750px * 1600px的页面:

Flexible实现手淘H5页面的终端适配

前端开发完成终端适配方案

拿到设计师给的设计图之后,剩下的事情是前端开发人员的事了。而手淘经过多年的摸索和实战,总结了一套移动端适配的方案——flexible方案

这种方案具体在实际开发中如何使用,暂时先卖个关子,在继续详细的开发实施之前,我们要先了解一些基本概念。

一些基本概念

在进行具体实战之前,首先得了解下面这些基本概念(术语):

视窗 viewport

简单的理解,viewport是严格等于浏览器的窗口。在桌面浏览器中,viewport就是浏览器窗口的宽度高度。但在移动端设备上就有点复杂。

移动端的viewport太窄,为了能更好为CSS布局服务,所以提供了两个viewport:虚拟的viewportvisualviewport和布局的viewportlayoutviewport。

George Cummins在Stack Overflow上对这两个基本概念做了详细的解释

而事实上viewport是一个很复杂的知识点,上面的简单描述可能无法帮助你更好的理解viewport,而你又想对此做更深的了解,可以阅读PPK写的相关教程

物理像素(physical pixel)

物理像素又被称为设备像素,他是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。正是这些设备像素的微小距离欺骗了我们肉眼看到的图像效果。

Flexible实现手淘H5页面的终端适配

设备独立像素(density-independent pixel)

设备独立像素也称为密度无关像素,可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素),然后由相关系统转换为物理像素。

CSS像素

CSS像素是一个抽像的单位,主要使用在浏览器上,用来精确度量Web页面上的内容。一般情况之下,CSS像素称为与设备无关的像素(device-independent pixel),简称DIPs。

屏幕密度

屏幕密度是指一个设备表面上存在的像素数量,它通常以每英寸有多少像素来计算(PPI)。

设备像素比(device pixel ratio)

设备像素比简称为dpr,其定义了物理像素和设备独立像素的对应关系。它的值可以按下面的公式计算得到:

设备像素比 = 物理像素 / 设备独立像素

在JavaScript中,可以通过window.devicePixelRatio获取到当前设备的dpr。而在CSS中,可以通过-webkit-device-pixel-ratio-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。

dip或dp,(device independent pixels,设备独立像素)与屏幕密度有关。dip可以用来辅助区分视网膜设备还是非视网膜设备。

缩合上述的几个概念,用一张图来解释:

Flexible实现手淘H5页面的终端适配

众所周知,iPhone6的设备宽度和高度为375pt * 667pt,可以理解为设备的独立像素;而其dpr为2,根据上面公式,我们可以很轻松得知其物理像素为750pt * 1334pt

如下图所示,某元素的CSS样式:

width: 2px;
height: 2px;

在不同的屏幕上,CSS像素所呈现的物理尺寸是一致的,而不同的是CSS像素所对应的物理像素具数是不一致的。在普通屏幕下1个CSS像素对应1个物理像素,而在Retina屏幕下,1个CSS像素对应的却是4个物理像素。

有关于更多的介绍可以点击这里详细了解。

看到这里,你能感觉到,在移动端时代屏幕适配除了Layout之外,还要考虑到图片的适配,因为其直接影响到页面显示质量,对于如何实现图片适配,再此不做过多详细阐述。这里盗用了@南宮瑞揚根据mir.aculo.us翻译的一张信息图:

Flexible实现手淘H5页面的终端适配

meta标签

<meta>标签有很多种,而这里要着重说的是viewport的meta标签,其主要用来告诉浏览器如何规范的渲染Web页面,而你则需要告诉它视窗有多大。在开发移动端页面,我们需要设置meta标签如下:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

代码以显示网页的屏幕宽度定义了视窗宽度。网页的比例和最大比例被设置为100%。

留个悬念,因为后面的解决方案中需要重度依赖meta标签。

CSS单位rem

W3C规范中是这样描述rem的:

font size of the root element.

简单的理解,rem就是相对于根元素<html>font-size来做计算。而我们的方案中使用rem单位,是能轻易的根据<html>font-size计算出元素的盒模型大小。而这个特色对我们来说是特别的有益处。

前端实现方案

了解了前面一些相关概念之后,接下来我们来看实际解决方案。在整个手淘团队,我们有一个名叫lib-flexible的库,而这个库就是用来解决H5页面终端适配的。

lib-flexible是什么?

lib-flexible是一个制作H5适配的开源库,可以点击这里下载相关文件,获取需要的JavaScript和CSS文件。

当然你可以直接使用阿里CDN:

<script src="http://g.tbcdn.cn/mtb/lib-flexible/{{version}}/??flexible_css.js,flexible.js"></script>

将代码中的{{version}}换成对应的版本号0.3.4

使用方法

lib-flexible库的使用方法非常的简单,只需要在Web页面的<head></head>中添加对应的flexible_css.js,flexible.js文件:

第一种方法是将文件下载到你的项目中,然后通过相对路径添加:

<script src="build/flexible_css.debug.js"></script>
<script src="build/flexible.debug.js"></script>

或者直接加载阿里CDN的文件:

<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>

另外强烈建议对JS做内联处理,在所有资源加载之前执行这个JS。执行这个JS后,会在<html>元素上增加一个data-dpr属性,以及一个font-size样式。JS会根据不同的设备添加不同的data-dpr值,比如说2或者3,同时会给html加上对应的font-size的值,比如说75px

如此一来,页面中的元素,都可以通过rem单位来设置。他们会根据html元素的font-size值做相应的计算,从而实现屏幕的适配效果。

除此之外,在引入lib-flexible需要执行的JS之前,可以手动设置meta来控制dpr值,如:

<meta name="flexible" content="initial-dpr=2" />

其中initial-dpr会把dpr强制设置为给定的值。如果手动设置了dpr之后,不管设备是多少的dpr,都会强制认为其dpr是你设置的值。在此不建议手动强制设置dpr,因为在Flexible中,只对iOS设备进行dpr的判断,对于Android系列,始终认为其dpr1

if (!dpr && !scale) {
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/iphone/gi);
    var devicePixelRatio = win.devicePixelRatio;
    if (isIPhone) {
        // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
        if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
            dpr = 3;
        } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
            dpr = 2;
        } else {
            dpr = 1;
        }
    } else {
        // 其他设备下,仍旧使用1倍的方案
        dpr = 1;
    }
    scale = 1 / dpr;
}

flexible的实质

flexible实际上就是能过JS来动态改写meta标签,代码类似这样:

var metaEl = doc.createElement('meta');
var scale = isRetina ? 0.5:1;
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
if (docEl.firstElementChild) {
    document.documentElement.firstElementChild.appendChild(metaEl);
} else {
    var wrap = doc.createElement('div');
    wrap.appendChild(metaEl);
    documen.write(wrap.innerHTML);
}

事实上他做了这几样事情:

  • 动态改写<meta>标签
  • <html>元素添加data-dpr属性,并且动态改写data-dpr的值
  • <html>元素添加font-size属性,并且动态改写font-size的值

案例实战

了解Flexible相关的知识之后,咱们回到文章开头。我们的目标是制作一个适配各终端的H5页面。别的不多说,动手才能丰衣足食。

创建HTML模板

<!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 src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>
        <link rel="apple-touch-icon" href="favicon.png">
        <link rel="Shortcut Icon" href="favicon.png" type="image/x-icon">
        <title>再来一波</title>
    </head>
    <body>
        <!-- 页面结构写在这里 -->
    </body>
</html>

正如前面所介绍的一样,首先加载了Flexible所需的配置:

<script src="http://g.tbcdn.cn/mtb/lib-flexible/0.3.4/??flexible_css.js,flexible.js"></script>

这个时候可以根据设计的图需求,在HTML文档的<body></body>中添加对应的HTML结构,比如:

<div class="item-section" data-repeat="sections">
    <div class="item-section_header">
        <h2><img src="{brannerImag}" alt=""></h2>
    </div>
    <ul>
        <li data-repeat="items" class="flag" role="link" href="{itemLink}">
            <a class="figure flag-item" href="{itemLink}">
                <img src="{imgSrc}" alt="">
            </a>
            <div class="figcaption flag-item">
                <div class="flag-title"><a href="{itemLink}" title="">{poductName}</a></div>
                <div class="flag-price"><span>双11价</span><strong>¥{price}</strong><small>({preferential})</small></div>
                <div class="flag-type">{activityType}</div>
                <a class="flag-btn" href="{shopLink}">{activeName}</a>
            </div>
        </li>
    </ul>
</div>

这仅是一个示例文档,大家可以根据自己风格写模板

为了能更好的测试页面,给其配置一点假数据:

//define data
var pageData = {
    sections:[{
        "brannerImag":"http://xxx.cdn.com/B1PNLZKXXXXXaTXXXXXXXXXXXX-750-481.jpg",
        items:[{
            "itemLink": "##",
            "imgSrc": "https://placeimg.com/350/350/people/grayscale",
            "poductName":"Carter's1年式灰色长袖连体衣包脚爬服全棉鲸鱼男婴儿童装115G093",
            "price": "299.06",
            "preferential": "满400减100",
            "activityType": "1小时内热卖5885件",
            "shopLink":"##",
            "activeName": "马上抢!"
        }
            ....
        }]
    }]
}

接下来的工作就是美化工作了。在写具体样式之前,有几个点需要先了解一下。

把视觉稿中的px转换成rem

读到这里,大家应该都知道,我们接下来要做的事情,就是如何把视觉稿中的px转换成rem。在此花点时间解释一下。

首先,目前日常工作当中,视觉设计师给到前端开发人员手中的视觉稿尺寸一般是基于640px750px以及1125px宽度为准。甚至为什么?大家应该懂的(考虑Retina屏)。

正如文章开头显示的示例设计稿,他就是一张以750px为基础设计的。那么问题来了,我们如何将设计稿中的各元素的px转换成rem

Flexible实现手淘H5页面的终端适配

我厂的视觉设计师想得还是很周到的,会帮你把相关的信息在视觉稿上标注出来

目前Flexible会将视觉稿分成**100份**(主要为了以后能更好的兼容vhvw),而每一份被称为一个单位a。同时1rem单位被认定为10a。针对我们这份视觉稿可以计算出:

1a   = 7.5px
1rem = 75px 

那么我们这个示例的稿子就分成了10a,也就是整个宽度为10rem<html>对应的font-size75px

Flexible实现手淘H5页面的终端适配

这样一来,对于视觉稿上的元素尺寸换算,只需要原始的px值除以rem基准值即可。例如此例视觉稿中的图片,其尺寸是176px * 176px,转换成为2.346667rem * 2.346667rem

如何快速计算

在实际生产当中,如果每一次计算px转换rem,或许会觉得非常麻烦,或许直接影响大家平时的开发效率。为了能让大家更快进行转换,我们团队内的同学各施所长,为px转换rem写了各式各样的小工具。

CSSREM

CSSREM是一个CSS的px值转rem值的Sublime Text3自动完成插件。这个插件是由@正霖编写。先来看看插件的效果:

Flexible实现手淘H5页面的终端适配

有关于CSSREM如何安装、配置教程可以点击这里查阅

CSS处理器

除了使用编辑器的插件之外,还可以使用CSS的处理器来帮助大家处理。比如说Sass、LESS以及PostCSS这样的处理器。我们简单来看两个示例。

Sass

使用Sass的同学,可以使用Sass的函数、混合宏这些功能来实现:

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

除了使用Sass函数外,还可以使用Sass的混合宏:

@mixin px2rem($property,$px-values,$baseline-px:16px,$support-for-ie:false){
    //Conver the baseline into rems
    $baseline-rem: $baseline-px / 1rem * 1;
    //Print the first line in pixel values
    @if $support-for-ie {
        #{$property}: $px-values;
    }
    //if there is only one (numeric) value, return the property/value line for it.
    @if type-of($px-values) == "number"{
        #{$property}: $px-values / $baseline-rem;
    }
    @else {
        //Create an empty list that we can dump values into
        $rem-values:();
        @each $value in $px-values{
            // If the value is zero or not a number, return it
            @if $value == 0 or type-of($value) != "number"{
                $rem-values: append($rem-values, $value / $baseline-rem);
            }
        }
        // Return the property and its list of converted values
        #{$property}: $rem-values;
    }
}

有关于更多的介绍,可以点击这里进行了解。

PostCSS(px2rem)

除了Sass这样的CSS处理器这外,我们团队的@颂奇同学还开发了一款npm的工具px2rem。安装好px2rem之后,可以在项目中直接使用。也可以使用PostCSS。使用PostCSS插件postcss-px2rem

var gulp = require('gulp');
var postcss = require('gulp-postcss');
var px2rem = require('postcss-px2rem');

gulp.task('default', function() {
    var processors = [px2rem({remUnit: 75})];
    return gulp.src('./src/*.css')
        .pipe(postcss(processors))
        .pipe(gulp.dest('./dest'));
});

除了在Gulp中配置外,还可以使用其他的配置方式,详细的介绍可以点击这里进行了解。

配置完成之后,在实际使用时,你只要像下面这样使用:

.selector {
    width: 150px;
    height: 64px; /*px*/
    font-size: 28px; /*px*/
    border: 1px solid #ddd; /*no*/
}

px2rem处理之后将会变成:

.selector {
    width: 2rem;
    border: 1px solid #ddd;
}
[data-dpr="1"] .selector {
    height: 32px;
    font-size: 14px;
}
[data-dpr="2"] .selector {
    height: 64px;
    font-size: 28px;
}
[data-dpr="3"] .selector {
    height: 96px;
    font-size: 42px;
}

在整个开发中有了这些工具之后,完全不用担心px值转rem值影响开发效率。

文本字号不建议使用rem

前面大家都见证了如何使用rem来完成H5适配。那么文本又将如何处理适配。是不是也通过rem来做自动适配。

显然,我们在iPhone3G和iPhone4的Retina屏下面,希望看到的文本字号是相同的。也就是说,我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px24px,所以我们不希望出现13px15px这样的奇葩尺寸。

如此一来,就决定了在制作H5的页面中,rem并不适合用到段落文本上。所以在Flexible整个适配方案中,考虑文本还是使用px作为单位。只不过使用[data-dpr]属性来区分不同dpr下的文本字号大小。

div {
    width: 1rem; 
    height: 0.4rem;
    font-size: 12px; // 默认写上dpr为1的fontSize
}
[data-dpr="2"] div {
    font-size: 24px;
}
[data-dpr="3"] div {
    font-size: 36px;
}

为了能更好的利于开发,在实际开发中,我们可以定制一个font-dpr()这样的Sass混合宏:

@mixin font-dpr($font-size){
    font-size: $font-size;

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

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

有了这样的混合宏之后,在开发中可以直接这样使用:

@include font-dpr(16px);

当然这只是针对于描述性的文本,比如说段落文本。但有的时候文本的字号也需要分场景的,比如在项目中有一个slogan,业务方希望这个slogan能根据不同的终端适配。针对这样的场景,完全可以使用rem给slogan做计量单位。

CSS

本来想把这个页面的用到的CSS(或SCSS)贴出来,但考虑篇幅过长,而且这么简单的页面,我想大家也能轻而易举搞定。所以就省略了。权当是给大家留的一个作业吧,感兴趣的可以试试Flexible能否帮你快速完成H5页面终端适配。

效果

最后来看看真机上显示的效果吧。我截了两种设备下的效果:

iPhone4

Flexible实现手淘H5页面的终端适配

iPhone6+

Flexible实现手淘H5页面的终端适配

总结

其实H5适配的方案有很多种,网上有关于这方面的教程也非常的多。不管哪种方法,都有其自己的优势和劣势。而本文主要介绍的是如何使用Flexible这样的一库来完成H5页面的终端适配。为什么推荐使用Flexible库来做H5页面的终端设备适配呢?主要因为这个库在手淘已经使用了近一年,而且已达到了较为稳定的状态。除此之外,你不需要考虑如何对元素进行折算,可以根据对应的视觉稿,直接切入。

当然,如果您有更好的H5页面终端适配方案,欢迎在下面的评论中与我们一起分享。如果您在使用这个库时,碰到任何问题,都可以在Github给我们提Issue。我们团队会努力解决相关需Issues。

Update

同学反馈说需要一个在线的DEMO,那么随便写了一个DEMO,希望对大家有所帮助。没有测试所有设备,可能不同的设备有细节上的差异。

DEMO

请用手机扫下面的二维码

DEMO

Update【2016年01月13日】

首先,由衷的感谢@完颜(@SMbey0nd) 帮忙踩了这个坑,回想起iOS从78,从89,都踩过只至少一个坑,真的也是醉了。

手淘这边的flexible方案临时升级如下:

  • 针对OS 9_3的UA,做临时处理,强制dpr1,即scale也为1,虽然牺牲了这些版本上的高清方案,但是也只能这么处理了
  • 这个版本不打算发布到CDN(也不发不到tnpm),所以大家更新的方式,最好手动复制代码内联到html中,具体代码可以点击这里下载
 
@chesihui
 

非常实用!

 
@hongru
 
Contributor

沙发地板,高质量文章点赞

 
@cristicmf
 

要细细品味~

 
@wssgcg1213
 

前排

 
@westke
 

占座

 
@cqgsm
 
cqgsm commented on 19 Nov 2015

好东西啊 谢谢无私分享

 
@fsy0718
 

占座

 
@cxyn
 
cxyn commented on 19 Nov 2015

感谢分享,非常受用!准备在项目中尝试运用。

 
@ghost
 
ghost commented on 19 Nov 2015

之前好多疑惑的地方,一次性解决了,大赞!!!

 
@jincdream
 

我厂的视觉设计师想得还是很周到的,会帮你把相关的信息在视觉稿上标注出来。

这才是我想要的设计师。不说了,我去哭会。
Markman 都是自费的。.

最近我们也做了这个适配方案的研究。~占位,明天放链接

 
@jincdream
 

为什么字体不能用rem ?

我们不希望文本在Retina屏幕下变小,另外,我们希望在大屏手机上看到更多文本,以及,现在绝大多数的字体文件都自带一些点阵尺寸,通常是16px和24px,所以我们不希望出现13px和15px这样的奇葩尺寸。

换句话说,如果使用rem,那么字体的单行数量显示,在不同的尺寸和像素比的屏幕上都是一样的。但真的不能用吗?未必呀( ⊙ o ⊙ )!!设计稿可能会有这样的需求:我这一行字必须就是这几个(其实就是标题),这时候,你总不能说,噢~介个iphone6 plusd的像素比这么高,像素这么多,就让它多显示几个字的标题吧吧吧吧吧...

所以,有时候并不是不能用,而是要选择合适的时候使用合适的单位吧。

如此一来,就决定了在制作H5的页面中,rem并不适合用到段落文本上。所以在Flexible整个适配方案中,考虑文本还是使用px作为单位。只不过使用[data-dpr]属性来区分不同dpr下的文本字号大小

当然这只是针对于描述性的文本,比如说段落文本。但有的时候文本的字号也需要分场景的,比如在项目中有一个slogan,业务方希望这个slogan能根据不同的终端适配。针对这样的场景,完全可以使用rem给slogan做计量单位。

 
@zeyongTsai
 

干货,又有新东西用了。:blush:

 
@mootee
 

:+1:

 
@terrykingcha
 
Member

人工点赞

 
@meiyzeng
 

用这套方案做适配的话有没有遇上在ios环境下fontsize无法控制emoji表情(unicode)编码的问题呢?

 
@GavinHans
 

好文要顶

 
@yuzhe927
 

受教了

 
@shawyon
 

讲得很细,重新学习了Flexible

 
@linjinying
 

请教一下,如果遇到雪碧图的icon,改如何适配。background-size对rem的适配好像很差吧

 
@moocss moocss referenced this issue in thoughtbit/it-note on 20 Nov 2015
 Open

移动开发资源 #20

@floraluo
 

虽然我现在还没做移动端,但是对这一方面关注已久了。flexible方案之前看过,这里一讲就更清楚了。另外我再想问一问,关于网易的移动端适配方案和flexible相比,针对项目不同的复杂度,这两个各自的优势劣势是什么呢?

 
@tangjinzhou
 

先赞后看

 
@floraluo
 

@linjinying雪碧图的话,那就要做两个,或者三个,看你要适配那种,dpr=2的雪碧图也要 X2

 
@hzh1990
 

@floraluo 如果你不想做两个或者三个... 你可以做一个最大的...

 
@linjinying
 

@floraluo @hzh1990 就假设拿到是最大的,那最终要通过什么样的策略达到适配效果。目前我是通过background-size+媒体查询来实现的。感觉效果不是很好。

 
@chenerlang666
 

占坑

 
@magele758
 

文章既然已经讲到了CSS像素和物理像素的区分,其实可以在这个地方做文章,却又走上了rem得路子上去,其实思路是一样的,却多做了一步。

 
@AlexBai1991
 

顶!d=====( ̄▽ ̄*)b

 
@zzbo
 
zzbo commented on 20 Nov 2015

nice~

 
@JingwenTian
 

@mark

 
@c2ye
 
c2ye commented on 20 Nov 2015

文章写的非常赞,娓娓道来,很有诚意,点赞!

 
@yimity
 

再配合这篇文章来看,会更不错哦。
http://div.io/topic/1092

 
@tarymee
 

 
@lylpixin2121
 

nice

 
@LindaWhite
 

学习了,谢谢

 
@crazyyfrog
 

mark

 
@kujian
 

mark

 
@airen airen referenced this issue in amfe/lib-flexible on 20 Nov 2015
 Closed

完整引用举例里写的是什么看不懂 #15

@del1214
 

请问这个lib-flexible库在微信的x5内核里能用么?

 
@airen
 
Contributor
airen commented on 20 Nov 2015

@del1214 理论上只要支持viewport的内核都是可以用的。不仿尝试一下,如果有问题,欢迎给我们提issue

 
@airen
 
Contributor
airen commented on 20 Nov 2015

@jincdream 并没有说在实际中对字号不能使用rem,而是强列建议使用px,在大于48px这样的字号时,考虑使用rem更适合。

 
@airen
 
Contributor
airen commented on 20 Nov 2015

@linjinying 您说的问题,我在实际中也碰到过,有时候会略为头痛。我们现在的做法是在实际中不使用icon sprites这种方式,一般对于icon,更建议采用icon font或者使用svg icon,也可以使用base64 配合background-size。

 
@linjinying
 

@airen 然而,实现开发中,难为有些icon不能用font或svg来实现,曾经想过用rem来设置background-size的值,这种不是很标准的做法,是否可取?

 
@jincdream
 

@airen 所有要改改标题嘛?~

- ##字号不使用rem
+ ##文本字体不建议使用rem
 
@qingying qingying referenced this issue on 20 Nov 2015
 Open

双十一敲钟项目总结 #19

@lidianhao123
 

使用这种适配方案,如何处理div background-image 图片是sprite的

 
@ireliale
 

image
不知道我这种方法是否可行,把viewport宽度固定为320(也可以是其他尺寸), 然后在不同设备上查看该设备的设备独立像素即:window.screen.width, 这个值与320的比值就是网页缩放的比值,然后添加相应的meta标签,如图所示,这样行不?

 
@lidianhao123
 

@ireliale 我指的是使用flexible 方案,如果使用你图片中的方案就不属于flexible方案了,也就不存在我提到的问题。

 
@ireliale
 

@lidianhao123 sorry, 我没有表达清楚,我的意思是用我图片中的那种方式做移动端h5页面的适配是否可行,@airen

 
@lidianhao123
 

@ireliale 目前项目中有用你提到的这种方式。现在一般都把宽度固定成640px了,估计很快要到750px

 
@dengxiaozhen
 

1rem=75px,感觉太难换算,我觉得1rem=40px比较好换算

 
@yinqiao
 

现在使用640px的设计稿还是居多

 
@jcpplus
 

赞!目前使用的就是基于这个框架之内的东西。

 
@yutingzhao1991 yutingzhao1991 referenced this issue in yutingzhao1991/github-blogs-weekly on 22 Nov 2015
 Open

文章更新 [ 2015-11-15 - 2015-11-21 ] #11

@gdmec07120721
 

好货好货~

 
@ChristYoung
 

纯干货要顶

 
@yeol
 
yeol commented on 23 Nov 2015

赞~

 
@elvinzhu
 

@airen 请教个问题

如果字体使用px的话,那么容器的高度使用的是自适应还是rem? 如果是rem的话,那么这个容器在有些屏幕宽度下稍微有些空旷! 如果使用px的或者自适应的话,假如页面有positioned 的元素的的时候,那这个元素的相对位置在有些屏幕下会错开,因为那些自适应的容器没有等比撑开页面!

不知道你有没有遇到过上面的问题,还望指点一二,谢谢

 
@dengxiaozhen
 

@elvinzhu 我一般高度设置px,这样看起来 也不会说 在横屏,高度会变得非常大

 
@dengxiaozhen
 

@yinqiao 我们也是640px的设计稿

 
@elvinzhu
 

@dengxiaozhen Thanks

高度设置px的话,难道你的字体大小不会随着dpr的增大而增大?

 
@dengxiaozhen
 

@elvinzhu 字号也是设置px咯

 
@airen
 
Contributor
airen commented on 24 Nov 2015

@jincdream 谢谢您的建议

 
@airen
 
Contributor
airen commented on 24 Nov 2015

@elvinzhu 这个应该根据具体情况来定,如果您觉得你的元素需要显式的指定高度,建议使用rem做为单位。从个人经验来说,一般情况下不给元素显式指定高度。

 
@airen
 
Contributor
airen commented on 24 Nov 2015

@floraluo 可以考虑直接使用SVG Sprites

 
@airen
 
Contributor
airen commented on 24 Nov 2015

@dengxiaozhen px 转换rem是不需要人工去计算的,文章中也提供了多种转换的方法。可以参考一下。另外设置为75px64px并不是根据好算不好算作为出发点,而应该根据您的设计图尺寸做为出发点。

 
@elvinzhu
 

@airen

Thanks

问题在于,当有些容器使用自适应高度的时候,页面上比如fixed的元素的位置(top)无论是rem单位还是px单位,在不同屏幕尺寸下相对位置就会不一致,因为那些自适应高度的元素的高度不是按照屏幕宽度的变化等比变化的

 
@dengxiaozhen
 

@airen 哦哦 谢谢大漠指点。

 
@vvchen
 

1rem=10px,这样不是更好换算吗?直接就心算出来了,都不需要工具
html字体大小按照:clientWidth*(10/750)来设置就好了

 
@ufologist
 

上面貌似没有一份完整可用的 demo 代码.

于是乎试着用 flexible 做了个页面 flexible.html, 需要的同学请带走.

另外如果是简单的专题着陆页需要适配方案, 可以试一试 responsive-page, 不好意思, 我卖了个瓜...
演示 responsive-page 适配功能

 
@dengxiaozhen
 

@ufologist 666666

 
@dengxiaozhen
 

@ufologist 看了你的demo发现一个类似卡顿的问题,后来一想可能是 Flexible库的问题。因为

<meta name="viewport" content="">

是通过js插入进去的,那么当我变化完视口的时候,再修改根节点的html字号,所以会出现这样的问题
图片一
图片不会跟随视口的变化及时变化

 
@xff1874
 

以6 位原型,那么6 plus 是414*3的,那么750的图片,还是会出现图片模糊的问题,你们是如何处理的呢。

 
@dengxiaozhen
 

@xff1874 设计稿 做宽 1242px :smile:

 
@airen
 
Contributor
airen commented on 27 Nov 2015

为了满足有需要的同学,今天添加了一个DEMO。友情提示:DEMO没有经过所有设备的测试,有可能在部分设备存在细节上差异。

DEMO

请用手机扫下面的二维码

DEMO

 
@dengxiaozhen
 

@airen 给大漠点赞 :+1::+1::+1:

 
@taxi666
 

为什么会有1125 的视觉稿尺寸?iphone6s的分辨率是1080啊

 
@dengxiaozhen
 

@taxi666 可能是 爱疯6的物理像素乘以3得到的 375*3=1125 :wink:

 
@airen
 
Contributor
airen commented on 27 Nov 2015

@linjinying 有关于CSS Sprites的,我们团队的经验是请不要再使用CSS Sprites,相关的介绍可以看看下面两篇文章中对应的内容:

 
@airen airen referenced this issue in amfe/lib-flexible on 27 Nov 2015
 Closed

设计稿到rem转换 #7

@wenroo
 

@vvchen 我也一直是这么干的,这样换算真的很方便,虽然写文本单位的时候会有些偏差,但是都在可控范围。

 
@amazg
 
amazg commented on 28 Nov 2015

感谢分享~

 
@geeeeeeeeek
 

很赞的分享

 
@yuu2lee4
 

不错 不错 之前自己 写了一个自适应动态更改htmlfontsize的js 比起来太简陋了 问个问题 直接设置html fontsie为固定的100px 有什么缺点呢

 
@chenbiting
 

@yuu2lee4 直接设置 html fontSize的话,rem就没有用了

 
@zhangzhaoaaa
 

@chenbiting 请你试一下再说,rem的单位是root元素的font-size,在其定义中并没有说不能设置html的font-size的固定值

 
@jerryyan1990
 

适配设备才是最要命的,感谢分享干货!

 
@xiaobinwu
 

mark

 
@grantCHG
 

为什么只在iOS下的dpr为2和3的屏用2倍的方案,其余的类似android用1倍方案呢

 
@w3cay
 
w3cay commented on 8 Dec 2015

同楼上问题,在安卓机是1倍的适配,但是明明devicePixelRatio为2。

 
@wssgcg1213
 

我猜是安卓下会有很多bug,参考集团gitlab里mbase的Flexible.js方案,实用后收到很多安卓下兼容性的问题。可见手掏的这一套lib.flexible 还是相对保守可靠

 
@riskers
 

@ireliale 你的那种方法有案例么?

 
@w3cay
 
w3cay commented on 17 Dec 2015

为什么最大根元素font-size最大54px?

 
@tonyljl526
 

请问下,为什么在dpr=2和3的 iphone手机上面 border 设置为1 的时候显示异常啊? 比如有个场景是:添加到购物车,加减号的border设置为1px点击的时候会有异常的情况。 是否和 meta设置有关? content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no 都为0.5 和0.3333333的时候 边框会有异常,请问淘宝是怎么解决的呀?

 
@zheyueguohou
 

@airen 如果字体大小直接用em的话,会直接根据body或者父元素的大小自动换算,而body直接通过js算好了如:12px、24px、36px。这样就不用下面的这样写法了,是这样的吗?
.flag .flag-price strong{font-size:16px}
[data-dpr="2"] .flag .flag-price strong {
font-size: 32px
}
改为:
.flag .flag-price strong{font-size:1.3333em}

 
@airen
 
Contributor
airen commented on 24 Dec 2015

@zheyueguohou 那也不一定。因为em单位不是相对于body。而是相对于其父元素,假设这样的场景:

<body>
      <div  class="parent"></div>
      <div  class="parent">
          <div class="children"></div>
      </div>
</body>

如果这样设置 font-size:

body {font-size: 12px}
.parent{font-size: 2em;}
.children{font-size: 3em;}

那么他们的font-size分别是:

body ==> 12px
.parent ==> 12px * 2 = 24px;
.children ==> 24px * 3 = 72px;

所以使用em做为单位还是要注意一些。详细的可以看看《CSS中强大的EM》。更多有关于CSS单位的介绍可以点这里

 
@zheyueguohou
 

@airen 其实我上面也说了父元素,所以用em的时候只需要注意父元素的font-size,加上一个页面大部分的字体大小都是相同的,只需要对特定的大小设置em。这种方法的弊端就是需要时刻注意父元素的font-size。不过还是谢谢@airen的回答^_^...

 
@airen
 
Contributor
airen commented on 24 Dec 2015

@w3cay 引用@terrykingcha的话来回:

这个540其实是个经验值,或者最大值,这个经验是怎么得出来的呢?
目前主流手机最大的css像素尺寸,是540(比如devicePixelRatio为2,分辨率是1080x1920的手机),所以用了这个经验值。这样可以让在ipad横屏这种情况下浏览无线页面,不至于因为拉伸适配后体验太差。
body上设置12 * dprfont-size值,为了重置页面中的字体默认值,不然没有设置font-size的元素会继承html上的font-size,变得很大。

 
@airen airen referenced this issue in amfe/lib-flexible on 24 Dec 2015
 Closed

今天看了源码 有点不明白 #14

@laijuncheng
 

有些安卓设备下,HTML的font-size是54PX,这时该怎么办呢?比如我司的一个同事手机分辨率是720X1280,这时的font-size是54PX,尺寸就会小很多,还是说我对这篇文章的理解有误差?

 
@camnpr
 

好文。。。

 
@eijil
 
eijil commented on 28 Mar 2016

我想知道demo中 flag-item.figcaption样式中 wdith:133rem怎么算出来的?

 
@zhuziyi1989
 

流明。

 
@zwj47
 
zwj47 commented on 11 Apr 2016

学习了

 
@121595113
 

看了好几遍这个库了。之前用过一次,写出来的页面样式没有任何问题,但是在写事件的时候出现了事件偏移的问题。没找到解决方法,最终放弃了。推荐一个纯css的H5适配方案给大家,也请大漠帮忙看看传送门

 
@whatlife
 
whatlife commented on 16 May 2016 • edited

@DoranYun,我猜测是因为变化的字体的font-size没有设置,是继承自父级元素的font-size吧?我有遇到过类似情况:
html

<div>
<p>我是一段文字</p>
</div>

css

div{font-size: 0.75rem}
p {...}

这个时候刷新页面,p的文字就会先大,后又变成.75rem,肉眼看起来就是屏幕闪烁

 
@MeCKodo
 

@whatlife 好像有遇到过即使写了 也会闪烁,不知道有没有好的解决方案,我们现在是直接用px写了,就不会闪烁

 
@ggpp224
 

您好:
我不明白一点: initial-scale 为什么要根据dpr进行缩放呢。 设为固定值1, 再根据屏幕宽度计算rem相对值可以吗? 因为我在实践中发现不同的内核在initial-scale进行缩放时会对ui产生意想不到的问题。 比如textarea字体overflow不是hidden的情况下宽度大于大概75%时会放大, div滚动条在dpr为3的情况下会缩小到一条细线。

 
@chshouyu
 

背景图是不是只需要切一个最高像素的就可以了?

 
@luzhilin
 

@whatlife 字体保留px 建议用gulp将px转化成rem

 
@zhoufenfens
 

字体用px,那在750上设计好的font-size,放在ip5上不会显得字体很大吗

 
@flyer153
 
flyer153 commented on 25 May 2016 • edited

mark,字体这个用px如果能改善就好了,另外文档写的虽然很多,但感觉用起来还是不方便,比如640的宽该怎么用并没有详细的说明,只能自己去摸索。

 
@webliving
 

div {
width: 1rem;
height: 0.4rem;
font-size: 12px; // 默认写上dpr为1的fontSize
}

[data-dpr="2"] div {
font-size: 24px;
}

[data-dpr="3"] div {
font-size: 36px;
}

这样dpr 不为 2, 3 的字体会太小吧 ??

 
@galenjiang
 
galenjiang commented on 6 Jun 2016 • edited

我发现一个很奇怪的现象。当设计稿为iphone6时,为了好计算,我没有按照10来除,而是换成7.5的来做计算。页面在渲染字体大小时,超过某个大小(如0.14618rem)时,会被放大处理,这种情况在chrome中产生,手机测试没有问题,虽然不影响用户体验,但在开发中会造成很大的麻烦。由于安卓系统统一设置dpr=1则没有这样的情况出现。还有个特别奇怪的现象,假如按照10来处理,除了chrome下因为字体不能小于12px的情况,并不会出现被放大的情况。

 
@dd1994 dd1994 referenced this issue on 7 Jun 2016
 Open

在移动端怎么适配 #38

@zhansingsong
 
zhansingsong commented on 13 Jun 2016 • edited

@airen 请教一个问题?在px2rem的mixin中
// If the value is zero or not a number, return it
@if $value == 0 or type-of($value) != "number"{
$rem-values: append($rem-values, $value / $baseline-rem);
}
为啥样要这样处理? 如果这样处理怎么调用?
我理解是这样调用 :@include px2rem('background-size', 230 24);
如果这样调用,type-of($value) != "number"应该是type-of($value) == "number"

 
@Rookiewan
 

@galenjiang 我也遇到一样的问题了,chrome上看起来有点大,不知道是不是chrome的计算问题,但是,看了本文的demo,发现不会发生这种现象,不知道是不是我的chrome有毒。

 
@huoruji
 

大家好,我现在遇到一个bug,就是给一个div单独设置上下边框都为1px的时候,在ios下只有一个边框的线会缩小成0.5px,另一条还是1px,有点诡异,不知道大家有么有遇到过

 
@dd1994
 

@huoruji 你倒是发一个外网可以访问的 demo

 
@huoruji
 

@dd1994 不好意思,我现在没有外网访问的地址,只能附图一张,只有第一条上边框和最后一条下边框的线缩成0.5px,中间的线都是1px
img_2433

 
@renxj renxj referenced this issue in weixin/tmt-workflow on 24 Jun 2016
 Closed

雪碧图自动适配问题 #44

@weapon-xx
 

学习了,感谢分享~

 
@SenYu
 
SenYu commented on 27 Jun 2016

@huoruji 做这种边框ios 上建议用 一张1px高的图片来做

 
@huoruji
 

@SenYu 用图片那这样不会影响到渲染的效率么?

 
@SenYu
 
SenYu commented on 27 Jun 2016

@huoruji 指render部分?这要有性能问题也没谁了…………用base64硬编码到css,抽象成一个class,设置background-image和repeat,哪里要用就把class写过去,别用一整个background属性覆盖就行……

 
@huoruji
 

@SenYu 醍醐灌顶,多谢分享~

 
@flyer153
 

用Flexible写了几个项目之后发现,还是存在一些问题,比如做活动页面时候字体有时候为14或者16,这样当dpr_2 dpr_3的时候字体就不标准了,显得非常大,需要手动去调整倍数。

 
@dd1994
 

@flyer153 你把 dpr 都设置为 1 不就好了

 
@junhey
 

最近接触移动端比较多之后才发现了类似的问题,为阿里点赞

 
@lienmac lienmac referenced this issue in lienmac/learnGulp on 30 Jun 2016
 Open

安装gulp #1

@flyer153
 

@dd1994 感谢回答,试过了,都设置为1不行,在有些手机上字体太小了。

 
@dd1994
 
dd1994 commented on 1 Jul 2016

@flyer153 安卓机器上 flexible 都是自动把 dpr 设为1的!

 
@eric2013
 

请问一下你的那些测试数据是通过js插件实现?

 
@fromIRIS
 

有个疑问:
在ios下根据dpr的不同将页面进行缩放有没有绝对的必要?

if (!dpr && !scale) {
        var isAndroid = win.navigator.appVersion.match(/android/gi);
        var isIPhone = win.navigator.appVersion.match(/iphone/gi);
        var devicePixelRatio = win.devicePixelRatio;
        if (isIPhone) {
            // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
        } else {
            // 其他设备下,仍旧使用1倍的方案
            dpr = 1;
        }
        scale = 1 / dpr;
    }

metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');

我们知道动态的改变initial-scale会改变页面layout viewport,从而改变页面的html标签的宽度。
如图,
image

image

这样有一个好处是完全的高清显示,改善了「著名」的border:1px 问题。见连接:http://www.html-js.com/article/Mobile-terminal-H5-mobile-terminal-HD-multi-screen-adaptation-scheme%203041

但是除此之外我好像找不到其他这样做的理由了。

至于retina图片的适配,dpr限定为1也是同样能操作的(@2x图)

dpr进行变换还要去维护字号在不同dpr下的兼容。

基于这几个考量?flexible.js中将iphone条件下的initial-scale进行动态变换真的有必要吗?

 
@zchen9 zchen9 referenced this issue in zchen9/code on 16 Jul 2016
 Open

20160606 - 20160710 #4

@Leega0
 

这时候如果又要使用媒体查询好像有些不便了

 
@jyzwf
 
jyzwf commented on 1 Aug 2016

请问这个框架在安卓和苹果的微信端是不是良好支持呢?

 
@youngwind
 

@fromIRIS 我也有同样的疑问。

if (!dpr && !scale) {
        var isAndroid = win.navigator.appVersion.match(/android/gi);
        var isIPhone = win.navigator.appVersion.match(/iphone/gi);
        var devicePixelRatio = win.devicePixelRatio;
        if (isIPhone) {
            // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案
            if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {                
                dpr = 3;
            } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){
                dpr = 2;
            } else {
                dpr = 1;
            }
        } else {
            // 其他设备下,仍旧使用1倍的方案
            dpr = 1;
        }
        scale = 1 / dpr;
    }

这一段代码,把所有安卓机的dpr假定为1(理由是部分安卓机的dpr并不准确),也就是说,其实dpr是多少并不影响布局。为什么要引入dpr和scale呢?
我看了这篇文章,是不是为了解决 1px border和高清图片的问题? 那意思是不是说,在所有的安卓机上其实都不是高清图片?

 
@fwon
 
fwon commented on 4 Aug 2016
@youngwind youngwind referenced this issue in youngwind/blog on 15 Aug 2016
 Open

如何开发一个移动web UI组件库:适配篇 #82

@clownvary
 
clownvary commented on 15 Aug 2016 • edited

看了几遍文章,然后自己试了试,我专门用的们的750x1600的设计稿来做得,我遵循了文章中的原则:

1.严格按750得高清样稿的尺寸编写css
2.字体基本没有用rem
3.最后使用postcss_px2rem,编译
结果在ip5/6/6plus/一些安卓机上都很正常,但有个问题,_在ipad或者各种设备横屏的情况下,样式就没法撑开_,像这样
img
我调了大半天也不知道问题在哪,这是我的demo,麻烦看下是怎么回事
update:已经修复好了,是条目栏应该用100%的宽度。

在这里我的理解是,如果你的项目要适配移动设备,同时也对pc或大屏幕尺寸设备友好显示的话,如果是按照750xXXX的设计稿设计的话,在这种外部container或者容器中如果是占满的话,就不要使用固定的750px,而是直接用100%,在内部的各组件就按设计稿的尺寸,该是多少就写多少,最后使用px2rem进行转换。

 
@lijinpeng7364
 

@clownvary 这个库本身设定了最大值,当页面宽度大于某个值的时候,计算rem基数的基准就是这个值而不是页面实际的宽度。这种情况下,计算出来的rem的基数就会比实际要小,某些元素的属性实际展现就会比预想的要小。实际上,我觉得淘宝的想法应该是这个库本身是适用于移动端的页面,是小页面通用的,而当页面大于某个值的时候,这一套体系下很多东西就不适用了,比如说字体或者某些元素的宽度之类的,这种情况下他们推荐的做法应该是以他们设定的这个值为基准来布局,但是把页面的主体元素居中,两边留空。

var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
    width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
 
@wy2016xiao
 

今天用这套方案做了一个手机网页,在适配手机QQ浏览器的时候发生了问题,具体情况就是100%宽度在手机QQ浏览器上出现变宽了,导致出现横向滚动条,并且所有内容都变大了一圈,求大牛解决

 
@fengyuanzemin
 
fengyuanzemin commented on 29 Aug 2016 • edited

visual viewport是可见视口,不是虚拟视口:flushed:

 
@wweggplant
 

布局上单位使用动态计算出rem,布局使用flex,字体使用px

 
@flyer153
 

@wweggplant 布局不用flex貌似也没问题吧!

 
@cwtuan
 
cwtuan commented on 8 Sep 2016

@lijinpeng7364
我在做大页面的时候,直接拿掉

if (width / dpr > 540) {
    width = 540 * dpr;
}
 
@eyeA
 
eyeA commented on 9 Sep 2016

yes

 
@dingdingdw
 
dingdingdw commented on 12 Sep 2016 • edited

有一处没看懂,你文中有一段提到flexible将设计图分为100份,1份被看作1a,也就是设计图被分为了100a;而后面一段又说示例设计图就被分为了10a???什么意思???即使是10a,那宽度不应该是1rem嘛?因为1rem被认为是10a啊???求解释!
20160912150231

 
@xiaoyann
 

为什么还有人在用这个?解决什么问题?

 
@fromIRIS
 

@xiaoyann 适配不同屏啊

 
@tangshengfei
 

大体布局结构用flex,具体涉及到大小具体单位设置的话 就用它,都有用。

 
@shineSnow
 

受教了

 
@kafeigeiwo
 

很感谢您回答了我长期以来不清不楚的问题!!!太棒了!!!!

 
@Alan-tao
 

这个例子怎么下载尼

 
@zhiqiang21 zhiqiang21 referenced this issue in zhiqiang21/blog on 6 Oct 2016
 Open

再谈移动端适配和点5像素的由来 #30

@zerofront
 

想请教一下,为什么不直接用百分比去实现布局,而用这个?

 
@4013465w
 

@zerofront 水平可以,垂直呢?

 
@MoyanGG
 

@zerofront 高度在使用有些时候使用百分比不方便

 
@shuijingleihen

我想问下为什么Android系列的dpr要统统设置为1

 
@Youbaofeng
 
Youbaofeng commented on 27 Oct 2016 • edited

赞了一下 wy2016xiao 的回答,
我在开发中也接触过这样的问题,不知道什么原因,JS不能得到准确的屏幕宽度导致页面溢出。
用小米4的微信自带浏览器打开,解析的font-size = 98px; dpr=2 但是其实这个屏幕宽度只有 360px;

 
@Josieee
 

initial-scale=0.5 或者为0.3333 是不是会对二维码识别有影响,因为发现改为1的话在微信ios中能识别,但是0.5跟0.333的情况下在微信ios版中都识别不了。有没有人遇到过?

 
@tiansn tiansn referenced this issue in tiansn/blog on 10 Nov 2016
 Open

移动端自适应方案调研 #2

@caowenhai888
 

我之前一直使用这种方式 请问有什么不同和弊端么

(function() {
	var b = navigator.userAgent;
	ipad = b.match(/(iPad).*OS\s([\d_]+)/) ? !0 : !1;
	iphone = !ipad && b.match(/(iPhone\sOS)\s([\d_]+)/) ? !0 : !1;
	ios = ipad || iphone;
	var a;
	if (ios && 2 <= window.devicePixelRatio) {
		a = .5;
		b = 2;
		a = '<meta id="viewMeta"content="width=device-width,initial-scale='+ a +',minimum-scale='+ a + ',user-scalable=no"name="viewport">';
		var c = document.getElementById("viewMeta"),
				d = c.parentNode;
		d && d.removeChild(c);
		alert(a)
		document.write(a);
		document.documentElement.style.fontSize = 50 * b + "px"
	}
})();
 
@aweakcoder
 

请问android手机放大系统字体,页面整体会放大,这个问题咋解决呢

 
@rocky-191
 
rocky-191 commented on 6 Dec 2016 • edited

@airen 请教下,直接引入这个库就可以吗?不用做其他配置,顶部也不用写<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">?

 
@w3cay w3cay referenced this issue in w3cay/blog on 7 Dec 2016
 Closed

优化移动端适配方案 #1

@chrisbobi
 

为什么写多个圆,设置圆为rem单位,有些显示的非正圆,会变成椭圆。border-radius:100%,是这么设置的!

 
@wbpmrck
 

移动端的viewport太窄,为了能更好为CSS布局服务,所以提供了两个viewport:虚拟的viewportvisualviewport和布局的viewportlayoutviewport。

这里"visual viewport"不应该翻译为“虚拟的”,而应该是“视觉视口”吧

 
@daimingjun
 

关于 border 怎么使用呢? 比如 border: 1px solid #ddd; 中的 1px 也要转成 rem 吗?

 
@mengxingshike2012

受教了

 
@p2227 p2227 referenced this issue in p2227/p2227.github.io on 25 Dec 2016
 Open

手机屏幕适配:原理与解决方案 #16

@zdddrszj
 

有rem为什么还用scale

 
@wind-stone
 
wind-stone commented on 3 Jan

请教一下:
1、android 设备即使 DPR = 2/3 也不做缩放处理,是基于什么考虑?
2、对段落字号做特殊处理,原先 CSS 里只要产出一种关于字号的规则,因为不同的 DPR 现在要产出里会有三种不同的规则,这里是否可以优化?
`
[data-dpr="1"] #page-slogan span {
font-size: 12px;
}

[data-dpr="2"] #page-slogan span {
font-size: 24px;
}

[data-dpr="3"] #page-slogan span {
font-size: 36px;
}
`

 
@jr-haynas
 
jr-haynas commented on 5 Jan

大漠老师,我在引用这个flexiable的时候,字体一开始是可以适配的,但是缩放浏览器,刷新页面的时候就不能适配了,这是什么问题呢?是不是环境还是哪里配置除了问题啊?

 
@leoyaojy leoyaojy referenced this issue in leoyaojy/tips on 8 Jan
 Open

10、前端资源汇总 #10

@yohehc
 
yohehc commented on 10 Jan

请教一下 ,为什么要将视觉稿放大1.5倍再切呢?谢谢~

 
@cy0707
 
cy0707 commented on 12 Jan • edited

大漠老师,对您的那个使用Sass的混合宏px2rem有一点疑问。想请教一下。

@mixin px2rem($property,$px-values,$baseline-px:16px,$support-for-ie:false){
    //Conver the baseline into rems
    $baseline-rem: $baseline-px / 1rem * 1;

这里的$baseline-px / 1rem除法中$baseline-px默认值是不是不应该带单位。
单位不同,是不能相除的。编译会出错的吧。

还有这个同学@zhansingsong提出的那个问题。

@else {
       //Create an empty list that we can dump values into
       $rem-values:();
       @each $value in $px-values{
           // If the value is zero or not a number, return it
           @if $value == 0 or type-of($value) != "number"{
               $rem-values: append($rem-values, $value / $baseline-rem);
           }
       }
       // Return the property and its list of converted values
       #{$property}: $rem-values;
   }

这里type-of($value) != "number"判断条件应该是等于吧。不然的话,这样调用的话,
编译会出现如下错误。

.box {
   @include px2rem(padding, 20 40);
}
//() isn't a valid CSS value.

如果想不带单位的调用。按您写的那种方式的话。需要把默认,$baseline-px的单位去掉,
还有那个判断条件也要改一下。

我还想到如果带单位的调用的话,我稍微修改了一下。

@mixin px2rem($property,$px-values,$baseline-px:16px,$support-for-ie:false){
    //Conver the baseline into rems
    // $baseline-rem: $baseline-px / 1rem * 1;
    // @debug  #{$baseline-rem};
    //Print the first line in pixel values
    @if $support-for-ie {
        #{$property}: $px-values;
    }
    //if there is only one (numeric) value, return the property/value line for it.
    @if type-of($px-values) == "number"{
        #{$property}: $px-values / $baseline-px * 1rem;
        @debug  #{$property};
    }
    @else {
        //Create an empty list that we can dump values into
        // example padding: 10px 20px;
        $rem-values:();
        @each $value in $px-values{
            // If the value is zero or not a number, return it
            @if type-of($value) == "number"{
                
                $rem-values: append($rem-values, $value / $baseline-px * 1rem);
            }
        }
        // Return the property and its list of converted values
        #{$property}: $rem-values;
    }
}
.box {
	@include font-dpr(14px);
	@include px2rem(padding, 20px 40px);
}
 
@cy0707 cy0707 referenced this issue in cy0707/mobile_develop on 13 Jan
 Open

2016对于做前端移动端的一些感悟 #2

@Sapphire2k
 
Sapphire2k commented on 17 Jan

@dingdingdw ”当前方案会把这3类视觉稿分成100份来看待(为了以后兼容vh,vw单位)。每一份被称为一个单位a。同时,1rem单位认定为10a。“ 确实是 100a 所以 1a = 7.5px

 
@LikeDege
 
LikeDege commented on 17 Jan

@airen 使用这个适配的方案后,border要怎么实现,直接设置为1px后,在不同设备像素比的手机上会粗细不一致?求大神解决?

 
@chenchenyuyu
 

学习了

 
@ecommerce888
 

学习了

 
@HelKyle
 
HelKyle commented on 22 Jan

用过这种方式去做设配,觉得修改 meta 的方式饶了一圈,而且不太直观。

我的做法还是保留,meta viewport 不变。

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

只不过在使用 rem 单位的时候做了下处理,比如 640 的设计稿

@function rem($num, $base: 32) {
    @return $num / $base * 1rem;
}
@function size($size) {
    @return rem($size * 0.5);
}

function size 算是特定的单位,用来把设计稿中的像素值转为 rem。

 
@hex-ci
 
hex-ci commented on 23 Jan

@Uheinanba @meiyzeng 关于 emoji 缩小的问题,我改进了一下 lib-flexible 类库,表情不会缩小,也不影响 1px 问题。表情缩小的主要原因是对 viewport 做了缩放。

 
@hex-ci
 
hex-ci commented on 23 Jan

我做了一个转换 px 为 rem 单位的 Atom 编辑器插件: https://github.com/hex-ci/px2rem-plus

主要功能:

  • 自动完成

  • 转换编辑器中的内容

    支持转换全部文本或选中的文本内容。快捷键: ctrl-alt-r

  • 为当前文件设置基准像素大小

    每个文件可以有自己的基准值,并且这个设置会自动保存,下次打开相同文件会自动使用设置过的值。快捷键: ctrl-alt-p

  • 添加注释

    支持给转换后的 rem 单位添加注释,例如 /* 100/75 */

  • 保留前导零

    如果转换后的值小于 1,则可以选择是否保留前导零,例如 0.5rem(保留) 或 .5rem(不保留)

  • 演示

 
@7demo
 
7demo commented on 24 Jan

@xiaoyann 你有什么更好的方案?

 
@meiyzeng
 
meiyzeng commented 19 days ago

@hex-ci 表情问题是viewport缩小引起的,你改进后的 lib-flexible 有没有demo和说明共享?

 
@hex-ci
 
hex-ci commented 19 days ago • edited

@meiyzeng 我 fork 了一份 lib-flexible,主要改动就是可以自定义缩放大小(原版就支持),但可以保留当前页面实际的 data-dpr 属性,所以在不缩放页面的时候也能解决 1px 问题。

 
@rocky-191
 

有完整的代码实例吗?可以发一份吗1375022007@qq.com

 
@earlymeme
 

mark

 
@rainbowzx
 
 rainbowzx commented 15 days ago
 

推荐阅读