第三章-浏览器的视图与坐标

陈大鱼头 ... 2021-8-3 Css
  • 前端
  • Css
  • Hello CSS
About 15 min

在上一篇【Hello CSS】的第二章第二章-CSS的逻辑属性与盒子模型 (opens new window)中提了个问题:

为什么Flex box跟Grid box的是以start、end为排列规则,而不是常规的top 、right 、bottom 跟left?

现在各位看官有答案了吗?

因为上一篇中有提到过CSS 逻辑属性的变革,从物理概念跳跃到了逻辑概念,也就是从toprightbottomleft更新为blockinlinestartend。由于Flex boxGrid boxCSS3的布局模式,所以自然而然会使用更加适应于新时代的语言属性。

上一篇主要介绍了CSS逻辑属性盒子模型的基本现状。本篇则会介绍浏览器的视图与坐标。

# 关于设备屏幕,我们应该知道的知识

# 像素(Pixel)

像素(pixel) (opens new window)是影像显示的基本单位,一个像素通常被视为影像的最小的完整取样。用来表示一幅影像的像素越多,结果更接近原始的影像。

我们看看下图,图中最小的点就是设备的像素

230px-Liquid_Crystal_Display_Macro_Example_zoom.jpg

# 分辨率(Image resolution)

分辨率(Image resolution) (opens new window)日常用语中之分辨率多用于影像的清晰度。分辨率越高代表影像质量越好,越能表现出更多的细节。

显示分辨率列表:https://zh.wikipedia.org/wiki/显示分辨率列表 (opens new window)

下图是不同分辨率下的图像显示

800px-HD_SD_resolutions_interlaced

# 每英寸像素(PPI)

