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

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

内容简介:编者按:本文作者李松峰,资深技术图书译者,翻译出版过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 必知必会之像素级还原设计稿


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

查看所有标签

猜你喜欢:

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

Haskell Programming from first principles

Haskell Programming from first principles

Christopher Allen、Julie Moronuki / 2015 / USD 59.00

I am writing this book because I had a hard time learning Haskell. It doesn't have to be that way. I've spent the last couple years actively teaching Haskell online and in person. Along the way, I ......一起来看看 《Haskell Programming from first principles》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具