H5 必知必会之像素级还原设计稿

栏目: Html · 发布时间: 7年前

内容简介:编者按:本文作者李松峰,资深技术图书译者,翻译出版过40余部技术及交互设计专著,现任360奇舞团高级前端开发工程师,360前端技术委员会委员、W3C AC代表本文是“H5必知必会”系列第二篇。在第一篇“不能不说,这个现象很神奇。也许,在前端行业之外人的眼里,手机屏幕上的网页就应该有一个跟大屏幕上的网页不一样的名字,这样才好区分。事实上,就算是在前端开发行业内,有这么一个词让我们瞬间就可以定位到一种应用形态,至少也是一件非常便利的好事。

编者按:本文作者李松峰,资深技术图书译者,翻译出版过40余部技术及交互设计专著,现任360奇舞团高级前端开发工程师,360前端技术委员会委员、W3C AC代表

本文是“H5必知必会”系列第二篇。在第一篇“ H5必知必会之与App交互 ”中我们提到过,所谓“H5”本来应该是HTML5的简称。但是,在中国,“H5”并不是HTML5的简称那么简单,它更多地被用于指代内嵌在手机App中的网页。无论国外有没有“H5”这个说法(应该没有),反正在国内只要说到App内嵌的网页或网页应用,你完全可以说它是“H5”。一说“H5”,产品经理、设计师、Android/iOS应用开发者、后端工程师全都明白。

不能不说,这个现象很神奇。也许,在前端行业之外人的眼里,手机屏幕上的网页就应该有一个跟大屏幕上的网页不一样的名字,这样才好区分。事实上,就算是在前端开发行业内,有这么一个词让我们瞬间就可以定位到一种应用形态,至少也是一件非常便利的好事。

那么手机上的网页跟大屏幕上的网页有什么不同呢?

首先,手机上的网页运行在手机浏览器或者App内嵌的WebView中,可以使用手机特有的硬件能力,比如GPS、加速计、陀螺仪等传感器;此外,如果加载了宿主App的JSSDK,还可以访问App暴露给网页的各种能力,比如获取登录用户的信息、拍照上传和分享,等等。

其次,手机上的网页布局设计要服从于原生App的界面(UI)设计规范,比如谷歌的扁平化设计Material Design,苹果的人机界面指南(Human Interface Guide)等;总之,手机上的网页看起来必须像原生App的界面,包括使用与原生App一致的布局组件、字体图标、配色方案,乃至交互模式等,比如要支持触摸而非鼠标点击交互。

最后,手机上的网页,特别是运行于App内的网页,构成混合移动应用的一部分,通常都需要与原生App互操作;需要H5与原生应用双方共同商定基础接口,并针对特定的交互场景确定具体的交互模式,包括单向调用还是双向调用,同步还是异步,如何传递数据和凭据,等等。

上述第三点,正是本系列第一篇文章“H5必知必会之一App交互”讨论的内容,感兴趣的同学稍后可以参考。那么今天,本文要讨论的则是上述第二点,即H5在构造页面布局时,如何逼真、像素级还原设计稿。

适配与还原:概念阐述

要说还原,必须先从适配说起。

H5适配手机主要有两个维度:

  • 适配不同像素密度

  • 适配不同屏幕大小

