引言

按照pc尺寸做好的网页,在手机端打开,看起来像是pc的缩小版,东西都在只是字太小都看不清了,有什么办法放大呢?

于是去google一下,发现,贴了这么一行代码就轻松解决了:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0"/>

为什么这行代码能让字看起来和电脑差不多呢?为了搞懂这行代码的意思,又去google,但是立马被一大堆的概念给弄糊涂了。px,pt,dpi,ppi,dip,dpr…… (其实不一定都要懂,懂你需要的就不会糊涂。)

如果你不是前端,也许对上面的代码不感兴趣,那么你很可能对下面的几个奇怪的现象感兴趣:

  • Q1: 为什么同样大小的字体(比如14px)或者同一个app的icon在不同的移动设备下人眼看起来的大小不一样?
  • Q2: 电影是不是分辨率越高,在电脑上看就越清晰?
  • Q3:为什么我用手机拍的同样的照片,在retina屏幕下的电脑更清晰?
  • Q4: 为什么视觉设计师为移动端设计的稿子是750px大小的?
  • Q5: 为什么在macbook pro(retina)里面的photoshop中打开同样尺寸的图片,retina中缩小了几乎一倍?

不要晕,听我慢慢说。

基本概念

照例,先从我自己的角度介绍一些基本概念。

一切都要从像素讲起。“像素”(pixel)只存在于数码设备显示领域,。图片、视屏、html中的dom元素的尺寸、iphone的设备分辨率都是可以用像素来度量的。

来一张官方iphoneSE的显示屏介绍图

像素的种类

像素分为物理像素和设备独立像素:

  • 设备像素/物理像素(physical pixel)

    和设备独立像素相反,它是“依赖设备的”的像素,表示设备能控制显示的最小单位。

    更详细点,如下图所示,一个电子屏是有很多个固定大小的“点”组成的,可以把“点”看成是能发出彩色光的“灯泡”,每个“灯泡”只能发出一种颜色的光。当每个“灯泡”都发白光时,就是一块纯白色的屏幕;同样的,“灯泡”按照一定的规则展示不同的颜色,就可以让电子屏展示一幅图啦。(为了区分,余下的文字中的物理像素都用“灯泡”来表示)



    那么人眼能不能看到这些像素点呢?在一些电子设备上,人眼是可以感受到颗粒感的:



    但是在像素点小到人眼在正常情况下无法看到的情况下,屏幕是光滑的。retina屏幕就是这样, 图2-iphone6手机配置图说的就是每行有1136个(灯泡)。

  • 设备独立像素(DIP - device-independent pixel)

    顾名思义,它是独立于设备的用于逻辑上衡量像素的单位。举两个例子:

    • css像素

      这个前端最熟悉,平常在开发网页时设置字体大小、图片显示大小等等。用来控制元素展示的长宽,根据代码自由定义

    • 描述位图尺寸的像素

      平时我们在电脑上可以看到的图片信息是这样的:



      一张位图图片是由很多个大小相等的纯色的色块构成,在你用“放大镜”放大到够大的时候能很清楚的看得到。在photoshop中创建画布,会首先让你设置画布长多少像素,宽多少像素。这里的像素值等于色块的个数。

      下图是某张图片在放大后看到的色块。如果一张图片尺寸是2*2,那么它就是由4个色块组成。这个图片像素指的是图片设计尺寸,不一定是真正显示的尺寸,但是显示尺寸等于设计尺寸时图片是是最清晰的。它指导着屏幕里面的“灯泡”应该展示哪种颜色。

像素的相关词

  • ppi (Pixels Per Inch)

    也叫像素密度,所表示的是每英寸所拥有的像素数量。密度越高,拟真越强。移动设备通常会给出对角线的长度(单位英寸),和长*宽的分辨率,所以根据公式可以算出ppi:

    同理,如果只给出了设备长(单位英寸)和长度分辨率(单位像素),也同样可以算出来。

  • dpi (Dots Per Inch)

    这是和ppi容易混淆到一起的概念。指打印设备每英寸印刷出来的点有多少个,同一张图片打印出来和在电脑上看到的清晰度就不一定相同。因为不影响我们理解,有一些博客又喜欢混用,作为只跟电子屏打交道的前端开发,认为各大博客上的dpi=ppi就好。

  • dpr (device-pixel-ratio: Number of device pixels per CSS Pixel)

