手机淘宝的flexible设计与实现

手机淘宝的flexible设计与实现

寒冬winter 发布在winter同样冷201587view70095HTML5CSSCSS3移动开发css

在文章任何区域双击击便可给文章添加【评注】!浮到评注点上能够查看详情。html

 

看到小黑的文章 关于webapp中的文字单位的一些捣腾 感受很赞。尤为是,他提到了手机淘宝的meta,因此以为要讲讲咱们这方面的一些实践。git

 

手机淘宝从2014年中开始,全面推行flexible设计。什么叫flexible呢?其实flexible就是responsive的低端形态和基础。对咱们来讲,最直观的感觉就是,在超宽屏幕上,网页显示不会两边留白。之前pc时代你们常常讲的流体布局,其实就是一种flexible design。只不过,流体的表述角度是实现,flexible的表述角度是结果,为了跟高大上的responsive保持一致,咱们这里使用了flexible这个说法。github

 

讨论方案以前,须要先了解三个关键概念:web

 

单位英寸像素数(Pixel Per InchPPI):现实世界的一英寸内像素数,决定了屏幕的显示质量app

设备像素比率(Device Pixel RatioDPR):物理像素与逻辑像素(px)的对应关系webapp

分辨率(Resolution):屏幕区域的宽高所占像素数布局

 

 

当咱们决定不一样屏幕的字体和尺寸的单位时,屏幕的这几个参数很是重要。字体

 

场景1——Resolution适配flex

一张banner图片,当你面对不一样的屏幕时你但愿它的行为是怎样的?

在这个场景中,咱们主要须要面对的是分辨率适配问题,考虑到多数网页都是纵向滚动的,在不一样的屏幕尺寸下,banner的行为应该是老是铺满屏幕宽度以及老是保持宽高比。

最天然的思路是使用百分比宽度,可是假如使用百分比宽度,即width:100%,咱们又有两种思路来实现固定宽高比:一是利用img标签的特性,只设宽度等图片加载完,这种方法会致使大量的重排,而且非固定高度会致使懒加载等功能难以实现,因此果断放弃;二是使用before伪元素的margin撑开高度,这种方法是比较干净的纯css实现,可是不具有任何复用性并且要求特定html结构,因此也只好放弃了。

因而,剩下最合适的办法是使用其它相对单位,原本最合适的单位是vw,它的含义是视口宽度,可是这个单位存在严重的兼容问题,因此也只好放弃。

最后咱们只好配合js来作,硬算也是一条路,可是一样不具有任何可复用性,最终咱们选择了rem,咱们用jshtml设置一个跟屏幕宽度成正比的font-size,而后把元素宽高都用rem做为单位。

这是咱们目前的线上方案了,它是一个近乎Hack的用法,已知的问题包括:

某些Android机型会丢掉rem小数部分

占用了rem单位

不是纯css方案

 

场景2——PPI适配

一段文字,当你面对不一样的屏幕时你但愿它的行为是怎样的?

显然,咱们在iPhone3GiPhone4Retina屏下面,但愿看到的文字尺寸是相同的,也就是说,咱们不但愿文字在Retina屏尺寸变小,此外,咱们在大屏手机上,但愿看到更多文字,以及,如今绝大多数的字体文件,是自带一些点阵尺寸的,一般是16px24px,因此咱们不但愿出现13px15px这样的奇葩尺寸。

这样的特征决定了,场景1中的rem方案,不适合用到段落文字上。因此段落文字应该使用px做为单位,考虑到Retina,咱们利用media query来指定不一样的字体,考虑到dpr断定的兼容性,咱们用宽度替换来代替:

.a {

    font-size:12px}

@media (min-width: 401px){

    .a {

        font-size:24px

    }}

另外一种场景,一些标题性文字,但愿随着屏幕宽而增大的,咱们能够仍然使用rem做为单位。超过35px(我的直观感觉)的文字,已经不用太考虑点阵信息了,靠字体的矢量信息也能渲染的很好。

 

场景3——DPR匹配

一个区块,设计稿上有1像素边框,当你面对不一样的屏幕时你但愿它的行为是怎样的?

这个场景,需求很简单,设计师但愿在任何屏幕上这条线都是1物理像素。

好吧,固然这个问题的答案不是写1px那么简单。在retina屏下面,若是你写了这样的meta

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

你将永远没法写出1px宽度的东西,除此以外,inlineSVG等元素,也会按照逻辑像素来渲染,整个页面的清晰度会打折。

因此,手机淘宝用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);}

结语

总的来讲,手机淘宝的flexible方案是综合运用rempx两种单位+js设置scalehtml字体。

这些JS的内容,能够在咱们开源的库ml中找到:

https://github.com/amfe/lib.flexible

相关文章
相关标签/搜索