像素密度,顾名思义就是CSS中的1像素对应多少物理像素。我们以这张iPhone各代屏幕对照图(来源:https://www.paintcodeapp.com/news)为例:

H5 必知必会之像素级还原设计稿

先看iPhone Xs Max和iPone XR。前者屏幕用CSS像素度量是414x896,而用实际渲染的物理像素度量则是1242x2688像素,简单换算可知,1242/414 = 3(或2688/896 = 3)。换句话说,iPhone Xs Max是人们常说的3倍屏(或@3x),即每个CSS像素对应9个物理像素(因为宽高均为3像素)。而iPhone XR呢,则是人们常说的2倍屏(或@2x),每个CSS像素对应4个物理像素。

当然还有1倍屏。上图最后一个iPhone 2G/3G/3GS,就是1倍屏,即每个CSS像素对应1个物理像素。像这种估计市面上已经绝迹的初代iPhone是不用适配的,因为1个CSS像素就对应屏幕上的1个物理像素。(当然,笔记本和电脑外接的大屏幕至今都是1倍屏,所以目前还不需要我们适配像素密度。)

我们常说的适配像素密度,通常指图片如何在3倍屏和2倍屏上显示不失真。当然,适配原则非常简单:1个图片像素对应1个物理像素,图片就不会失真。具体来说,假设原始图片是500x300像素(如image@1x.jpg),那么适配高密度屏的版本则分别是1500x900像素(如image@3x.jpg)和1000x600像素(如image@2x.jpg)。这样才能做到1个物理像素对应到1个图片像素。

当然,也有一个简单粗暴的适配方案,就是针对所有屏幕,都只提供最高清图片。虽然低密度屏幕用不到那么多图片像素,而且会因为下载多余的像素造成带宽浪费和下载延迟,但从结果上说能保证图片在所有屏幕上都不会失真。

适配像素密度的具体技术方案本文就忽略了,因为它不是本文的重点。本文的重点其实是适配不同屏幕大小。适配不同屏幕大小的原则非常简单: 确保页面布局的度量与屏幕大小保持一定比例

听起来简单,做起来可不容易。因为这里就涉及还原设计稿的问题了。比如,设计稿宽度通常是750像素:

H5 必知必会之像素级还原设计稿

在这个宽度下,不同页面组件都有各自的度量值,比如,“对音箱说”这个标题的度量为112x28像素:

H5 必知必会之像素级还原设计稿

而标题的上、右、下、左,距离当前组件的边界,分别是38像素、289像素、394像素和289像素:

H5 必知必会之像素级还原设计稿

当然,每个组件与屏幕边界、组件与组件之间,乃至文本大小、间距,在这个设计稿中也都有确定的像素值度量。那么问题来了,面对设计稿中林林总总的像素值,我们如何在H5页面中还原它们?

答案很简单:按比例还原。

仍然以前面的设计图为例,我们知道设计稿假定的屏幕宽度为750像素(实际上多少像素都没问题,因为我们是按比例还原设计稿),而如下面几张图所示,这个圆角矩形组件的宽度是690像素:

H5 必知必会之像素级还原设计稿

它与上方距离为30像素(与左、右边界同样是30像素):

H5 必知必会之像素级还原设计稿

有了这些像素数据,经过简单的数学换算,不难得出:

  • 组件宽度占屏幕宽度的百分比为:690/750 = 0.92,即92%;

  • 组件上、右、左边距占屏幕宽度的百分比为:30/750 = 0.04,即4%。

好了,现在只要能让浏览器(WebView)按照这个比例去渲染,我们的组件就能做到对设计稿的像素级还原——在750像素宽的屏幕上,组件及其子组件的所有像素度量都能严格与设计稿保持一致!

更重要的是,在屏幕不是750像素的情况下(事实上750像素宽的手机屏幕至今还没出现过,注意我是CSS像素宽度),页面的布局依旧可以按照设计稿的既定比例完美适配,即在大一点的屏幕上,页面的方方面面都会显示得大一些;而在小一点的屏幕上,则整个布局都会按比例缩小一些。

事实上,除了宽度、高度和间距,文本大小(即 font-size )、边框、阴影等度量也可以按这个思路把像素转换为百分比。

好了,以上就是关于适配和还原的概念阐述。接下来,我们从理念到实践,看一看技术上如何实现吧。

一个全局性CSS单位

上一节概念阐述提到按比例适配可以做到像素级还原设计稿。但是,实践中可以直接在CSS里使用百分比单位吗? 很可惜,不能

我们知道,根据CSS Values and Units Module Level 4(https://www.w3.org/TR/css-values-4/#percentages)的定义:

百分比值总要相对于另一个量,比如长度。每个允许使用百分比值的属性,同时也要定义百分比值参照的那个量。这个量可以是相同元素的另一个属性的值,也可以是祖先元素的某个属性的值,甚至是格式化上下文的一个度量(比如包含块的宽度)。

那我们也知道:

  • 宽度( width )、高度( height )、间距( maring / padding )支持百分比值,但默认的相对参考值是包含块的宽度;

  • 边框( border )不支持百分值;

  • 边框圆角半径( border-radius )支持百分比值,但水平方向相对参考值是盒子的宽度,垂直方向相对参考值是盒子的高度;

  • 文本大小( font-size )支持百分比值,但相对参考值是父元素的 font-size 的值;

  • 盒阴影( box-shadow )和文本阴影( text-shadow )不支持百分比值;

  • ……

可见,即使支持使用百分比值的属性,其百分比参考值也都不是我们想要的屏幕宽度!换句话说,要实现屏幕级的适配,必须有一个统一的全局性单位供我们参照。我们有吗?有。

首先,有一个 rem 。同样,根据CSS Values and Units Module Level 4(https://www.w3.org/TR/css-values-4/#font-relative-lengths):

(rem)等于根元素(也就是 html 元素) font-size 属性的计算值。

rem 归根结底是一个 font-size ,但却是一个全局性的度量单位,而且其背后还是像素。如果为了适配目的,根据不同屏幕密度动态修改 rem 的值(比如, document.documentElement.style.fontSize = rem + 'px' ),不就可以实现按比例适配了吗?事实上,阿里手机淘宝团队专门为此研发了一个框架:https://github.com/amfe/lib-flexible。从Github仓库来看,这个框架用了大概有两年多时间,2019年年初正式宣布退役。因为又找到了新的更好的全局性参照单位: vw

什么是 vw ?同样根据CSS Values and Units Module Level 4:

(vw)等于初始包含块(html元素)宽度的1%。

换句话说,可以认为: 1vw 就等于屏幕宽度的 1% 。哇,这个单位似乎是专门为我们适配量身打造的。首先,它本质上就是一个百分比单位,比如 3vw 就相当“屏幕宽度的3个百分点”;其次,它又是全局性的与屏幕宽度直接相关的单位。那么上一节概念阐述中举的两个百分比的例子,用 vw 单位可以直接写成:

  • 组件宽度占屏幕宽度的百分比为:690/750 = 0.92,即 92vw

  • 组件上、右、左边距占屏幕宽度的百分比为:30/750 = 0.04,即 4vw

那么移动浏览器对 vw 的支持度如何呢?根据caniuse.com(https://caniuse.com/#search=vw):

H5 必知必会之像素级还原设计稿

即iOS 8+和Android 4.4+都支持 vw ,而目前的手机应用通常支持iOS 9+和Android 5+。所以,实践中使用 vw 单位完全可行。而这也正是手机淘宝团队今年年初正式转向使用 vw 单位适配的原因。

那么,现在唯一的问题就是人工进行设计稿的 pxvw 单位的转换太麻烦。不过,如果你在开发中使用Webpack编译打包,那么已经有人开发了postcss的插件:postcss-px-to-viewport(https://www.npmjs.com/package/postcss-px-to-viewport)。配置好这个插件,你写CSS的时候可以严格按照设计稿上的像素值去写,这个插件负责将你写的 px 转换为 vw 。这样一来,我们所说的“像素级还原设计稿”,就彻底打通了开发和呈现,真的做到了“像素级”!

(假如,我只是说假如你没有或不能使用Webpack打包,那么你可能还需要人工计算。)

使用postcss-px-to-viewport

这一节实际是没有必要的。不过,为了完整起见,我们就简单说一下postcss-px-to-viewport插件的配置。以下内容截取自.postcssrc.js配置文件:

module.exports = {

"plugins" : {

// ...

"postcss-px-to-viewport" : {

viewportWidth : 750 ,

viewportHeight : 1334 ,

unitPrecision : 3 ,

viewportUnit : 'vw' ,

selectorBlackList : [ '.usepixel' ] ,

minPixelValue : 1 ,

mediaQuery : false

} ,

// ...

}

}

其中几个配置项的含义如下:

  • viewportWidth:视口宽度,这里设置为跟设计稿宽度一致;

  • viewportHeight:视口高度,随便设置一个就可以;

  • unitPrecision:转换后值的精度,3表示保留3位小数;

  • viewportUnit:转换成什么视口单位,这里当然是 vw

  • selectorBlackList:是一个选择符数组,对应声明中的像素单位不会转换;

  • minPixelValue:最小像素值,大于等于这个值才会转换;

  • mediaQuery:是否转换媒体查询中的像素。

最后,我们以一个实例展示结束本篇文章。仍然是本文开头的设计稿,还是那个圆角矩形组件,在我们这个应用里的类名是 .card 。下面是它的CSS源代码:

section.card {

margin : 0 auto ;

margin-bottom : 20 px ;

background-color : #fff ;

border-radius : 10 px ;

box-shadow : 0 6 px  6 px  0 rgba ( 0 , 0 , 0 , 0.02 ) ;

text-align : center ;

padding : 38 px  70 px  46 px ;

font-weight : 300 ;

}

没错,所有这些 px 值都从设计稿中实测得到的(事实上是标注页面自动给出的)。而经过postcss-px-to-viewport插件转换之后,可以看到这些值都被转换成了相对于视口宽度的 vw 单位:

H5 必知必会之像素级还原设计稿

结束语

作为“H5必知必会”系列的第二篇,本文主要从两个方面讨论了如何高保真还原设计稿,同时适配形态各异的手机屏幕。首先,我们从理论或概念上先搞清楚了适配和还原的内容和目。H5适配主要分适配不同像素密度和适配不同屏幕大小。而适配的目的是为保证用户体验,比如图片不失真;以及在不同大小的屏幕上呈现比例相同的页面布局,这也就是所谓的百分之百还原设计稿,或像素级还原设计稿。

明确了适配和还原的含义及原理,接下来技术实现层面的关键是找到一个全局性的CSS单位。我们先介绍了阿里手机淘宝团队基于 rem 的适配框架(这个框架除了动态修改 rem ,还解决了真1像素边框的问题),然后介绍了基于更普适的 vw 单位实现适配。最后简单介绍了自动实现 pxvw 单位转换的插件postcss-px-to-viewport的配置。

看到这里,读者可能会不由自主地猜测这个系列第三篇的主题是什么?是讨论H5如何使用手机或宿主App赋予它的特殊能力吗?我也不知道。因为也有可能会跟大家分享多版本下的H5部署与运维策略。当然,还有可能会写一写基于某个脚手架快速从头搭建一个H5项目以及实现前端工程化。总之,未来有多种可能。其实我也想知道大家都想看哪个主题?如果你有想法,那欢迎留言吧。

关于奇舞周刊

《奇舞周刊》是360公司专业前端团队「 奇舞团 」运营的前端技术社区。关注公众号后,直接发送链接到后台即可给我们投稿。

H5 必知必会之像素级还原设计稿


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithms + Data Structures = Programs

Algorithms + Data Structures = Programs

Niklaus Wirth / Prentice Hall / 1975-11-11 / GBP 84.95

It might seem completely dated with all its examples written in the now outmoded Pascal programming language (well, unless you are one of those Delphi zealot trying to resist to the Java/.NET dominanc......一起来看看 《Algorithms + Data Structures = Programs》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器