dpr可以用window.devicePixelRatio得到,是设备上物理像素和设备独立像素(device-independent pixels (dips))的比例。

公式表示就是:window.devicePixelRatio = 物理像素 / dips

大家通常指的dpr是个固定值: dpr的值表示在理想布局宽度(ideal viewport)里,使用多少个物理像素来渲染一个设备独立像素

在ios中,dpr通常是1,2,3;但是在android中,ideal viewport会根据浏览器自己的喜好变化,甚至会是小数。现在andorid注重高分辨率,很多都达到3了。

Viewport

终于讲到上面的meta标签,name是viewport。 那么什么是viewport?

viewport是视口、视窗的意思,Peter-Paul Koch 大神将其分为layout viewport,visual viewport,ideal viewport三种,三种的单位都是相对像素。在这个meta标签中指的是layout viewport。

  • ideal viewport 理想视图

    • 它不是一个真实存在的视图,而是开发者期望的视图。在这个视图中,文字和图片不管在何种分辨率下(无论是pc还是移动端)在肉眼看起来都可以保持差不多大小。在响应式设计的年代,确实只要保证这一点就够了。
    • 不同设备"理想视图"的宽度有不同的大小,安卓的设备种类比较多,只列出一种参考下。

    • 一些设备上,ideal viewport宽度可以用screen.width获取;另一些设备上需要screen.width除以window.devicePixelRatio

剩下的两种视图,我看了很多博客都觉得晕晕的。最后发现用<html></html> 来切入很适合用来理解。

在网页设计里,如果用百分比定义块状元素的尺寸,那么元素的尺寸等于其父元素乘以该百分比。一张网页中所有标签的父元素是<html></html>,那如果html的宽度也用百分比定义,html的父元素又是什么呢?没错,就是“渲染视图”(layout viewport)。

  • visual viewport 视觉视图

    • 从好懂的视图讲起,“视觉视图”的宽度就是指你看到的浏览器或者app的webview中可视区域的宽度。他的值很有用,可以用来推算1个css像素在当前页面等价于多少里面。很简单,把页面分成宽度值那么多份就好。
    • 举例:比如视觉视图的宽度为6px;那么2px的字就是这么大。



      所以说,为了让手机上的字和电脑上大小差不多,我们希望visual viewport的宽度等于ideal viewport。
    • visual viewport宽度可以用window.innerWidth获取
  • layout viewport 渲染视图

    • <html></html>的父元素,网页内容在其基础上进行渲染,所以叫“渲染视图”。
    • 和visual viewport的关系:
      • 在pc上,dom树中超出的layout viewport的部分(网页中有元素任性的比渲染视图还宽)不会算入visual viewport。

        • 网页缩放倍率为1或者缩小时,layout viewport宽度=visual viewport宽度;。
        • 网页放大时,layout viewport宽度>visual viewport宽度(和手机一样,可参考下图)。

      • 在移动端比较复杂,不同浏览器/设备有不同的表现。
        • 一部分浏览器/设备,dom树中超出的layout viewport的部分不会算入visual viewport。
        • 另一部分浏览器/设备,dom树中超出的layout viewport的部分会算入visual viewport,此时visual viewport宽度 > layout viewport(亲测摩托罗拉的chrome浏览器就是这样)。
        • 在网页设计中,我们不希望有滚动条,通常会保证没有元素超出<html></html>,或者把超出的部分hidden掉,所以暂时可以不用考虑超不超出的问题。
      • 综上,为了让在宽度有限的设备上看到layout viewport的所有内容,我们让layout viewport的宽度等于visual viewport,设置页面缩放比例为1即可.
      • layout viewport宽度可以用document.documentElement.clientWidth获取。

文章开头说的字在手机上变小的情况,是因为手机面世初期,很多网页都是针对pc端设计的.宽度至少在900px以上吧。这样放在手机上因为容器变窄,文字和图片会互相挤压。为了解决这个问题,很多手机浏览器会在默认情况下,设置visual viewport为一个较大的值,比如iphone6和摩托罗拉t40上是980px。这样,pc上的页面基本就可以不变形的展示在手机上,只是字很小。

如今很多网页都是响应式开发,其实已经不需要这个默认值了。