每英寸像素(英语:Pixels Per Inch,缩写:PPI (opens new window),又被称为像素密度,是一个表示打印图像或显示器单位面积上像素 (opens new window)数量的指数。一般用于计量电子设备屏幕的精细程度。通常情况下,每英寸像素值越高,屏幕能显示的图像也越精细。如上面分辨率的图显示。

# 视网膜显示屏(Retina Display)

视网膜显示屏(Retina Display) (opens new window)是一种由苹果公司设计和委托制造的显示屏。有研究表明,人类肉眼能够分辨的最高PPI300PPI,所以超过PPI超过300的往往被称为Retina显示屏,这个概念是不对的,Retina显示屏指的是在人体正常使用距离下,无法用肉眼看到屏幕像素的显示屏。

下图为显示了“地图”二字的Retina显示屏

Map_on_Retina_Display.jpg

# 每英寸点数(DPI)

DPI(英语:Dots Per Inch,每英寸点数) (opens new window)是一个量度单位,用于点阵数位影像,意思是指每一英寸 (opens new window)长度中,取样或可显示或输出点的数目。如:打印机输出可达600DPI的分辨率,表示打印机可以在每一平方英寸的面积中可以输出600X600=360000个输出点。

下图为喷墨打印机以较低质量在约 0.25 平方英寸的范围内按 150 dpi 打印的效果的特写

PrinterDots.jpg

# 设备独立像素(DIP, DP)

设备独立像素(Device Independent Pixels,DIP,又称设备无关像素) (opens new window)是一种物理测量单位,基于计算机控制的坐标系统和抽象像素(虚拟像素),是定义UI布局时使用的虚拟像素单位。

# 设备像素比(DPR)

设备像素比(DPR) (opens new window)是设备上物理像素DIP的比例。公式如下:

window.devicePixelRatio = 物理像素 / dips
1

# CSS像素(CSS Pixels)

CSS像素(CSS Pixels)WEB编程中诞生的概念,用于定于浏览器中每个模型不同CSS的值大小。由于CSS像素(CSS Pixels)是个逻辑性的像素,而非物理性的像素,所以1个CSS像素在不同设备上大小可能会有不同。但即便是如此,对于CSS来说,还是希望在不同设备上大小尽可能地看起来相同。

# 那么这该如何实现呢?

基于这个问题,W3C (opens new window)提出参考像素 (opens new window)这个概念。定义如下:

参考像素是设备上一个像素的视角,像素密度为96dpi,离设备长一臂。标准的手臂长度为28英尺,所以视角大概为0.0213度。对于臂长的读数,1px应该为0.26mm(1/96 英尺)。

如下图:

pixel1.png

# 所以1px CSS像素大小该是多少?

基于这个问题,W3C (opens new window)给出的答案如下:

对于CSS设备而言,这些尺寸要么锚定(i)通过将物理单元与其物理测量关联起来,或者锚定(ii)通过将像素单元与参考像素关联起来。对于打印介质和类似的高分辨率设备,锚单元应该是标准物理单位之一(像英尺,厘米等)。对于低分辨率的设备和具有不寻常观看距离的设备,建议将锚单元作为像素大圆。对于此类设备,建议像素单元参考最接近参考像素的设备像素的整数。

以上就是1px CSS像素的定义。也合理的解释了为什么显示设备的物理尺寸与物理像素不同,但是同样CSS值的元素大小却相差无几了。这是因为不同设备的px实现的参考锚点不同。

如果想知道不同设备屏幕的具体差异,可以参考这个网站:https://uiiiuiii.com/screen/index.htm (opens new window)

# 屏幕尺寸怎么算?

首先我们可以知道1英寸=2.54CM,基本所有的屏幕都以对角线来衡量尺寸。

手机屏幕常见尺寸有:5、6、5.5、6.5、7

笔记本一般是:10、12、13、14、15、18、19

想知道自己屏幕的尺寸可以使用勾股定理:

ggdl.jpg

如果想知道你的显示器尺寸,可以参考这个网站:https://zh.infobyip.com/detectdisplaysize.php (opens new window)

鱼头注:关于CSS的单位值,会在后面的章节讲解,有兴趣的千万不要错过。

# 视图

# 视口(viewport)

视口(viewport) (opens new window)代表当前可见的计算机图形区域。在 Web 浏览器术语中,通常与浏览器窗口相同,但不包括浏览器的 UI, 菜单栏等——即指你正在浏览的文档的那一部分。

在WEB开发中,视口(viewport) 是个很重要的概念,尤其在响应式网页设计 (opens new window)中是必备的。

  • 通过上述一系列的名词介绍,我们可以知道不同设备的尺寸,分辨率,CSS像素大小都不尽相同,所以 视口(viewport) 的大小也就跟设备相关。

  • 在尺寸较大的设备中,在这些设备上,应用显示区域不一定是全屏的,viewport 是浏览器窗口的大小。

  • 在大多数移动设备中,浏览器是全屏的,viewport 是整个屏幕的大小。
  • 在全屏模式下,viewport 是设备屏幕的范围,窗口是浏览器窗口,浏览器窗口大小小于或等于视口的大小,并且文档是这个网站,文档的大小可比 viewport 长或宽。

# 如何设置文档viewport?

文档viewport可以通过三种方式进行设置:

# HTML标签

第一种方式就是在HTML<head></head>中引入

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

下面表格来自MDN (opens new window)

Value 可能值 描述
width 一个正整数或者字符串 device-width 以pixels(像素)为单位, 定义viewport(视口)的宽度。
height 一个正整数或者字符串 device-height 以pixels(像素)为单位, 定义viewport(视口)的高度。
initial-scale 一个0.010.0之间的正数 定义设备宽度(纵向模式下的设备宽度或横向模式下的设备高度)与视口大小之间的缩放比率。
maximum-scale 一个0.010.0之间的正数 定义缩放的最大值;它必须大于或等于minimum-scale的值,不然会导致不确定的行为发生。
minimum-scale 一个0.010.0之间的正数 定义缩放的最小值;它必须小于或等于maximum-scale的值,不然会导致不确定的行为发生。
user-scalable 一个布尔值(yes或者no 如果设置为no,用户将不能放大或缩小网页。默认值为yes

鱼头注:具体的作用跟属性会在后面的章节讲解,有兴趣的千万不要错过。

# CSS伪类选择器@viewport

@viewport (opens new window)规则让我们可以对文档的大小进行设置 viewport。这个特性主要被用于移动设备,但是也可以用在支持类似“固定到边缘”等特性的桌面浏览器,如微软的Edge。

按百分比计算尺寸的时候,就是参照的初始视口(viewport)。初始视口指的是任何用户代理和样式对它进行修改之前的视口。桌面浏览器如果不是全屏模式的话,一般是基于窗口大小。

在移动设备上(或者桌面浏览器的全屏模式),初始视口通常就是应用程序可以使用的屏幕部分。它可能是全屏或者减去由操作系统或者其它应用程序所占用的部分(例如状态栏)。

语法如下:

@viewport {
    <group-rule-body>
}
1
2
3

描述符:

属性值 描述
min-width (opens new window) 设置viewport的最小宽度
max-width (opens new window) 设置viewport的最大宽度
width (opens new window) 同时设置 min-widthmax-width
min-height (opens new window) 设置viewport的最小高度
max-height (opens new window) 设置viewport的最大高度
height (opens new window) 同时设置 min-heightmax-height
zoom (opens new window) 设置初始缩放系数
min-zoom (opens new window) 设置最小缩放系数
max-zoom (opens new window) 设置最大缩放系数
user-zoom (opens new window) 设置用户是能更改缩放系数
orientation (opens new window) 控制文档的方向
viewport-fit (opens new window) 控制非矩形显示屏上文档的显示。

can_i_use (opens new window)显示,兼容性几乎全线飙红。

@viewport_support.png

对于我们在移动设备上常用的viewport设置

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes">
1

就可以这么来写

@viewport {
    width: device-width;
    zoom: 1.0;
    min-zoom: 0.5;
    max-zoom: 2.0;
    user-zoom: zoom;
}
1
2
3
4
5
6
7

# VisualViewport

首先我们看Window.visualViewport (opens new window)

这是一个只读的实验性的web api,目前只有**chrome 60 +Opera 47+**支持。

属性如下:

{
    height: 936, // 视觉视口高度,返回值为CSS像素值。
    offsetLeft: 0, // 视觉视口边缘与布局视口左边的偏移量
    offsetTop: 0, // 视觉视口边缘与布局视口顶边的偏移量
    onresize: null, // 视觉视口大小变化时触发
    onscroll: null, // 滚动视觉视口时触发。
    pageLeft: 0, // 视觉视口边缘的初始化包含原点的X坐标,返回值为CSS像素值。
    pageTop: 6680, // 视觉视口边缘的初始化包含原点的Y坐标,返回值为CSS像素值。
    scale: 1, // 返回值为视觉视口的缩放比例
    width: 1364, // 视觉视口宽度,返回值为CSS像素值。
}
1
2
3
4
5
6
7
8
9
10
11

# 坐标系统

通过上述对设备屏幕视口的介绍,我们应该可以对电子设备中的浏览器显示情况有了基本的了解。那么接下来我们来了解一下浏览器中的坐标系系统。

# 迪卡尔坐标系

早在初中开始,我们就开始接触一个非常重要的概念 —— 笛卡尔坐标系 (opens new window)。在数学里,笛卡尔坐标系(英语:Cartesian coordinate system),也称直角坐标系,是一种正交坐标系 (opens new window)

下图是数学概念中的平面坐标系:

1024px-Cartesian-coordinate-system.png

下图是数学概念中的三维直角坐标系:

1024px-Cartesian_coordinates_3D.png

图上信息就不作过多的解释了,有需要详细了解的可以参考https://zh.wikipedia.org/笛卡尔坐标系 (opens new window)

# WEB中的坐标系统

上面介绍的是我们数学概念中的坐标系,在WEB页面中,也有相应的坐标系统。计算法则也相仿,只是它和我们数学中的概念有点不一样,就是原点位于浏览器的左上角。整个浏览器屏幕就是第一象限,表现上只有正值,负值都隐藏了起来。无论是平面坐标还是三维坐标都是如此,只不过由于浏览器屏幕是个平面,所以三维坐标中的Z轴是贯穿浏览器的。

平面坐标系的坐标值可以看以下图示与DEMO:

xy_start.png

xy_end.png

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta name="screen-orientation" content="portrait">
    <meta name="x5-orientation" content="portrait">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <title>平面坐标系</title>
    <style>
      html,
      body,
      div {
        margin: 0;
        padding: 0;
      }
      html,
      body {
        width: 100%;
        height: 100%;
      }
      .poinerPosition {
        font-size: 2vw;
        position: absolute;
        left: 0;
        top: 0;
      }
    </style>
  </head>
  <body>
    <div id="poinerPosition" class="poinerPosition"></div>
    <script>
      'use strict';
      window.addEventListener('pointermove', PointerEvent => {
        const {
          x,
          y,
        } = PointerEvent;
        poinerPosition.innerHTML = `
          (${x}, ${y})
        `;
        poinerPosition.style.left = `${x + 20}px`;
        poinerPosition.style.top = `${y}px`;
      });
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

DEMO地址:https://blog.krissarea.com/css/css-ccs.html (opens new window)

鱼头注:关于CSS 二维与三维的图像跟动画会在后续的章节进行讲解,有兴趣的可以继续关注本系列。

# 参考资料

你真的了解css像素嘛? (opens new window)

什么是CSS像素?什么是参考像素? (opens new window)

devicepixelrati (opens new window)

设备像素比devicePixelRatio简单介绍 (opens new window)

W3C (opens new window)

分辨率 (opens new window)

像素 (opens new window)

视网膜显示屏 (opens new window)

每英寸像素 (opens new window)

每英寸点数 (opens new window)

在移动浏览器中使用viewport元标签控制布局 (opens new window)

Visual Viewport API (opens new window)

视口概念 (opens new window)

VisualViewport (opens new window)

meta (opens new window)

Window.visualViewport (opens new window)

@viewport (opens new window)

[CSS] 淺談 @viewport 與 @media (opens new window)

# 【Hello CSS】系列

【Hello CSS】是以CSS基础概念为主题的系列文章,旨在帮助大家更深刻地了解并且提高CSS在各位开发者心目中的地位。由于鱼头我水平有限,文笔有限,如果各位在文章中发现有任何不合理,不正确的地方,还烦不吝指出,我会非常感谢的;如果通过文章有任何想法或疑问,也希望各位能积极留言,我们互相探讨;如果通过本系列文章有所收获,这就让鱼头我喜不自胜了!

如果你喜欢探讨技术,或者对本文有任何的意见或建议,非常欢迎加鱼头微信好友一起探讨,当然,鱼头也非常希望能跟你一起聊生活,聊爱好,谈天说地。 鱼头的微信号是:krisChans95 也可以扫码关注公众号,订阅更多精彩内容。 https://bucket.krissarea.com/blog/base/qrcode-all1.png

Last update: June 25, 2023 00:16
Contributors: 陈大鱼头 , fish_head