文中开头的代码是常见的移动端开发会加入的代码,但是在pc端是不生效的。最后解释一下meta标签中的每一个属性:

  • width: 设置layout viewport的宽度。可设置为为一个正整数(单位px),或字符串"width-device"(等于设备宽度/理想宽度)
  • initial-scale: 设置页面的初始缩放值,为一个数字,可以带小数。当initial-scale为1时,不管是否设置width,layout viewport宽度=visual viewport宽度=ideal viewport宽度。iphone6上就是375px。
  • minimum-scale: 允许用户的最小缩放值,为一个数字,可以带小数
  • maximum-scale: 允许用户的最大缩放值,为一个数字,可以带小数
  • user-scalable: 是否允许用户进行缩放,值为"no"或"yes", no 代表不允许,yes代表允许

解答问题

  • Q1: 为什么同样大小的字体(比如14px)或者同一个app的icon在不同的移动设备下人眼看起来的大小不一样?

    答:其实这个问题等价于一个css像素在两个设备中分别等价于多少英寸。如果网页是在ideal viewport下,可以推理出一个公式:每个物理像素等于1/PPI()英寸),在ideal viewport下,DPR表示1个css像素由几个物理像素组成。因此,得到公式:

    (1/PPI)* DPR = DPR/PPI

    举个例子:iphone6-PPI为326,DPR为2,DPR/PPI约等于0.0061;iphone6S-PPI为401,DPR为3,DPR/PPI约等于0.0075;所以iphone6s上的app和字比iphone6大哦。

    通常,设备显示屏越大,一个css像素代表的物理尺寸需要大一点。因为人眼会离大屏幕的比较远,离小屏幕的比较近。虽然物理尺寸不一样,但是人眼感觉起来是差不多大的。

  • Q2: 电影是不是分辨率越高,在电脑上看就越清晰?

    答:不是。每个设备拥有的“灯泡”(设备像素)是固定的。如果电影的分辨率大于设备拥有的“灯泡”,就代表着要用1个“灯泡”来显示多个图像像素。但是一个“灯泡”只能发出一种光,最好是让一个“灯泡”显示一个图像像素。所以以后下电影下适合的分辨率就好啦,否则也是浪费掉了。

  • Q3:为什么我用手机拍的同样的照片,在retina屏幕下的电脑更清晰?

    答:PPI越高,画面越精细。当图片的显示大小小于它实际的分辨率(数码设备发展很快,随随便便一张图就可以很大的分辨率,所以一般都是小于的),4 * 4的照片一般设备只能用2 * 2的“灯泡”来渲染,而retina的设备可以用4*4的来渲染,所以就更清晰啦。同理也可以应用与上面电影的问题,retina可以播放更大分辨率的电影。

  • Q4: 为什么视觉设计师为移动端设计的稿子是750px大小的?

    答:现在移动端的页面会基于宽度为750px的画布进行设计,是根据iphone6的设备分辨率来设计的。虽然iphone6上网页设计出来只有375px大小,但是为了充分利用每一个“灯泡”,画面更精细,需要用750px的画布来设计。

  • Q5: 为什么在macbook pro(retina)里面的photoshop中打开同样尺寸的图片,retina中缩小了几乎一倍?

    答:补充一下,这里的场景是图片都不放大的情况下。

    在不放大的情况下,默认photoshop中一个“灯泡”渲染一个图片像素。因为retina屏幕的像素密度更大,在dpr为2的retina屏幕下面,图片就缩小了一倍。看到论坛上的一些解决方案是放大一倍来设计。

响应式之像素和viewport的更多相关文章

  1. 带你玩转JavaWeb开发之五-如何完成响应式开发页面

    响应式页面开发 使用BootStrap开发一个响应式的页面出来 响应式开发就是同一个页面在PC端与手机端Pad端显示不同的效果,以给用户更好的体验 需求分析 开发一套页面,让用户能够在PC端, Pad ...

  2. web响应式之bootstrap的基础用法。

    1/首先必须在head里面引用视窗viewport,以保证之后可以响应式分布 <!--meta:vp 响应式布局--> <meta name="viewport" ...

  3. BootStrap学习之先导篇——响应式网页

    Bootstrap学习之前,要知道响应式网页的原理. 1.什么是响应式网页? 一个页面,可以根据浏览设备的不同,以及特性的不同,而自动改变布局.大小等.使得在不同的设备上上都可以呈现优秀的界面. 优点 ...

  4. CSS3 @media 查询(制作响应式布局)

    这里简单说明一下@media 查询. 详细说明文档:http://www.runoob.com/cssref/css3-pr-mediaquery.html 使用 @media 查询,你可以针对不同的 ...

  5. 关于响应式、媒体查询和media的关系 、流媒体布局flex 和em rem像素的使用 我有一些废话要讲.....

    一.什么是响应式 随着移动端越来遇火 网站的布局成为一个热议的话题 有的人喜欢用手机浏览网站.有的人喜欢用paid浏览网站.有人喜欢用电脑浏览网站 那么问题来了 我们怎么样才能使用一套css样式 完成 ...

  6. 响应式设计:理解设备像素,CSS像素和屏幕分辨率

    概述 屏幕分辨率.设备像素和CSS像素这些术语,在非常多语境下,是可互换的,但也因此easy在有差异的地方引起混淆,实际上它们是不同的概念. 屏幕分辨率和设备像素是物理概念,而CSS像素是WEB编程的 ...

  7. 如何做好移动端的响应式设计:Viewport控制

    新人翻译,欢迎转载~ 英文原文地址:http://bitsofco.de/2015/respove-design-viewport/ 原文例程地址:https://github.com/ireade/ ...

  8. 响应式注意要添加“视口”约束标记---viewport

    视口:我们试图在iPhone中输出屏幕宽度,你会发现屏幕宽度是980,却和PC屏幕差不多大.原因是苹果主导的这些手机厂商,为了使用户获得完整web体验,很多设备都会欺骗浏览器返回一个数值较大的“视口” ...

  9. [学习笔记]viewport定义,弹性布局,响应式布局

    一,移动端宽度设置viewport视图窗口,<meta name="viewport" content="width=device-width,initial-sc ...

随机推荐

  1. win平台搭建Lnmp环境

    win10上面安装的phpStudy这些天有时候打不开网页 502,请求一直loading,就算是代码问题我也扶不住,安装个Redis,mongodb都超级麻烦,并且好多都模拟Linux做的东西,最终 ...

  2. java根据系统生成临时文件

    createTempFile 会根据当前系统,自动找系统的临时文件目录,在此目录下生成临时文件

  3. RabbitMQ的基础介绍

    转自:http://blog.csdn.net/whycold/article/details/41119807 一.引言 你是否遇到过两个(多个)系统间需要通过定时任务来同步某些数据?你是否在为异构 ...

  4. time_t与GMT格式互转

    time_t Time::timeFromGMT(string gmt) { char week[4]; memset(week,0,4); char month[4]; memset(month,0 ...

  5. Final类和Final方法

    终止继承 Final类 当关键字final用来修饰类时,其含义是该类不能在派生子类.换句话说,任何其他类都不能继承用final修饰的类,即使该类的访问限制为public类型,也不能被继承:否则,将编译 ...

  6. C11构造函数的改善

    1.委托构造函数 委托构造函数就是允许在同一个类中一个构造函数可以调用另一个构造函数,从而在初始化时简化变量的初始化. class CTest { public: int x; int y; int ...

  7. c# 重载运算符(ovveride operator)踩坑记,关于null比对

    场景描述: 需要比对两个版本的对应对象是否完全一致(每个属性值一致),不一致的导出报表颜色标识,以便提醒后续使用报表人员. 实现思路: 对象重载ToString方法,另实现一比对基类(为了通用)重载= ...

  8. powerdesigner怎么设置同时显示name和code

    实现方法:Tools-Display Preference 从数据库里抽取了数据模型,为了理清思路,需要将name改为中文名称,但是pd自动将name填充为code,可以通过如下配置修改: 选择too ...

  9. 【BZOJ】4872: [Shoi2017]分手是祝愿 期望DP

    [题意]给定n盏灯的01状态,操作第 i 盏灯会将所有编号为 i 的约数的灯取反.每次随机操作一盏灯直至当前状态能够在k步内全灭为止(然后直接灭),求期望步数.n,k<=10^5. [算法]期望 ...

  10. 爬虫--PySpider框架

    PySpider框架 PySpider框架的作用