没有所谓的 CSS 绝对单位:为什么 CSS 英寸并不总是与物理英寸相匹配?

注:机翻,未校。


There Is No Such Thing As A CSS Absolute Unit 没有 CSS 绝对单位这样的东西

Elad Shechter

Jul 29, 2021

What are absolute units? What are the differences between relative and absolute units, and how do we create accurate sizes on the web? In this article, Elad Shechter explains why CSS absolute units aren’t so absolute.
什么是绝对单位?相对单位和绝对单位之间的区别是什么?我们如何在网络上创建准确的尺寸?在这篇文章中,Elad Shechter 解释了为什么 CSS 的绝对单位不是那么绝对。

When we start learning CSS, we find that CSS units of measurement are categorized as relative or absolute. Absolute units are rooted in physical units, such as pixels, centimeters, and inches. But over the years, all absolute units in CSS have lost their connection to the physical world and have become different kinds of relative units, at least from the perspective of the web.
当我们开始学习 CSS 时,我们发现 CSS 的度量单位被分类为相对或绝对。绝对单位植根于物理单位,例如像素、厘米和英寸。但多年来,CSS中的所有绝对单位都失去了与物理世界的联系,变成了不同类型的相对单位,至少从Web的角度来看是这样。

It’s important to note that there are still significant differences between relative and absolute units. CSS relative units are sized according to other style definitions defined by parent elements or are affected by the size of a parent container. As for absolute units, we will dive in and see how they are affected by other things, such as the screen and the device’s operating system.
需要注意的是,相对单位和绝对单位之间仍然存在显着差异。CSS 相对单元的大小根据父元素定义的其他样式定义确定,或者受父容器大小的影响。至于绝对单位,我们将深入研究,看看它们如何受到其他因素的影响,例如屏幕和设备的操作系统。

Relative units include units such as %, em, rem, viewport units (vw and vh), and more. The most common absolute unit is the pixel (px). Besides that, we have the centimeter unit (cm) and the inches unit (in).
相对单位包括 %emrem、视口单位(vwvh)等单位。最常见的绝对单位是像素 (px)。除此之外,我们还有厘米单位 (cm) 和英寸单位 (in)。

Now, let’s explore why CSS absolute units aren’t so absolute.
现在,让我们探讨一下为什么CSS绝对单位不是那么绝对。

CSS Pixels CSS 像素

Pixels have been the most common unit of CSS, dating to the beginning of the web. In the old world of desktop screens, before we had any smartphones, the screen’s pixels were always equivalent to CSS pixels.
像素一直是 CSS 最常见的单位,可以追溯到 Web 的开始。在桌面屏幕的旧世界中,在我们没有任何智能手机之前,屏幕的像素总是等同于 CSS 像素。

In 2007, for example, the most common desktop resolution was 1024×768 pixels. Back then, we would normally give our web pages a fixed width of 1000 pixels to fit the entire page, and the leftover pixels would be saved for the browser’s scrollbar.
例如,在 2007 年,最常见的桌面分辨率是 1024×768 像素。那时,我们通常会为我们的网页设定一个固定的 1000 像素宽度以适应整个页面,剩下的像素将保存为浏览器的滚动条。

Old desktop screen

Monitors used to look quite different back in the day! (Image credit: Shutterstock) (Large preview)

Smartphone Screens 智能手机屏幕

Smartphones brought another quiet evolution, starting the era of high-density screens. If we consider an iPhone 12 Pro, whose screen is 1170 pixels wide, we would count every 3 pixels on the device as 1 pixel in the CSS.
智能手机带来了另一次悄然的演变,开启了高密度屏幕的时代。如果我们考虑屏幕宽为 1170 像素的 iPhone 12 Pro,我们会将设备上的每一 3 像素计为 CSS 中的 1 像素。

The density of iPhone screens over the years

High-density screens caused the first separation between device pixels and CSS pixels. (Image credit: Wikipedia) (Large preview)

When we size in mobile, we measure according to CSS pixels, not according to device pixels. To sum up:
当我们在移动设备中调整尺寸时,我们根据 CSS 像素进行测量,而不是根据设备像素进行测量。总结一下:

  • CSS pixel are logical pixels.
    CSS 像素是逻辑像素。
  • Device pixels are real physical pixels.
    设备像素是真实的物理像素。

High density screens comparison

1 CSS pixel could be more than 1 device pixel. (Large preview)

Okay, but what about desktop devices? Do they still work with the same old pixel calculation? Let’s talk about that.
好的,但是桌面设备呢?它们是否仍然使用相同的旧像素计算?让我们来谈谈这个问题。

Desktop Screens In 2021 2021 年的桌面屏幕

High-density screens came to laptops several years later. The 2014 MacBooks got the first “retina” screens (retina being synonymous with high density).
几年后,高密度屏幕进入了笔记本电脑。2014 年的 MacBook 获得了第一个“视网膜”屏幕(视网膜是高密度的代名词)。

These days, most laptops have a high-density screen.
如今,大多数笔记本电脑都有高密度屏幕。

Let’s consider MacBooks:
让我们考虑一下MacBook:

  • The 13.3-inch MacBook Pro has a screen that is 2560 pixels wide but that behaves like 1440 pixels. This means that every 1.778 physical pixels act like 1 logical pixel.
    13.3 英寸 MacBook Pro 的屏幕宽为 2560 像素,但行为类似于 1440 像素。这意味着每 1.778 个物理像素都像 1 个逻辑像素。
  • The 16-inch MacBook Pro has a screen that is 3072 pixels wide but that behaves like 1792 pixels. This means that every 1.714 physical pixels act like 1 logical pixel.
    16 英寸 MacBook Pro 的屏幕宽为 3072 像素,但行为类似于 1792 像素。这意味着每 1.714 个物理像素都像 1 个逻辑像素。

Built-in retina display showing 16-inch with 3072 times 1920 pixels

(Large preview)

Among PC laptops, I tested two 15.6-inch screens, one with full HD resolution and the other with 4K resolution. The results were interesting:
在 PC 笔记本电脑中,我测试了两个 15.6 英寸的屏幕,一个是全高清分辨率,另一个是 4K 分辨率。结果很有趣:

  • The 15.6-inch full-HD screen is 1920 pixels wide but behaves like 1536 pixels. This means that every 1.25 physical pixels act like 1 logical pixel.
    15.6 英寸全高清屏幕宽 1920 像素,但行为类似于 1536 像素。这意味着每 1.25 个物理像素都像 1 个逻辑像素。
  • The 15.6-inch 4K screen is 3840 pixels wide but behaves, again, like 1536 pixels. This means that every 2.5 physical pixels act like 1 logical pixel.
    15.6 英寸 4K 屏幕的宽度为 3840 像素,但行为同样类似于 1536 像素。这意味着每 2.5 个物理像素都像 1 个逻辑像素。

Two 15.6-inch screens compared with full HD on the left and 4K on the right with both having a CSS resolution of 1536 times 864 pixels

These PC devices have different resolutions but act the same for CSS resolution. (Image credit: Elad Shechter) (Large preview)

As you can see, the connection between the real physical (i.e. device) pixels and the CSS (i.e. logical) pixels has almost vanished.
正如你所看到的,真实的物理(即设备)像素和CSS(即逻辑)像素之间的联系几乎消失了。

Screens Have Become Denser Over The Years 多年来,屏幕变得越来越密集

In the past, if you looked closely at a screen, you could actually see its pixels. When the technology of screens improved, manufacturers started to create higher-density screens.
过去,如果你仔细观察屏幕,你实际上可以看到它的像素。当屏幕技术改进时,制造商开始制造更高密度的屏幕。

A close-up of an image on a screen showing device pixels

In the past, if you got close enough to your screen, you could see the device pixels. (Large preview)

Recommended reading: What Does A Foldable Web Actually Mean?
推荐阅读:可折叠网页到底是什么意思?

Why Do We Calculate Logical Pixels Differently? 为什么我们计算逻辑像素的方式不同?

Over the years, as screens became denser, we couldn’t fit more content in the same screen size merely because the screen has more pixels.
多年来,随着屏幕变得越来越密集,我们无法仅仅因为屏幕具有更多的像素而在相同的屏幕尺寸中容纳更多的内容。

Think about it for a moment. Consider the Samsung Galaxy S21 Ultra. Its narrower dimension is 1440 physical pixels. We could easily fit it in a regular desktop screen. But if we did, the text would be small to the point of being unreadable. Because of this, we separate physical pixels from logical pixels.
想一想。以三星 Galaxy S21 Ultra 为例。其较窄的维度是 1440 个物理像素。我们可以轻松地将其安装在常规桌面屏幕上。但是,如果我们这样做,文本就会很小到无法阅读的地步。因此,我们将物理像素与逻辑像素分开。

Sizes in CSS (i.e. width and height), then, are calculated according to CSS logical pixels. Of course, we can use physical pixels to load high-density content, such as images and videos, like so:
然后,CSS中的大小(即宽度和高度)是根据CSS逻辑像素计算的。当然,我们可以使用物理像素来加载高密度内容,例如图像和视频,如下所示:

<img src="image-size-1200px.jpg" width="300" >

OK, CSS pixels aren’t equal to a device’s physical pixels. But we have centimeters and inches. Those are physical units connected to the physical world, right? Let’s check them out.
好的,CSS 像素不等同于设备的物理像素。但是我们有厘米和英寸。这些是与物理世界相连的物理单元,对吧?让我们来看看它们。

CSS Inches And CSS Centimeters CSS 英寸和 CSS 厘米

Wherever we use physical units like inches and centimeters, we know these are absolute units.
无论我们在哪里使用英寸和厘米等物理单位,我们知道这些都是绝对单位。

I had a thought that if CSS pixels aren’t equal to device pixels, then maybe it would be a good idea to use physical units such as inches and centimeters on the web. They are absolute units, right?
我有一个想法,如果 CSS 像素不等于设备像素,那么在网络上使用英寸和厘米等物理单位可能是个好主意。它们是绝对单位,对吧?

To be sure, I tested it. I created a box with a width and height of 1 centimeter and gave it a background color of red. I grabbed a real tape measure and got a surprise:
可以肯定的是,我测试了它。我创建了一个宽高为 1 厘米的盒子,并给它起了红色的背景色。我拿起一个真正的卷尺,得到了一个惊喜:

A CSS centimeter isn’t equal to a physical centimeter.
CSS 厘米不等同于物理厘米。

Here I am testing a CSS centimeter unit with a tape measure on a mid-2019 13-inch MacBook:
在这里,我正在 2019 年中期的 13 英寸 MacBook 上用卷尺测试一个 CSS 厘米单元:

Comparing a CSS centimeter with a physical centimeter using a tape on a 13-inch MacBook screen

As you can see, a CSS centimeter is obviously not equal to a physical one. (Image credit: Elad Shechter) (Large preview)

The result is the same for CSS inches:
对于 CSS 英寸,结果相同:

A CSS inch isn’t equal to a physical inch.
CSS 英寸不等同于物理英寸。

The same holds true for pica (pc) and millimeter (mm) units. These correspond to a part of either a CSS inch or a CSS centimeter, neither of which is connected to a real inch or a real centimeter.
这同样适用于异食癖 (pc) 和毫米 (mm) 单位。它们对应于 CSS 英寸或 CSS 厘米的一部分,两者都未连接到实际英寸或实际厘米。

Why CSS Inches And Centimeters Aren’t Real Inches And Centimeters 为什么 CSS 英寸和厘米不是真实的英寸和厘米

Since the 1980s, the PC market has determined a CSS inch to be equivalent to 96 pixels. This calculation of pixels was directly tied to the DPI/PPI (pixels per inch) standard of Microsoft’s Windows operating system for monitors at the time, the most common of which had a standard of 96 DPI.
自 1980 年代以来,PC 市场已确定 CSS 英寸等同于 96 像素。这种像素的计算与当时 Microsoft Windows 操作系统的显示器的 DPI/PPI(每英寸像素数)标准直接相关,其中最常见的标准为 96 DPI。

This meant that 1 CSS inch would always be equivalent to 96 CSS pixels.
这意味着 1 CSS 英寸将始终等同于 96 CSS 像素。

As for CSS centimeters, every centimeter is directly calculated from inches, which means that 1 inch is equivalent to 2.54 centimeters. This means that every 1 CSS centimeter will always be equal to 37.7952756 CSS pixels.
至于CSS厘米,每一厘米都是直接从英寸开始计算的,这意味着1英寸相当于2.54厘米。这意味着每 1 个 CSS 厘米将始终等于 37.7952756 个 CSS 像素。

In other words: 1cm = 37.7952756px (96px / 2.54).
换言之:1cm = 37.7952756px (96px / 2.54)

See the Pen CSS Real Dimensions! by Elad Shechter.

That decision, which seemed like a good idea at the beginning of the PC industry (which had kind of one standard), turned out to be a poor decision that would make the CSS inch and centimeter obsolete and useless (at least from the perspective of the web).
这个决定在PC行业(只有一个标准)开始时似乎是个好主意,但结果证明是一个糟糕的决定,它将使CSS英寸和厘米变得过时和无用(至少从Web的角度来看)。

Note that in the 1980s, Apple had a different standard of 72 DPI for screens.
请注意,在 1980 年代,Apple 对屏幕采用了不同的 72 DPI 标准。

Screen Pixels Get Denser 屏幕像素变得更密集

As I mentioned, the DPI of screens got denser over the years, and we saw screens of 120 to 160 DPI. And because 1 CSS inch always equals 96 CSS pixels, it means now that a CSS inch isn’t equal to a real physical inch.
正如我所提到的,多年来屏幕的 DPI 变得越来越密集,我们看到 120160 DPI 的屏幕。而且由于 1 CSS 英寸始终等于 96 个 CSS 像素,这意味着现在 CSS 英寸不等于真实的物理英寸。

A table comparing baseline pixel density in three categories of devices: a twentieth century PC with CRT display, modern laptop with LCD, and smartphones and tablets
(Image credit: “CSS Length Explained”, Mozilla Hacks) (Large preview)

Because a CSS inch and a CSS centimeter are directly converted from CSS pixels, and because screens have gotten more DPIs over the years, we’ve gotten to the point where these units don’t represent what they’re supposed to represent on screens.
因为 CSS 英寸和 CSS 厘米是直接从 CSS 像素转换而来的,而且由于屏幕多年来获得了更多的 DPI,我们已经到了这些单位不代表它们在屏幕上应该表示的内容的地步。

CSS Point Unit CSS 点单位

The point (pt) unit is one of the less-recognized units of CSS. As Wikipedia states:
点 (pt) 单位是 CSS 中较不容易识别的单位之一。正如维基百科所述:

“In typography, the point is the smallest unit of measure. It is used for measuring font size, leading, and other items on a printed page.”
“在排版中,点是最小的度量单位。它用于测量打印页面上的字体大小、行距和其他项目。

The Wikipedia page shows a ruler with the point scale on the bottom and the inch scale on the top:
维基百科页面显示了一把标尺,底部是点刻度,顶部是英寸刻度:

Ruler shown on the Wikipedia page
(Image credit: Wikipedia) (Large preview)

Before we get into why this unit isn’t really an absolute unit for the web, let’s go over the basic units of screens and printers.
在我们深入探讨为什么这个单位并不是真正的网络绝对单位之前,让我们先回顾一下屏幕和打印机的基本单位。

PPI And DPI PPI 和 DPI

We’ve already mentioned DPI, and you might have heard those terms in the past, but if you’ve never understood what exactly they’re all about, here is quick primer:
我们已经提到了 DPI,您过去可能听说过这些术语,但如果您从未了解过它们的全部内容,那么这里有一个快速入门:

  • PPI
    Screens are built from a lot of small light dots, called pixels. To measure the density of pixels, we count the number of pixels that fit 1 inch, called pixels per inch (PPI).
    生产者价格指数(PPI) 屏幕是由许多小光点(称为像素)构成的。为了测量像素的密度,我们计算适合 1 英寸的像素数,称为每英寸像素数 (PPI)。
  • DPI
    Printers print color dots. To represent the density of printer dots, we count the number of dots that fit 1 inch of paper, called dots per inch (DPI).
    新闻部 打印机打印彩色圆点。为了表示打印机点的密度,我们计算适合 1 英寸纸张的点数,称为每英寸点数 (DPI)。

PPI vs DPI: PPI refers to display resolution while DPI refers to printer resolution
(Image credit: Shutterstock) (Large preview)

In short, these are two ways to measure the density of visual information that we can fit in 1 inch.
简而言之,这是测量我们可以在 1 英寸内容纳的视觉信息密度的两种方法。

  • PPI: pixels per inch (for screens)
    PPI:每英寸像素数(用于屏幕)
  • DPI: dots per inch (for printers)
    DPI:每英寸点数(用于打印机)

It is important to mention that the count of CSS pixels and dots in 1 inch are for both the width and the height. This means that on a screen of 96 PPI, a box with a height and width of 1 inch will have a total size of 9216 pixels (96×96 px = 9216 px).
值得一提的是,1 英寸的 CSS 像素和点的数量是针对宽度和高度的。这意味着,在 96 PPI 的屏幕上,高度和宽度为 1 英寸的框的总大小为 9216 像素 (96×96 像素 = 9216 像素)。

Here is a visual demonstration of 1 inch with a screen of 10 PPI:
以下是 1 英寸的视觉演示,屏幕为 10 PPI:

A demonstration of 1 inch with a screen of 10 PPI
(Image credit: Shutterstock) (Large preview)

Here are some examples of real calculations of CSS PPI:
以下是 CSS PPI 实际计算的一些示例:

CSS Resolution (Pixels)CSS PPICSS Inches (width and height)
96x96961×1
141×1411411×1

“DPI” For Screens 屏幕的“DPI”

Manufacturers of mobile and desktop devices prefer to express their screen measurements in DPI, not PPI. But don’t let that confuse you: It is always PPI for screens and DPI for printers.
移动和桌面设备制造商更喜欢用 DPI 而不是 PPI 来表示他们的屏幕测量值。但不要让这让您感到困惑:屏幕的始终是 PPI,打印机的 DPI 始终是 PPI。

DPI/PPI Standards DPI/PPI标准

To represent all those dots and pixels, we have the point (pt) unit.
为了表示所有这些点和像素,我们有点 (pt) 单位。

But the point unit of CSS derives from the default printer DPI, which, again, was decided in the 1980s and is equal to 72 DPI. This means that 1 inch of CSS always equals 72 points.
但是 CSS 的点单位源自默认打印机 DPI,该 DPI 同样是在 1980 年代确定的,等于 72 DPI。这意味着 1 英寸的 CSS 始终等于 72 磅。

  • 1 inch = 72 points
    1 英寸 = 72
  • 1 point = 1/72nd of 1 inch
    1 点 = 1/72 英寸的 1 英寸的第 1 个

Pixels For Web, Dots For Printers WEB 的像素,打印机的点

For the web, the DPI unit has no meaning. The web DPI is defined according to a different standard (96 DPI), which we already talked about when we calculated a CSS inch and CSS centimeter. Because of this, there is no reason to use the point unit on the web.
对于 Web,DPI 单位没有任何意义。Web DPI 是根据不同的标准 (96 DPI) 定义的,我们在计算 CSS 英寸和 CSS 厘米时已经讨论过。因此,没有理由在网络上使用点单位。

Note: 1 point isn’t equal to (CSS) pixels.
注意:1 磅不等于 (CSS) 像素。

  • 1 point = 1.333 pixels
    1 点 = 1.333 像素
  • 72 points = 1 inch
    72 点 = 1 英寸
  • 72 points = 96 pixels
    72 点 = 96 像素

Printers 打印机

In this article, I mainly wanted to demonstrate why there aren’t any absolute units for the web. But what about using them for printers? Is there a reason to use CSS inches or centimeters or point units for printers?
在这篇文章中,我主要想演示为什么 Web 没有任何绝对单位。但是将它们用于打印机呢?是否有理由为打印机使用 CSS 英寸或厘米或点单位?

My Printing Test 我的打印测试

I ran a small test to check whether the 1980s standard of DPI works correctly on printers. I created two boxes: one with a width and height of 72 points, and the second one with a width and height of 1 inch.
我进行了一个小测试,以检查 1980 年代的 DPI 标准是否在打印机上正常工作。我创建了两个框:一个框的宽度和高度为 72 磅,第二个框的宽度和高度为 1 英寸。

I printed these two boxes on a laser printer that I have in my office. Here is my Codepen for testing points and inches for printers:
我在办公室里的激光打印机上打印了这两个盒子。这是我的Codepen,用于测试打印机的点和英寸:

See the Pen 1 inch by Elad Shechter.

Result 结果

I printed this demo on a laser printer. To my surprise, if I use 72 points (or 1 inch), I get exactly 1 inch. This means that, for printers, there is still, maybe, a good reason to use CSS units such as points, inches, and centimeters.
我在激光打印机上打印了这个演示。令我惊讶的是,如果我使用 72 点(或 1 英寸),我正好得到 1 英寸。这意味着,对于打印机来说,仍然有充分的理由使用CSS单位,如磅、英寸和厘米。

On the left, the printer. On the right, the printed test.
(Image credit: Elad Shechter) (Large preview)

Printers are able to print more DPIs, but if we are working at 100% zoom on the printer, then 72 points (or 1 inch) of CSS will equal a real physical inch.
打印机能够打印更多的 DPI,但是如果我们在打印机上以 100% 缩放工作,则 72 点(或 1 英寸)的 CSS 将等于实际的物理英寸。

Reminder: This article is more about the connection of absolute units to the web rather than to printers. Of course, the results might change on different types of printers.
提醒:本文更多的是关于绝对单位与 Web 的连接,而不是与打印机的连接。当然,在不同类型的打印机上,结果可能会有所不同。

Recommended reading: Using HSL Colors In CSS
推荐阅读:在 CSS 中使用 HSL 颜色

Trying To Create Accurate Sizes On The Web 尝试在网络上创建准确的尺寸

If we look at the 16-inch MacBook Pro, which has a ratio of 1.714 physical pixels to every 1 CSS pixel, we can’t accurately predict sizes on the web.
如果我们看一下 16 英寸的 MacBook Pro,它的物理像素与每 1 个 CSS 像素的比率,我们无法准确预测网络上的大小。

If we try to guess the real device pixel ratio on the 16-inch MacBook Pro using JavaScript’s window.devicePixelRatio, it will return an incorrect ratio of 2, instead of 1.714. (And this is without taking into account the zoom state of the web browser and operating system.)
如果我们尝试使用 JavaScript 的 window.devicePixelRatio 来猜测 16 英寸 MacBook Pro 上的真实设备像素比,它将返回不正确的 2 比例,而不是 1.714。(这还没有考虑到 Web 浏览器和操作系统的缩放状态。

An illustration of a measuring tape
Image credit: (Shutterstock) (Large preview)

Why We Need Real Absolute CSS Units 为什么我们需要真正的绝对 CSS 单位

When we want to define a fixed size for a sidebar element, we would use CSS pixels. But if you think about it, CSS pixels have no meaning these days. As we saw above, on most smartphones and desktops, CSS pixels don’t describe device pixels anymore.
当我们想为侧边栏元素定义固定大小时,我们会使用 CSS 像素。但如果你仔细想想,CSS像素现在已经没有意义了。正如我们上面看到的,在大多数智能手机和台式机上,CSS 像素不再描述设备像素。

Based on this, I believe we need actual physical units for CSS (like a real centimeter or inch unit) because CSS pixels no longer have any true meaning on the web.
基于此,我认为我们需要 CSS 的实际物理单位(如真实的厘米或英寸单位),因为 CSS 像素在 Web 上不再具有任何真正的含义。

It’s worth mentioning that Firefox had implemented an actual physical millimeter unit (mozmm), but removed it in version 59. I don’t know why they removed it. Perhaps it’s because so many things already depend on CSS pixels, such as responsive images and the em and rem units. If we tried to add a new physical measurement, maybe it would cause more problems than it solves.
值得一提的是,Firefox已经实现了一个实际的物理毫米单位(mozmm),但在版本59中删除了它。我不知道他们为什么要删除它。也许是因为很多东西已经依赖于 CSS 像素,例如响应式图像以及 emrem 单元。如果我们尝试添加新的物理测量值,也许它会导致比解决的问题更多的问题。

It seems that web folk have gotten so used to thinking in pixels that, even though the CSS pixel unit has lost its connection to device pixels, we’ll keep using the unit.
似乎网络上的人已经习惯于用像素来思考,以至于即使CSS像素单元已经失去了与设备像素的连接,我们也会继续使用这个单元。

And in case you still think that CSS pixels are an excellent unit of measurement, try to explain to a new web developer what this unit is actually measuring.
如果您仍然认为 CSS 像素是一个很好的测量单位,请尝试向新的 Web 开发人员解释这个单位实际上测量的内容。

For now, we don’t have any real way to describe physical sizes in CSS.
目前,我们没有任何真正的方法来描述CSS中的物理大小。

So, the CSS pixel is the worst kind of absolute unit — except for all the others.
因此,CSS 像素是最糟糕的绝对单位——除了所有其他单位。

To Summarize 总结一下

At the beginning of this article, I said that the absolute CSS units have become like new kinds of relative units. We started with CSS pixels, and we saw the difference between CSS pixels and device pixels.
在本文的开头,我说过绝对的CSS单位已经变得像新型的相对单位。我们从 CSS 像素开始,我们看到了 CSS 像素和设备像素之间的区别。

Then, we found that CSS inches and CSS centimeters are directly converted from CSS pixels and aren’t connected to real inches and centimeters. In the end, we talked about the point unit and, again, about how this unit has no absolute meaning for the web.
然后,我们发现 CSS 英寸和 CSS 厘米是直接从 CSS 像素转换而来的,并没有连接到真实的英寸和厘米。最后,我们谈到了点单位,并再次谈到了这个单位对网络没有绝对意义。

Final Words 最后的话

That’s all. I hope you’ve enjoyed this article and learned from my experience. If you like this post, I would appreciate hearing about it and sharing it.
就这样。我希望你喜欢这篇文章,并从我的经验中吸取了教训。如果您喜欢这篇文章,我将不胜感激地听到并分享它。

References


via:


一次搞懂 CSS 字体单位:px、em、rem 和 %

对于绘图和印刷而言,“单位” 很相当重要的,然而在网页排版里,单位也是同样具有重要性,在 CSS3 普及以来,更支援了一些方便好用的单位 ( px、em、rem… 等 ),这篇文章将整理这些常用的 CSS 单位,也帮助自己未来在使用上能更加得心应手。

“网页” 和 “印刷” 的单位

若要把单位做区隔,最简单可以分为 “网页” 和 “印刷” 两大类,通常对于 CSS 来说只会应用到网页的样式,毕竟真正要做印刷,还是会倾向透过排版软件来进行设计。

网页 ( 单位 )

  • px:绝对单位,代表屏幕中每个 “点”( pixel )。
  • em:相对单位,每个子元素透过 “倍数” 乘以父元素的 px 值。
  • rem:相对单位,每个元素透过 “倍数” 乘以根元素的 px 值。
  • %:相对单位,每个子元素透过 “百分比” 乘以父元素的 px 值。

网页 ( 属性名称 )

  • medium:预设值,等于 16px ( h4 预设值 )
  • xx-small:medium 的 0.6 倍 ( h6 预设值 )
  • x-small:medium 的 0.75 倍
  • small:medium 的 0.8 倍 ( h5 预设值,W3C 定义为 0.89,实测约为 0.8 )
  • large:medium 的 1.1 倍 ( h3 预设值,W3C 定义为 1.2,实测约为 1.1 )
  • x-large:medium 的 1.5 倍 ( h2 预设值 )
  • xx-large:medium 的 2 倍 ( h1 预设值 )
  • smaller:约为父层的 80%
  • larger:约为父层的 120%

印刷

  • pt:打印机的每个 “点”,定义为 1 pt = 1/72 in,如果在 72 dpi 的系统上 1 px = 1 pt,但如果在 96 dpi 的系统上 1 px = 0.75 pt ( 72/96 = 0.75 )。
  • in:英寸,在 96 dpi 的系统上 1 in = 96 px。
  • cm:公分,在 96 dpi 的系统上 1 cm = 37.795275593333 px。
  • mm:毫米,在 96 dpi 的系统上 1 cm = 3.7795275593333 px。

范例展示

以下将展示四种不同单位的范例,为公平起见,四个范例都套用预设的 div 格式,纯粹改变 font-size 看看有何不同,由于子元素若没有设定 font-size,会自动继承父元素的 font-size,使用上就应该要预先初始化字体大小,下面这两段 CSS 可以将所有的元素字体大小预设为 16px,尔后亦可个别进行调整。

html {
    font-size:16px;
}

html*{
    font-size: 1rem;
}

1. px

px 是绝对单位,因此只要设定多少 px,就会精确的呈现,对于一些讲求精准位置的排版而言十分有用,如范例表示的,指定多大 px 字体就会多大。

<div style="font-size:16px;">16px
    <div style="font-size:20px;">20px
        <div style="font-size:24px;">24px
            <div style="font-size:16px;">16px
                <div style="font-size:32px;">32px</div>
            </div>
        </div>
    </div>
</div>

在这里插入图片描述

2. em

em 是相对单位,为每个子元素透过 “倍数” 乘以父元素的 px 值,如果我们每一层 div 都使用 1.2em,最内层就会是 16px x 1.2 x 1.2 x 1.2 x 1.2 x 1.2 = 39.8px。( 浏览器预设字体大小为 16px,若无特别指定则会直接继承父元素字体大小 )

<div style="font-size:1.2em;">1.2em
    <div style="font-size:1.2em;">1.2em
        <div style="font-size:1.2em;">1.2em
            <div style="font-size:1.2em;">1.2em
                <div style="font-size:1.2em;">1.2em</div>
            </div>
        </div>
    </div>
</div>

在这里插入图片描述

3. rem

rem 是相对单位,为每个元素透过 “倍数” 乘以根元素的 px 值,如果我们每一层 div 都使用 1.2rem,最内层就会是 16px x 1.2 = 19.2px。( 根元素指的是 html 的 font-size,预设为 16px )。

<div style="font-size:1.2rem;">1.2rem
    <div style="font-size:1.2rem;">1.2rem
        <div style="font-size:1.2rem;">1.2rem
            <div style="font-size:1.2rem;">1.2rem
                <div style="font-size:1.2rem;">1.2rem</div>
            </div>
        </div>
    </div>
</div>

在这里插入图片描述

4. %

% 百分比是相对单位,和 em 大同小异,简单来说 em 就是百分比除以一百,如果我们每一层 div 都使用 120%,就等同于 1.2em,最内层就会是 16px x 1.2 x 1.2 x 1.2 x 1.2 x 1.2 = 39.8px

<div style="font-size:120%;">120%
    <div style="font-size:120%;">120%
        <div style="font-size:120%;">120%
            <div style="font-size:120%;">120%
                <div style="font-size:120%;">120%</div>
            </div>
        </div>
    </div>
</div>

在这里插入图片描述

5. small、medium、large… 等

字体大小的属性有七种,分别是xx-small、x-small、small、medium、large、x-large 和 xx-large,除了 x-small,其馀六种分别对应 h6~h1 的标签文字大小,根据 W3C 的规范,以 medium 预设 16px 为基础 ( 若 html 字体预设大小改变,medium 也会跟着变 ),使用固定的百分比乘以 medium 的大小,例如 ss-small 预设为 16px x 0.6 = 9.6px ( 浏览器显示为 12px )。

在这里插入图片描述

<div style="font-size:xx-small;">xx-small
    <div style="font-size:x-small;">x-small
        <div style="font-size:small;">small
            <div style="font-size:medium;">medium
                <div style="font-size:large;">large
                    <div style="font-size:x-large;">x-large
                        <div style="font-size:xx-large;">xx-large</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

在这里插入图片描述

6. larger、smaller

larger 和 smaller 就是固定百分比为单位,larger 为父层的 120%,smaller 为父层的 80%。

<div style="font-size:medium;">medium
  <div style="font-size:larger;">larger
    <div style="font-size:larger;">larger
      <div style="font-size:larger;">larger
        <div style="font-size:smaller;">smaller
          <div style="font-size:smaller;">smaller
            <div style="font-size:smaller;">smaller</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

在这里插入图片描述

小结

熟悉了字体大小单位之后,就更能有系统的设计整个网站的 CSS 架构,不过 font-size 本身和 font-family 有着一些复杂的关系,不同的 font-family 有时也会影响 font-size 的设定,因此使用上还是得稍微注意一下啰!


via:


CSS 单位指南:CSS em、rem、vh、vw 等详解

译者:Chengjun.L

作者:freeCodeCamp (英语)

原文:CSS Unit Guide: CSS em, rem, vh, vw, and more, Explained

许多 CSS 属性如 widthmarginpaddingfont-size 都需要一个长度,而 CSS 有许多不同的方法来表达长度。

在 CSS 中,长度是一个数字,一个没有空格的单位。例如,5px0.9em,等等。

在 CSS 中,一般有两种用于长度和尺寸的单位:绝对单位和相对单位。

绝对长度单位

绝对长度单位是基于一个实际的物理单位,通常被认为是跨设备的相同尺寸。但是,根据你的屏幕尺寸和质量,或者你的浏览器或操作系统的设置,可能会有一些例外。

下面是 CSS 中一些常见的绝对长度单位:

px

像素,或 px,是 CSS 中最常见的长度单位之一。

在 CSS 中,1 像素被 正式定义 为 1/96 英寸。所有其他的绝对长度单位都是基于这个像素的定义。

但是,在最初制定这一标准时,大多数显示器的分辨率为 1024×768,DPI(每英寸点数)为 96。

现代设备的屏幕具有更高的分辨率和 DPI,所以 96 像素长的线可能无法精确测量到 1 英寸,这取决于设备的情况。

尽管以像素为单位的尺寸在不同的设备上会有所不同,但一般认为在屏幕上使用像素更好。

如果你知道你的页面将在高质量的打印机上打印,那么你可以考虑使用另一个单位,比如 cmmm

cm

厘米

在 CSS 中,1cm 大约是 37.8 个像素,或约为 25.2/64 英寸。

mm

毫米

在 CSS 中,1mm 大约是 3.78 像素,或 1/10 厘米。

in

英寸

在 CSS 中,1 英寸大约是 96 个像素,或大约 2.54 厘米。

pt

在 CSS 中,1pt 大约是 1.3333 像素,或 1/72 英寸。

pc

派卡

在 CSS 中,1pc 大约是 16 个像素,或 1/6 英寸。

相对长度单位

相对长度单位是相对于另一个元素的大小或设置。例如,一个元素的相对字体大小可以用父元素的字体大小来计算。

下面是一些常见的相对长度单位:

em

CSS 的 em 单位的名字来自于一个排版单位。在字体排印学中,em 这个词 “最初是指所使用的字体和尺寸中大写字母 M 的宽度”。

当与 font-size 属性一起使用时,em 继承其父元素的 font-size 大小:

.container {
  font-size: 16px;
}

.container p {
  font-size: 1em;
}

.container h2 {
  font-size: 3em;
}

.container h3 {
  font-size: 2em;
}

在这个例子中,pfont-size16px(161)同时,h2font-size48px(163),h332px(16*2)。

如果 em 与另一个属性(如 width)一起使用,em 是用目标元素的大小来计算的。

rem

em。这种相对单位不受父元素的大小或设置的影响,而是以文档的根为基础。对于网站来说,文档的根是 html 元素。

p {
  font-size: 1.25rem;
}

在大多数浏览器中,默认的字体大小是 16,所以 html 元素的 font-size16px。所以在这种情况下,p20px(16*1.25)。

但是如果用户改变了他们浏览器的默认字体大小,那么 pfont-size 就会相应地放大或缩小。

%

百分比,或相对于父级大小的百分比大小:

div {
  width: 400px;
}

div p {
  width: 75%;
}

由于父级的宽度是 400px,所以内部段落的宽度是 300px(400*.75)。

vw

视图宽度,1vw 是视口宽度的 1%。

比如说:

body {
  width: 100vw;
}

由于 body 元素被设置为 100vw,即视口宽度的 100%,所以它将占用它所能获得的全部宽度。因此,如果你把浏览器的大小调整为 690 像素宽,那么 body 就会占据所有 690 像素的宽度。

vh

视图高度,1vh 是视口高度的 1%。

例如:

div {
  height: 50vh;
}

div 将填充视口高度的 50%。因此,如果浏览器窗口的高度是 900 像素,那么该 div 的高度将是 450 像素。

ex

CSS ex 单位的名称来自于字体排印学中的 x - 字高,即 “[字体中字母 x 的高度](https://www.wikiwand.com/zh/X 字高)”。在许多字体中,小写的 x 字符通常是最大字符高度的一半。

在 CSS 中,1ex 是字体的 x - 字高,或 1em 的一半。

但是,由于小写字母 x 的大小可以根据字体的不同而有很大的变化,因此 CSS 的 ex 单位很少被使用。

ch

字符单位,CSS 的 ch 单位被定义为字体的 0(零,或 U+0030)字符的宽度。

虽然 ch 单位对于像 Courier 这样的单行线 / 固定宽度的字体来说是一种精确的测量,但对于像 Arial 这样的比例字体来说,它可能是不可预测的。

例如,如果你的字体是 Courier,而你把一个元素的宽度设置为 60ch,那么这个元素的宽度就正好是 60 个字符。

但是,如果你的字体是 Arial,而你把一个元素的宽度设置为 60ch,那么就不知道这个元素会有多宽 —— 字符可能会溢出容器,也可能不够。


请看这篇文章(机翻,未校)

What is the CSS ‘ch’ Unit?

published on Thursday, June 28th, 2018.

I keep seeing authors and speakers refer to the ch unit as meaning “character width”. This leads to claims that you can “make your content column 60 characters wide for maximum readability” or “size images to be a certain number of characters!”
我不断看到作者和演讲者提到 ch 单位意味着“字符宽度”。这导致了这样的说法:“将你的内容列设置为 60 个字符宽,以获得最佳可读性”或“将图像调整为特定数量的字符!”

Well… yes and no. Specifically, yes if you’re using fixed-width fonts. Otherwise, mostly no.
嗯……是的,也不是。具体来说,如果您使用的是等宽字体,则是的;否则,基本上不是。

This is because, despite what the letters ch might imply, ch units are not “character” units. They are defined as:
这是因为,尽管字母 ch 可能暗示了某种含义,ch 单位并不是“字符”单位。它们的定义为:

Equal to the used advance measure of the “0” (ZERO, U+0030) glyph found in the font used to render it. (The advance measure of a glyph is its advance width or height, whichever is in the inline axis of the element.)
等于用于渲染字体中“0”(零,U+0030)字形的使用前进度量。(字形的前进度量是其前进宽度或高度,以元素的行内轴为准。)

So however wide the “0” character is in a given typeface, that’s the measure of one ch. In monospace (fixed-width) fonts, where all characters are the same width, 1ch equals one character. In proportional (variable-width) fonts, any given character could be wider or narrower than the “0” character.
因此,在给定的字体中,“0”字符的宽度就是一个 ch 的度量。在等宽(固定宽度)字体中,所有字符的宽度相同,1ch 等于一个字符。在比例(可变宽度)字体中,任何给定字符的宽度可能比“0”字符宽或窄。

To illustrate this, here are a few example elements which are set to be exactly 20ch wide, and also contain exactly 20 characters.
为了说明这一点,这里有几个示例元素,它们被设置为恰好 20ch 宽,并且包含恰好 20 个字符。

在这里插入图片描述

It’s probably no surprise that in Courier, all the elements are the exact same width as their text contents. In Helvetica, by contrast, this is mostly not the case except for numbers, which appear to be fixed-width. In Georgia, by contrast, none of the text contents fit the boxes, not even the numbers.
在 Courier 字体中,所有元素的宽度与其文本内容完全相同,这可能并不令人惊讶。相比之下,在 Helvetica 中,除数字外,大多数情况下并非如此,数字似乎是固定宽度的。而在 Georgia 字体中,甚至连数字的文本内容都无法适应框。

What I’ve found through random experimentation is that in proportional typefaces, 1ch is usually wider than the average character width, usually by around 20-30%. But there are at least a few typefaces where the zero symbol is skinny with respect to the other letterforms; in such a case, 1ch is narrower than the average character width. Trajan Pro is one example I found where the zero was a bit narrower than the average, but I’m sure there are others. Conversely, I’m sure there are typefaces with Big Fat Zeroes, in which case the difference between ch and the average character width could be around 50%.
通过随机实验,我发现,在比例字体中,1ch 通常比平均字符宽度要宽,通常多约 20-30%。但至少有几种字体的零符号与其他字母形状相比显得较窄;在这种情况下,1ch 的宽度就会小于平均字符宽度。我发现 Trajan Pro 就是一个例子,其中零的宽度稍微窄于平均宽度,但我相信还有其他类似的例子。反之,我也肯定有一些字体的零非常宽,在这种情况下,ch 与平均字符宽度之间的差异可能达到 50%。

So in general, if you want an 80-character column width and you’re going to use ch to size it, aim for about 60ch, unless you’re specifically working with a typeface that has a skinny zero. And if you’re working with multiple typefaces, say one for headlines and another for body copy, be careful about setting ch measures and thinking they’ll be equivalent between the two fonts. The odds are very, very high they won’t be.
因此,通常情况下,如果您想要 80 个字符的列宽,并打算使用 ch 来设置它,则目标大约为 60ch,除非您特别使用的是零比较窄的字体。如果您在使用多种字体,例如一种用于标题,另一种用于正文,请谨慎设置 ch 的度量,并认为它们在两种字体之间是等效的。概率极高,它们不会是。

It would be interesting to see the Working Group take up the idea of average character width as a unit of measure — say, 1acw or possibly just 1cw — which actually uses all the letterforms in a typeface to calculate an average value. That would get a lot closer to “make your columns 60 characters wide!” in a lot more cases than ch does now.
看到工作组采纳平均字符宽度作为度量单位的想法将会很有趣——比如说,1acw 或者可能仅为 1cw ——这样可以利用字体中的所有字形来计算平均值。这将使“将你的列宽设置为 60 个字符!”在更多情况下更接近现实,而不仅仅是现在的 ch。


了解对 ch 单位的深入解释,并看一些例子。

vminvmax

视口最小(vmin)和视口最大(vmax)的单位是基于 vwvh 的值。

1vmin 是视口最小尺寸的 1%,而 1vmax 是视口最大尺寸的 1%。

例如,想象一个宽 1200 像素、高 600 像素的浏览器窗口。在这种情况下,1vmin6pxvh 的 1%,即 600 像素时较小值)。同时,1vmax12pxvh 的 1%,即 1200 像素时的较大值)。


via:


综合指南:何时使用 Em 与 Rem

Kezz Bracey

Jul 21, 2015

你可能已经很熟练使用这两个灵活的单位,但你可能不完全了解何时使用 rem ,何时使用 em。 本教程将帮你弄清楚!

Em 和 rem 都是灵活、 可扩展的单位,由浏览器转换为像素值,具体取决于您的设计中的字体大小设置。 如果你使用值 1em 或 1rem,它可以被浏览器翻译成 从 16px 到 160px 或其他任意值。

CSS 边距设置为 1em

file

浏览器翻译成 16px

在这里插入图片描述

CSS padding 设为 16px

在这里插入图片描述

浏览器翻译成 160px

另一方面,浏览器使用 px 值,所以 1px 将始终显示为完全 1px。

滑动滑块试试这个 CodePen 例子,你可以看到 rem 和 em 单位的值可以转化为不同的像素值,而 px 单位保持固定大小:

最大的问题是

使用 em 和 rem 单位可以让我们的设计更加灵活,能够控制元素整体放大缩小,而不是固定大小。 我们可以使用这种灵活性,使我们在开发期间,能更加快速灵活的调整,允许浏览器用户调整浏览器大小来达到最佳体验。

Em 和 rem 单位提供的这种灵活性和工作方式都很相似,所以最大的问题是,我们何时应使用 em 值,何时应使用 rem 值呢?

主要区别

Em 和 rem 单位之间的区别是浏览器根据谁来转化成 px 值 理解这种差异是决定何时使用哪个单元的关键。

我们要通过复习 rem 和 em 单位如何工作,来确保你知道每一个细节。 然后我会讲到为什么你应该使用 em 或 rem 的单位。

最后,我们会看看到底哪些典型元素的设计,你应该在实际应用中使用哪种类型的单位。

rem 单位如何转换为像素值

当使用 rem 单位,他们转化为像素大小取决于页根元素的字体大小,即 html 元素的字体大小。 根元素字体大小乘以你 rem 值。

例如,根元素的字体大小 16px,10rem 将等同于 160px,即 10 x 16 = 160。

file

CSS padding 设置为 10rem

在这里插入图片描述

计算结果为 160px

em 单位如何转换为像素值

当使用 em 单位时,像素值将是 em 值乘以使用 em 单位的元素的字体大小。

例如,如果一个 div 有 18px 字体大小,10em 将等同于 180px,即 10 × 18 = 180。

在这里插入图片描述

CSS padding 设置为 10em

file

计算到 180px (或接近它)

重点理解:

有一个比较普遍的误解,认为 em 单位是相对于父元素的字体大小。 事实上,根据 W3 标准 ,它们是相对于使用 em 单位的元素的字体大小。

父元素的字体大小可以影响 em 值,但这种情况的发生,纯粹是因为继承。 让我们看看为什么以及如何起作用。

Em 单位的遗传效果

使用 em 单位存在继承的时候,情况会变得比较棘手,因为每个元素将自动继承其父元素的字体大小。 继承效果只能被明确的字体单位覆盖,比如 px,vw

使用 em 单位的元素字体大小根据它们来定。 但该元素可能继承其父元素的字体大小,而父元素又继承其父元素的字体大小,等等。 因此,以 em 为单位的元素字体大小可能会受到其任何父元素的字体大小影响。

让我们看看一个例子。 在下面的 CodePen 单步执行试试。 随着你的前进,使用 Chrome 开发工具或 Firebug 为火狐浏览器来检查我们的 em 单位计算到的像素值。

Em 继承的例子

如果我们的根元素字体大小为 16px (通常是默认值) 一个子元素 div 里面 padding 值为 1.5em,该 div 将从根元素继承字体大小 16px。 因此 padding 会翻译成 24px,即 1.5 x 16 = 24。

如果我们加多一个 div 来包裹原先的 div,然后设置其字体大小为 1.25em 呢?

我们包裹的 div 继承根元素字体大小 16px ,并乘以它自己的 1.25em 的字体大小。 这将设置包裹 div 字体大小为 20px,即 1.25 x 16 = 20。

现在我们原始的 div 不再直接从根元素继承,而是从其新的父元素继承字体大小为 20px 1.5em 其 padding 值现在等于 30px,即 1.5 x 20 = 30。

这个继承效应可以更复杂,如果我们向我们原始的 div 添加 em 字体单位,比方说 1.2em。

Div 从其父级继承 20px 字体大小,然后,乘以它自己的 1.2em 设置,给它 24px,即 1.2 × 20 = 24 新字体大小。

div 上的 1.5em padding 现在将再次改变大小,用新的字体大小,36px,即 1.5 × 24 = 36 。

最后,为了进一步说明那个 em 单位是相对于他们最终获得 (不是父元素) 的字体大小,让我们来看看设置 padding 1.5em 如果我们显式设置 div 使用 14px 值,不继承字体大小会发生什么。

现在,我们的 padding 为 21px,即 1.5 x 14 = 21 已经变小了。 它不受父元素的字体大小。

由于存在着这些隐患,你可以看到为什么必须知道如何正确管理使用 em 单位。

浏览器设置 HTML 元素字体大小的影响

默认情况下浏览器通常有字体大小 16px,但这可以被用户更改为从 9px 到 72px 的任何值

在这里插入图片描述

你需要知道的:

根 html 元素将继承浏览器中设置的字体大小,除非显式设置固定值去覆盖。

所以 html 元素的字体大小虽然是直接确定 rem 值,但字体大小可能首先来自浏览器设置。

因此浏览器的字体大小设置可以影响每个使用 rem 单元以及每个通过 em 单位继承的值。

没有设置 HTML 字体大小时,浏览器设置起作用

除非重写,否则它将继承浏览器默认设置的字体大小。 例如,让我们把网站的 html 元素没有设置 font-size 值。

如果用户让他们的浏览器默认字体大小为 16px,那么根元素字体大小将为 16px。 在 Chrome 开发工具下,你可以在已计算选项卡下看到一个元素继承的属性。

在这里插入图片描述

在这种情况下 10rem 等于 160px,即 10 x 16 = 160。

如果用户将其浏览器中的默认字体大小调为 18px,根字体大小变成 18px。 现在 10rem 转换为 180px,即 10 × 18 = 180。

file

浏览器将调整使用 em 单位的 HTML 元素字体大小

当 em 单位设置在 html 元素上时,它将转换为 em 值乘以浏览器字体大小的设置。

例如,如果网站的 html 元素的字体大小属性设置为 1.25em,根元素字体大小将为 1.25 倍的浏览器的字体大小设置。

如果浏览器字体大小被设置为 16px,根字体大小会出来为 20px,即 1.25 x 16 = 20。

在这里插入图片描述

在这种情况下 10rem 将等于 200px,即 10 × 20 = 200。

在这里插入图片描述

所以,如果浏览器字体大小被设置为 20px,根元素字体大小会翻译成 25px,即 1.25 × 20 = 25。

file

现在 10rem 将等于 250px,即 10 × 25 = 250。

在这里插入图片描述

总结与 rem 差异 em

上述所有归结如下:

  • rem 单位翻译为像素值是由 html 元素的字体大小决定的。 此字体大小会被浏览器中字体大小的设置影响,除非显式重写一个具体单位。
  • em 单位转为像素值,取决于他们使用的字体大小。 此字体大小受从父元素继承过来的字体大小,除非显式重写与一个具体单位。

为什么使用 rem 单位:

Rem 单位提供最伟大的力量并不仅仅是他们提供一致尺寸而不是继承。 相反,它给我们的一个途经去获取用户的偏好来影响网站中每一处使用 rem 的元素大小,不再是使用固定的 px 单位。

为此,使用 rem 单位的主要目的应该是确保无论用户如何设置自己的浏览器,我们的布局都能调整到合适大小。

一个站点最初设计可以专注于最常见的默认浏览器中字体大小 16px。

在这里插入图片描述

浏览器字体大小 16px

但是,通过使用 rem 单位,如果用户调整其字体大小,我们也能保证布局的完整性,使用较小的文本避免文本空间被压扁了。

file

浏览器字体大小 34px

如果用户缩小其字体大小,整个布局掉下来,空白区域中的文本也不会想得很无力。

在这里插入图片描述

浏览器字体大小 9px

用户会因为各种各样的原因更改字体大小设置。 容纳这些设置可以获得更好的用户体验。

重要的是:

一些设计师使用结合 rem 单位的方式给 html 元素设置了一个固定的 px 单位。 这是很普遍的做法,所以改变 html 元素的字体大小时,可以使整个页面做相应调整

我强烈反对种做法,因为它重写继承了用户设置的浏览器字体大小。 更夸张的说,这剥削了用户自行调整以获得最佳视觉效果的能力。

如果您确实需要更改 html 元素的字体大小,那么就使用 em,rem 单位,这样根元素的值还会是用户浏览器字体大小的乘积。

这将允许您通过更改您的 html 元素的字体大小,调整你的设计,但仍会保留用户的浏览器设置的效果。

为什么使用 em 单位

em 单位取决于一个 font-size 值而非 html 元素的字体大小。

为此,em 单位的主要目的应该是允许保持在一个特定的设计元素范围内的可扩展性。

例如,您可能使用 em 值设置导航菜单项的 padding、 margin,line-height 等值。

在这里插入图片描述

带有 0.9rem 字体大小的菜单

通过这种方式,如果您更改菜单的字体大小菜单项周围的间距将在剩余的空间按比例缩放。

file

带有 1.2rem 字体大小的菜单

前面一节中你看到跟踪 em 单位如何变得不可收拾。 为此,我建议只在你标识清楚的情况下使用 em 单位。

实际应用

一些 web 设计师之间存在辩论,我相信不同的人有不同的首选的方法,但我的建议是,如下所示。

使用 em 单位:

根据某个元素的字体大小做缩放而不是根元素的字体大小。

一般来说,你需要使用 em 单位的唯一原因是缩放没有默认字体大小的元素。

根据我们上面的例子,设计组件比如按钮,菜单和标题可能会有自己明确的字体大小。 当你修改字体大小的时候,你希望整个组件都适当缩放

通用属性这一准则将适用于在非默认字体大小的元素上的 padding、 margin、 width、 height 和 line-height 等值。

我建议,当您使用 em 单位,他们使用的元素的字体大小应设置对 rem 单位,以保留的可扩展性,但避免继承混淆。

通常不使用 em 单位控制字体大小

我们经常会看到使用 em 作为字体大小单位,特别是标题,当我认为如果使用 rem 将更具可扩展性。

标题经常使用 em 单位的原因是他们相比 px 单位,在相对常规文本大小方面更出色。 然而 rem 单位同样也可以实现这一目标。 如果 html 元素上任何字体大小调整,标题大小仍会缩放。

请尝试更改下面的 CodePen,看看 html 元素上的 em 字体大小如何起作用:

少部分情况下,我们不想我们的字体大小根据根元素做调整,只有几个例外的情况。

我们可以想到的例子是一个使用 em 字体大小的下拉菜单,我们有第二个级别的菜单项文本大小取决于第一级字体大小。 另一个例子可能是用在按钮里面的字体图标,字体图标的大小跟按钮的文本大小有关。

然而,大多数 web 设计中的元素往往不会有这种类型的要求,所以一般使用 rem 单位的字体大小,em 单位只在特殊的情况下使用。

使用 rem 单位:

不需要 em 单位,并且根据浏览器的字体大小设置缩放的任何尺寸。

这几乎在一个标准的设计中占据了一切,包括 heights,widths,padding,margin,border,font-size,shadows,几乎包括你布局的每部分。

简单地说,一切可扩展都应该使用 rem 单位。

小贴士

创建布局时,往往要以像素为单位更方便,但部署时应使用 rem 单位。

你可以使用预处理比如 Stylus / Sass / Less,来自动转换单位或 PostCSS 之类的插件。

或者,您可以使用 PXtoEM 手动做您的转换。

始终使用 rem 单位做媒体查询

特别注意,当使用 rem 单位创建统一可扩展的设计,媒体查询也应该是 rem 单位。 这将确保,无论用户浏览器的字体大小,您的媒体查询会对它作出反应和调整您的布局。

例如,如果用户缩放文本非常高,您的布局可能需要从两列到单个列调整,因为它可能会在较小的移动设备上显示。

如果您的断点在固定的像素宽度,只有不同的视口的大小可以触发它们。 但是基于 rem 的断点他们将响应不同的字体大小。

不要使用 em 或 rem :

多列布局

布局中的列宽通常应该是 %,因此他们可以流畅适应无法预知大小的视区。

然而单一列一般仍然应使用 rem 值来设置最大宽度。

例如:

.container {
    width: 100%;
    max-width: 75rem;
}

这保持列的灵活,可扩展。又能防止变得太宽了。

当元素应该是严格不可缩放的时候

在一个典型的 web 设计的过程中,不会有很多部分的你不能使用伸缩性设计的布局。 不过偶尔你会遇到真的需要使用显式的固定的值,以防止缩放的元素。

采用固定的尺寸值的前提应该是,如果被缩放的话,它的结构会被打碎。 这真的不常出现,所以你想拿出那些 px 单位之前,问问自己是否使用它们是绝对必要的。

总结

让我们以一个快速符号点概括我们介绍的内容:

  • rem 和 em 单位是由浏览器基于你的设计中的字体大小计算得到的像素值。
  • em 单位基于使用他们的元素的字体大小。
  • rem 单位基于 html 元素的字体大小。
  • em 单位可能受任何继承的父元素字体大小影响
  • rem 单位可以从浏览器字体设置中继承字体大小。
  • 使用 em 单位应根据组件的字体大小而不是根元素的字体大小。
  • 在不需要使用 em 单位,并且需要根据浏览器的字体大小设置缩放的情况下使用 rem。
  • 使用 rem 单位,除非你确定你需要 em 单位,包括对字体大小。
  • 媒体查询中使用 rem 单位
  • 不要在多列布局中使用 em 或 rem - 改用 %。
  • 不要使用 em 或 rem,如果缩放会不可避免地导致要打破布局元素。

我希望你现在已经建立了强健的、 完整的图片,到底 em 和 rem 的单位如何工作,并通过,知道如何最好地利用他们在你的设计中。

我鼓励您尝试为你自己使用本教程指南,它们会为您创建完全成熟的可伸缩性和响应性布局。

ByKezz Bracey


via:


物理像素与逻辑像素的关系

物理像素

指的是设备的实际像素,这个主要由设备自身的硬件所决定,因此同一类型的设备物理像素是固定的。

逻辑像素(DPI)

逻辑像素是相对于物理像素之后提出的一个概念,也被称为设备独立像素(Device Independent Pixel)

我们在 css 中设置的 1px 就等于一个设备独立像素

设备像素比(Device Pixel Ratio,DPR)

1,DPR = 物理像素 / 逻辑像素;

2, 例如 DPR = 2, 也就相当于一个逻辑像素实际上由四个物理像素组成;

3, 以 iPhone6 手机为例,iPhone6 的物理像素为 1334 x 750 像素,而逻辑像素只有 667 x 375 像素;

4,DPR 值,厂商在设备出厂时就已经进行设置,并且禁止用户进行更改。

逻辑像素出现的原因

1,随着科技的发展,设备所能达到的物理像素只会不断提高

2,就以 iPhone12 为例,它的物理像素可以达到 2532 x 1170 像素,这相较于一般电脑也毫不逊色

3,但这并不代表它就可以按照实际的物理像素来设置 css 尺寸,原因主要为以下两点:

人机尺寸的限制

1. 手机只能这么大

手机作为移动设备,有属于它自己的设计定位,

这也决定着它必须依据人手的尺寸进行人机工程设计

这就决定了它的实际设备尺寸上限

2. 内容的显示不能特别小

人所能接受的最小字体尺寸是一定的

以 DPR= 2 的手机为例,如果厂商不进行 dpr 的设置,同样将 css 的字体大下设置为 12px

在手机上显示的字体其实只有 12px 的四分之一大小,这对使用者来说无疑是一种折磨。


via:


什么是物理像素、虚拟像素、逻辑像素、设备像素,什么又是 PPI, DPI, DPR 和 DIP

有关 viewport 以及苹果安卓设备上的页面呈现为什么效果不一样,又有哪些方法去改变和统一呢?

网络上有很多资源对这些知识点进行了介绍,但是查看之后我发现大都比较零散且阅读顺序容易让新人疑惑,在这里我尝试根据几篇文章糅合了一个循序渐进的知识点整理。在正式开始介绍之前,我们先集中看看几个基本概念。

  • 设备像素 (device pixel, dp): 又称为物理像素。指设备能控制显示的最小物理单位,意指显示器上一个个的点。从屏幕在工厂生产出的那天起,它上面设备像素点就固定不变了,单位 pt。pt 在 css 单位中属于真正的绝对单位,1pt = 1/72 (inch), inch 及英寸,而 1 英寸等于 2.54 厘米。所以设备像素的特点就是大小固定,不可变。比如 iPhone 5 的分辨率为 640 x 1136px.
  • CSS 像素 (css pixel, px): 又称为虚拟像素,也可以理解为直觉像素。CSS 像素是 Web 编程的概念,指的是 CSS 样式代码中使用的逻辑像素。在 CSS 规范中,长度单位可以分为两类,绝对 (absolute) 单位以及相对 (relative) 单位。px 是一个相对单位,相对的是前面所说的设备像素 (device pixel)。比如 iPhone 5 的 CSS 像素数为 320 x 568px.

像素概念汇总

前面说到的 px 相对单位指的是图像显示的基本单元,它既不是一个确定的物理量,也不是一个点或者小方块,而是一个抽象概念。 刚刚提到了图像显示的基本单元,这个东西在不同设备上又是不一样的,例如显示器上的物理像素指的是显示器的点距,而打印机的物理像素则指的是打印机的墨点。

作为一个抽象概念,CSS 像素又具有两个方面的相对性,即:

  • 在同一个设备上,每 1 个 CSS 像素所代表的设备像素是可以变化的(即 CSS 像素的第一方面的相对性);
  • 在不同的设备之间,每 1 个 CSS 像素所代表的设备像素是可以变化的(即 CSS 像素的第二方面的相对性);

所以,CSS 中的 1px(CSS 像素 可变)!== 设备的 1px(设备像素 不可变)。

CSS 像素的真正含义

按照 CSS 规范的定义,CSS 中的 px 是一个相对长度,它相对的,是 viewing device 的分辨率。这个 viewing device,通常就是电脑显示器。典型的电脑显示器的分辨率是 96DPI,也就是 1 像素为 1/96 英寸(实际上,假设我们的显示器分辨率都与物理分辨率一致,而液晶点距其实是 0.25mm 到 0.29mm 之间,所以不太可能是正好 1/96 英寸,而只是接近)。

一般来说,px 就是对应设备的物理像素,然而如果输出设备的解析度与电脑显示器大不相同,输出效果就会有问题。例如打印机输出到纸张上,其解析度比电脑屏幕要高许多,如果不缩放,直接使用设备的物理像素,那电脑上的照片由 600DPI 的打印机打出来就比用显示器看小了约 6 倍。

由于不同的物理设备的物理像素的大小是不一样的,所以 CSS 认为浏览器应该对 CSS 中的像素进行调节,使得浏览器中 1 个 CSS 像素的大小在不同物理设备上看上去大小总是差不多,目的是为了保证阅读体验的一致。为了达到这一点,浏览器可以直接按照设备的物理像素大小进行换算,而 CSS 规范中使用参考像素来进行换算。

一个参考像素即为从一臂之遥看解析度为 96DPI 的设备输出(即 1 英寸 96 点)时,1 点(即 1/96 英寸)的视角。它并不是 1/96 英寸长度,而是从一臂之遥的距离处看解析度为 96DPI 的设备输出一单位(即 1/96 英寸)时视线与水平线的夹角。通常认为常人臂长为 28 英寸,所以它的视角是: (1/96) in / (28in * 2 * PI / 360deg) = 0.0213 度。如下图是一个示意图:

在这里插入图片描述

对于人来说,眼睛看到的大小取决于可视角度。而可视角度取决于物体的实际大小以及物体与眼睛的距离。10 米远处一个 1 米见方的东西,与 1 米远处的 10 厘米见方的东西,看上去的大小差不多是一样的,所谓一叶障目不见泰山,讲的就是这个常识。

左边的屏幕(可以认为是电脑屏幕)的典型视觉距离是 71 厘米即 28 英寸,其 1px 对应了 0.28mm;而右边的屏幕(可以认为是你的 42 寸高清电视)的典型视觉距离是 3.5 米即 120 英寸,其 1px 对应 1.3mm。42 寸的 1080p 电视,分辨率是 1920*1080,则其物理像素只有 0.5mm 左右。

综上,px 是一个相对单位,而且在特定设备上总是一个近似值(原则是尽量接近参考像素)。

然而,如果你把绝对单位理解为对输出效果的绝对掌控,事情却大相径庭。就网页输出的最主要对象 —— 电脑屏幕来说,px 可被视为一个基准单位 —— 与桌面分辨率一致,如果是液晶屏,则几乎总是与液晶屏物理分辨率一致 —— 也就是说网页设计者设定的 1px,就是 “最终打开这个网页的用户在显示器上看到的 1 个点距”!反倒是那些绝对单位,其实一点也不绝对。

那么 px 都会受哪些因素的影响而变化?

  • 每英寸像素 (pixel per inch, ppi/PPI): 它表示的是每英寸所拥有的像素 (pixel) 数目,更确切的说法应该是像素密度,放到显示器上说的是每英寸多少物理像素及显示器设备的点距。数值越高,代表显示屏能够以越高的密度显示图像。
  • 设备像素比 (device pixel ratio, dpr/DPR): 它描述的是未缩放状态下,设备像素和 CSS 像素的初始比例关系,也可以解释为默认缩放比例。如何理解这个概念呢?通俗来说,它是指在开发中 1 个 CSS 像素占用多少设备像素,如 dpr=2 代表 1 个 CSS 像素用 2x2 个设备像素来绘制,所以,可以理解为 1px 由多少个设备像素组成
  • DPI: 每英寸多少点。

当用于描述显示器时,我们可以吧 ppi 和 dpi 认为是同一个概念。那么 ppi 和 dpr 到底是什么关系呢? ppi 用作显示设备的工业标准,业界人士用 ppi 的值来衡量一个屏幕是否为高清屏,然后根据得到的密度分界来获得此时对应的 dpr 值,也即默认缩放比例。 dpr 和 ppi 相关,一般 dpr 为 ppi/160 的整数倍,如下所示:

项名ldpimdpihdpixhdpi
密度分界(密度值)120160240320
屏幕尺寸(分辨率)240×320320×480480×800640×960
默认缩放比例0.751.01.52.0

了解了这两个概念后,我们可以来说说导致 CSS 中 px 变化的因素了。

  • 像素密度:从 iPhone4 开始,苹果推出了 Retina 屏,分辨率提高了一倍(640*960),而屏幕尺寸却没变。这时一个 css 像素 = 2 个设备像素(换算公式为 1 \text {px} = (dpr)^2 \times 1 \text {dp}$, 必须让 css 中的 1px 代表更多的设备像素,才能让 1px 的东西在屏幕上的大小与那些低分辨率的设备差不多,否则会因太小而看不清),即 DPR=2,示意图如下:

在这里插入图片描述

  • 缩放操作:缩放也会引起 css 中 px 的变化。放大页面到 200%,字体大小与元素宽度的像素值不变,只是 css 的 1px 代表设备像素中的 4px,宽高都是 200%,DPR 增加了。此时,获取 screen.width 值不变,而 window.innerWidth/Height 值(visual viewport)变成原来的一半。缩放值越大,当前 viewport 宽度会越小。

如何理解上面说到的缩放呢?放大 1 倍,原来 1px 的东西变成 2px,但 1px 变为 2px 并不是把原来的 320px 变为 640px,而是在实际宽度不变的情况下,1px 变得跟原来的 2px 的长度(长宽)一样了(元素会占据更多的设备像素),所以放大 1 倍后原来需要 320px 才能填满的宽度现在只需要 160px,也即原来 320px 的面积里现在只能填入 160px 的东西了。

举个例子说明 CSS 像素的相对性,如下示意图:

在这里插入图片描述

作为 Web 开发者,我们接触的更多的是用于控制元素样式的样式单位像素。这里的像素我们称之为 CSS 像素。假设我们用 PC 浏览器打开一个页面,浏览器此时的效果如左图所示,但如果我们把页面放大(通过 “Ctrl 键” 加上 “+ 号键”),此时块状容器则横向扩张,如右图所示(黑色为实际效果,灰色为原来效果)。吊诡的是此时我们既没有调整浏览器窗口大小,也没有改变块状元素的 css 宽度,但是它看上去却变大了一倍 —— 这是因为我们把 CSS 像素放大为了原来的两倍。

也就是说默认情况下一个 CSS 像素应该是等于一个物理像素的宽度的,但是浏览器的放大操作让一个 CSS 像素等于了多个设备像素宽度。

  • 设备独立像素 (Device independent Pixel, DIP): 也称为逻辑像素,简称 DIP.

像素换算与倍率

DPR = 设备像素 / CSS像素 = 屏幕横向设备像素 / 理想视口的宽
CSS像素 = 设备独立像素 = 逻辑像素

有关倍率,我们用 iPhone 3gs 和 4s 来举例。假设有个邮件列表界面,我们不妨按照 PC 端网页设计的思维来想象。3gs 上大概只能显示 4-5 行,4s 就能显示 9-10 行,而且每行会变得特别宽。但两款手机其实是一样大的。如果照这种方式显示,3gs 上刚刚好的效果,在 4s 上就会小到根本看不清字。

在这里插入图片描述

在现实中,这两者效果却是一样的。这是因为 Retina 屏幕把 2x2 个像素当 1 个像素使用。比如原本 44 像素高的顶部导航栏,在 Retina 屏上用了 88 个像素的高度来显示。导致界面元素都变成 2 倍大小,反而和 3gs 效果一样了。画质却更清晰。

在以前,iOS 应用的资源图片中,同一张图通常有两个尺寸。你会看到文件名有的带 @2x 字样,有的不带。其中不带 @2x 的用在普通屏上,带 @2x 的用在 Retina 屏上。只要图片准备好,iOS 会自己判断用哪张,Android 道理也一样。

由此可以看出,苹果以普通屏为基准,给 Retina 屏定义了一个 2 倍的倍率(iPhone 6plus 除外,它达到了 3 倍)。实际像素除以倍率,就得到逻辑像素尺寸。只要两个屏幕逻辑像素相同,它们的显示效果就是相同的。

Viewport

什么是 viewport? 通俗的讲,移动设备上的 viewport 就是设备的屏幕上能用来显示我们的网页的那一块区域,在具体一点,就是浏览器上 (也可能是一个 app 中的 webview) 用来显示网页的那部分区域,但 viewport 又不局限于浏览器可视区域的大小,它可能比浏览器的可视区域要大,也可能比浏览器的可视区域要小。在默认情况下,一般来讲,移动设备上的 viewport 都是要大于浏览器可视区域的,这是因为考虑到移动设备的分辨率相对于桌面电脑来说都比较小,所以为了能在移动设备上正常显示那些传统的为桌面浏览器设计的网站,移动设备上的浏览器都会把自己默认的 viewport 设为 980px 或 1024px(也可能是其它值,这个是由设备自己决定的),但带来的后果就是浏览器会出现横向滚动条,因为浏览器可视区域的宽度是比这个默认的 viewport 的宽度要小的。

首先,移动设备上的浏览器认为自己必须能让所有的网站都正常显示,即使是那些不是为移动设备设计的网站。但如果以浏览器的可视区域作为 viewport 的话,因为移动设备的屏幕都不是很宽,所以那些为桌面浏览器设计的网站放到移动设备上显示时,必然会因为移动设备的 viewport 太窄,而挤作一团,甚至布局什么的都会乱掉。也许有人会问,现在不是有很多手机分辨率都非常大吗,比如 768x1024,或者 1080x1920 这样,那这样的手机用来显示为桌面浏览器设计的网站是没问题的吧?前面我们已经说了,css 中的 1px 并不是代表屏幕上的 1px,你分辨率越大,css 中 1px 代表的物理像素就会越多,DPR 的值也越大,这很好理解,因为你分辨率增大了,但屏幕尺寸并没有变大多少,必须让 css 中的 1px 代表更多的物理像素,才能让 1px 的东西在屏幕上的大小与那些低分辨率的设备差不多,不然就会因为太小而看不清。所以在 1080x1920 这样的设备上,在默认情况下,也许你只要把一个 div 的宽度设为 300 多 px(视 DPR 的值而定),就是满屏的宽度了。为了防止某些网站因为 viewport 太窄而显示错乱,所以这些浏览器就决定默认情况下把 viewport 设为一个较宽的值,比如 980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。ppk 大神 把这个浏览器默认的 viewport 叫做 layout viewport。这个 layout viewport 的宽度可以通过 document.documentElement.clientWidth 来获取。

然而,layout viewport 的宽度是大于浏览器可视区域的宽度的,所以我们还需要一个 viewport 来代表 浏览器可视区域的大小,我们叫他 visual viewport。visual viewport 的宽度可以通过 window.innerWidth 来获取,但在 Android 2, Oprea mini 和 UC 8 中无法正确获取。下图为两个 viewport 的示意图:

在这里插入图片描述

现在我们已经有两个 viewport 了 - layout viewport 和 visual viewport。但浏览器觉得还不够,因为现在越来越多的网站都会为移动设备进行单独的设计,所以必须还要有一个能完美适配移动设备的 viewport。所谓的完美适配指的是,首先不需要用户缩放和横向滚动条就能正常的查看网站的所有内容;第二,显示的文字的大小是合适,比如一段 14px 大小的文字,不会因为在一个高密度像素的屏幕里显示得太小而无法看清,理想的情况是这段 14px 的文字无论是在何种密度屏幕,何种分辨率下,显示出来的大小都是差不多的。当然,不只是文字,其他元素像图片什么的也是这个道理,这就是第三个 viewport —— 移动设备的理想 viewport (ideal viewport)。

ideal viewport 并没有一个固定的尺寸,不同的设备拥有有不同的 ideal viewport。所有 iPhone 的 ideal viewport 宽度都是 320px,无论它的屏幕宽度是 320 还是 640,也就是说,在 iPhone 中,css 中的 320px 就代表 iPhone 屏幕的宽度。

但是安卓设备就比较复杂了,有 320px 的,有 360px 的,有 384px 的等等,关于不同的设备 ideal viewport 的宽度都为多少,可以到 http://viewportsizes.com 去查看一下,里面收集了众多设备的理想宽度。

总结一下,ppk 把移动设备上的 viewport 分为 layout viewport, visual viewport 和 ideal viewport 三类:

  • ideal viewport 是最适合移动设备的 viewport,ideal viewport 的宽度等于移动设备的屏幕宽度,只要在 css 中把某一元素的宽度设为 ideal viewport 的宽度 (单位用 px),那么这个元素的宽度就是设备屏幕的宽度了,也就是宽度为 100% 的效果。ideal viewport 的意义在于,无论在何种分辨率的屏幕下,那些针对 ideal viewport 而设计的网站,不需要用户手动缩放,也不需要出现横向滚动条,都可以完美的呈现给用户;
  • layout viewport 表示的是浏览器默认的 viewport,一般情况下这个宽度要大于浏览器可视区域宽度;
  • visual viewport 表示浏览器可视区域的大小。

利用 meta 标签对 viewport 进行控制

viewport 是专为手机浏览器设计的一个 meta 标签,一个简单的示例如下所示:

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

其中,width=device-width 表示此宽度不依赖于原始象素 (px),而依赖于屏幕的宽度。移动设备默认的 viewport 是 layout viewport,也就是那个比屏幕要宽的 viewport,但在进行移动设备网站的开发时,我们需要的是 ideal viewport。我们在开发移动设备的网站时,最常见的的一个动作就是把上面这个东西复制到我们的 head 标签中,它的作用是让当前的 viewport 宽度等于设备宽度,同事不允许用户手动缩放。也许允不允许用户缩放不同的网站有不同的要求,但让 viewport 的宽度等于设备的宽度,这个应该是大家都想要的效果,如果你不这样的设定的话,那就会使用那个比屏幕宽的默认 viewport,也就是说会出现横向滚动条。

这个 name 为 viewport 的 meta 标签到底有哪些东西呢,又都有什么作用呢?meta viewport 标签首先是由苹果公司在其 safari 浏览器中引入的,目的就是解决移动设备的 viewport 问题。后来安卓以及各大浏览器厂商也都纷纷效仿,引入对 meta viewport 的支持,事实也证明这个东西还是非常有用的。在苹果的规范中,meta viewport 有 6 个可以设置的内容:

内容含义
width设置 layout viewport 的宽度,为一个正整数,或字符串 “device-width”
initial-scale设置页面的初始缩放值,为一个数字,可以带小数
minimum-scale允许用户的最小缩放值,为一个数字,可以带小数
maximum-scale允许用户的最大缩放值,为一个数字,可以带小数
height设置 layout viewport 的高度,这个属性对我们并不重要,很少使用
user-scalable是否允许用户进行缩放,值为 “no” 或 “yes”, no 代表不允许,yes 代表允许

这些属性可以同时使用,也可以单独使用或混合使用,多个属性同时使用时用逗号隔开就行了。此外,在安卓中还支持 target-densitydpi 这个私有属性,它表示目标设备的密度等级,作用是决定 css 中的 1px 代表多少物理像素,但作为将要废弃的属性,所以使用中需要避免该用法。我们接下来看看具体的几个用法:

  • width=device-width: 所有浏览器都能把当前的 viewport 宽度变成 ideal viewport 的宽度,但要注意的是,在 iPhone 和 iPad 上,无论是竖屏还是横屏,宽度都是竖屏时 ideal viewport 的宽度。
  • initial-scale=1: 这句代码也能达到和前一句代码一样的效果,也可以把当前的的 viewport 变为 ideal viewport。

要想清楚这件事情,首先你得弄明白这个缩放是相对于什么来缩放的,因为这里的缩放值是 1,也就是没缩放,但却达到了 ideal viewport 的效果,所以,那答案就只有一个了,缩放是相对于 ideal viewport 来进行缩放的。

但如果 width 和 initial-scale=1 同时出现,并且还出现了冲突呢?

<meta name="viewport" content="width=400, initial-scale=1">

width=400 表示把当前 viewport 的宽度设为 400px,initial-scale=1 则表示把当前 viewport 的宽度设为 ideal viewport 的宽度,那么浏览器到底该服从哪个命令呢?是书写顺序在后面的那个吗?不是。当遇到这种情况时,浏览器会取它们两个中较大的那个值。例如,当 width=400,ideal viewport 的宽度为 320 时,取的是 400;当 width=400, ideal viewport 的宽度为 480 时,取的是 ideal viewport 的宽度。(ps: 在 uc9 浏览器中,当 initial-scale=1 时,无论 width 属性的值为多少,此时 viewport 的宽度永远都是 ideal viewport 的宽度)

最后,总结一下,要把当前的 viewport 宽度设为 ideal viewport 的宽度,既可以设置 width=device-width,也可以设置 initial-scale=1,但这两者各有一个小缺陷,就是 iphone、ipad 以及 IE 会横竖屏不分,通通以竖屏的 ideal viewport 宽度为准。所以,最完美的写法应该是,两者都写上去,这样就 initial-scale=1 解决了 iphone、ipad 的毛病,width=device-width 则解决了 IE 的毛病。关于缩放,我们可以得出以下一个式子:

当前缩放值 = ideal viewport宽度 / visual viewport宽度

大多数浏览器都符合这个理论,但是安卓上的原生浏览器以及 IE 有些问题。安卓自带的 webkit 浏览器只有在 initial-scale = 1 以及没有设置 width 属性时才是表现正常的,也就相当于这理论在它身上基本没用;而 IE 则根本不甩 initial-scale 这个属性,无论你给他设置什么,initial-scale 表现出来的效果永远是 1。

好了,现在再来说下 initial-scale 的默认值问题,就是不写这个属性的时候,它的默认值会是多少呢?很显然不会是 1,因为当 initial-scale = 1 时,当前的 layout viewport 宽度会被设为 ideal viewport 的宽度,但前面说了,各浏览器默认的 layout viewport 宽度一般都是 980 啊,1024 啊,800 啊等等这些个值,没有一开始就是 ideal viewport 的宽度的,所以 initial-scale 的默认值肯定不是 1。安卓设备上的 initial-scale 默认值好像没有方法能够得到,或者就是干脆它就没有默认值,一定要你显示的写出来这个东西才会起作用,我们不管它了,这里我们重点说一下 iphone 和 ipad 上的 initial-scale 默认值。

根据测试,我们可以在 iphone 和 ipad 上得到一个结论,就是无论你给 layout viewpor 设置的宽度是多少,而又没有指定初始的缩放值的话,那么 iphone 和 ipad 会自动计算 initial-scale 这个值,以保证当前 layout viewport 的宽度在缩放后就是浏览器可视区域的宽度,也就是说不会出现横向滚动条。比如说,在 iphone 上,我们不设置任何的 viewport meta 标签,此时 layout viewport 的宽度为 980px,但我们可以看到浏览器并没有出现横向滚动条,浏览器默认的把页面缩小了,此时值应为 0.33 左右。

所以总结一下:在 iphone 和 ipad 上,无论你给 viewport 设的宽的是多少,如果没有指定默认的缩放值,则 iphone 和 ipad 会自动计算这个缩放值,以达到当前页面不会出现横向滚动条 (或者说 viewport 的宽度就是屏幕的宽度) 的目的。

JavaScript 动态更改 meta viewport 标签

  • 方法一:可以使用 document.write 来动态输出 meta viewport 标签
document.write('<meta name="viewport" content="width=device-width,initial-scale=1">');
  • 方法二:通过 setAttribute 方法改变
<meta id="testViewport" name="viewport" content="width = 380">
<script>
let mvp = document.getElementById('testViewport');
mvp.setAttribute('content','width=480');
</script>

但是要注意,在安卓 2.3 (或许是所有 2.x 版本中) 的自带浏览器中,对 meta viewport 标签进行覆盖或更改,会出现让人非常迷糊的结果。

总结一下,每个移动设备浏览器中都有一个理想的宽度,这个理想的宽度是指 css 中的宽度,跟设备的物理宽度没有关系,在 css 中,这个宽度就相当于 100% 的所代表的那个宽度。我们可以用 meta 标签把 viewport 的宽度设为那个理想的宽度,如果不知道这个设备的理想宽度是多少,那么用 device-width 这个特殊值就行了,同时 initial-scale=1 也有把 viewport 的宽度设为理想宽度的作用。

为什么需要有理想的 viewport 呢?比如一个分辨率为 320x480 的手机理想 viewport 的宽度是 320px,而另一个屏幕尺寸相同但分辨率为 640x960 的手机的理想 viewport 宽度也是为 320px,那为什么分辨率大的这个手机的理想宽度要跟分辨率小的那个手机的理想宽度一样呢?这是因为,只有这样才能保证同样的网站在不同分辨率的设备上看起来都是一样或差不多的。


via:


图文并茂带你弄懂物理分辨率、分辨率、物理像素、逻辑像素、dpr、ppi

物理分辨率和分辨率

首先得知道物理分辨率分辨率是 2 个概念,可别混淆。

物理分辨率(标准分辨率):显示屏的最佳分辨率,即屏幕实际存在的像素行数乘以列数的数学表达方式,是显示屏固有的参数,不能调节,其含义是指显示屏最高可显示的像素数。

img

我的显示屏的物理分辨率(显示屏最高可显示的像素数)就是 1920×1080,但是分辨率是 1600×900

物理分辨率即 LED 液晶板的实际分辨率,在 LED 液晶板上通过网格来划分液晶体,一个液晶体为一个像素点(物理像素)。

分辨率是可以改变的。分辨率为 1600×900 时,就是指在 LED 液晶板的横向上划分了 1600 个物理像素点,竖向上划分了 900 个物理像素点。如果你换成 1920×1080,那么 LED 液晶板就会横纵向重新划分物理像素点。 物理分辨率越高,则可接收分辨率的范围越大,则显示屏的适应范围越广。通常用物理分辨率来评价 LED 显示屏的档次。

我们把一个个像素点当成小格子,那么下图的分辨率就是 2*4 的分辨率,代表横向 2 个像素点,纵向有 4 个像素点

img

我们经常所说的分辨率 1024*768 就是横向有 1024 个像素点,纵向有 768 个像素点,再细化一点就是输出图像的每一条水平线上包含 1024 个物理像素点,一共有 768 条水平线

很明显,显示相同尺寸的屏幕,肯定是点越多,显示的越精细,效果越好。

那图中这些像素点是什么呢?其实就是物理像素

什么是物理像素

物理像素(physical pixel) 又可以称为设备像素(dp : device pixel)

我们来感受一下这些物理像素点,像一个个小格子,一个个小点,看得很清楚

img

img

再细看每个小点,每一个小像素点都是由三原色 RGB 组成,显示器再控制明暗程度就可以显示想要的效果图案,从定义上来看,像素是指三原色及其灰度的基本编码。

实际的开发是以物理像素为准的吗?

img

这两个手机的宽和高都是一样的,很显然高清屏分辨率 48 比标清屏的 24 要清晰一些

假如实际开发的像素以物理像素为准,我们要显示 1 个像素的东西,结果如下

img

你看到的内容是不一样大的,很显然实际开发不是用物理像素描述的,物理像素只是为了描述设备分辨率需要知道的。实际开发其实是用 CSS 像素描述的。

不管是 PC 端还是移动端,都可以用 screen.width/height 来描述来描述水平和垂直方向的物理像素,即分辨率的水平和垂直方向上的数值。注意:这里分辨率不是物理分辨率。

什么是 CSS 像素

CSS 像素可称为来逻辑像素(logical pixel),也可以称为设备独立像素(dip : device independent pixel)

写 css 的时候,其实用到的就是 css 像素

比如

.box {

width:200px;

height:200px;

}

这里的 px 就是说的 CSS 像素,不是物理像素。那么 CSS 像素和物理像素是什么关系呢?来看下图

img

左边表示标清屏幕,右边表示视网膜高清屏幕

宽和高都是 2 个 CSS 像素,那么在标清屏中需要用 22 个物理像素来显示,即 1 个 CSS 像素用 11 个物理像素来描述

在高清屏需要 44 个物理像素来显示,即 1 个 CSS 像素用 22 个物理像素来描述

高清屏就是显示每个 CSS 像素的物理点变多了,更精细了,看起来就更清晰了。

再来看看最初的例子

img

用 CSS 像素就可以解释上面的例子,手机实际宽和高一样,左边标清屏 1 个 CSS 像素代表 1 个物理像素,右边高清屏 1 个 CSS 像素代表 4 个物理像素。

什么是设备像素比

设备像素比(dpr : device pixel ratio)

dpr = 同一方向上的 物理像素 / CSS 像素 (缩放比是 1 的情况)

同一方向就是指的横向比或者纵向比,后面讲缩放的时候再说为什么计算 dpr 要求缩放比是 1。

还是这张图,来讲解一下 dpr

img

我们以一个方向为例,比如横向

标清屏:dpr = 2 / 2 = 1

高清屏:dpr = 4 / 2 = 2

dpr = 2 表示 1 个 css 像素用 2*2 个设备像素来绘制

console.log (window.devicePixelRatio); 

可以打印 dpr

什么是标清屏和高清屏

dpr 为 1 的就是标清屏,dpr > 1 的就是高清屏,如下图示例

img

dpr 越大,1 CSS 像素表示的物理像素点越多,显示的越精细越清晰,所以会称为高清

缩放

我们看手机经常会用手指去放大图片,看完缩小图片,缩放的是什么?是 CSS 像素,不是物理像素

物理像素是和分辨率的划分有关的,不可能通过编码来改变的

比如我们要放大,如下面 2 张图的示例

img

img

放大之后一个 CSS 像素与多个设备像素重叠

又比如我们要缩小,如下面 2 张图的示例

img

img

缩小之后一个设备像素现在重叠了几个 CSS 像素

缩放之后,缩放比就不为 1 了,所以就不能这样计算 dpr 了,刚刚定义 dpr 的时候说过了,那是缩放比必须是 1 才成立的定义。

什么是 PPI(DPI)

PPI (pixels per inch)就是每英寸的物理像素点,PPI 也可以称为 DPI (dots per inch)

img

每英寸物理像素点越多,密度越大,显示的越精细,类似分辨率,也是来描述像素密度和显示效果的

img

计算,利用勾股定理先算斜边的物理像素,再除以实际尺寸 6.06 英寸就能算出每英寸的物理像素点 PPI 了

img


via:


css 中单位 em 和 rem 的区别

在 css 中单位长度用的最多的是 px、em、rem,这三个的区别是:

px 是固定的像素,一旦设置了就无法因为适应页面大小而改变。

em 和 rem 相对于 px 更具有灵活性,他们是相对长度单位,意思是长度不是定死了的,更适用于响应式布局。

对于 em 和 rem 的区别一句话概括:em 相对于父元素,rem 相对于根元素。

rem 中的 r 意思是 root(根源),这也就不难理解了。

em

  • 子元素字体大小的 em 是相对于父元素字体大小
  • 元素的 width/height/padding/margin 用 em 的话是相对于该元素的 font-size

上代码:

<div>
    我是父元素div
    <p>
        我是子元素p
        <span>我是孙元素span</span>
    </p>
</div>
div {
  font-size: 40px;
  width: 10em; /*400px*/
  height: 10em;
  border: solid 1px black;
}
p {
  font-size: 0.5em; /*20px*/ 
  width: 10em; /*200px*/
  height: 10em;
  border: solid 1px red;
}
span {
  font-size: 0.5em;  
  width: 10em;
  height: 10em;
  border: solid 1px blue;
  display: block;
}

结果如下:

img

巩固测验:你能说出孙元素 span 的 font-size 和 width 吗?

答案:我猜你会说 10px、100px,哈哈,其实逻辑上是正确的,但是如果你是 chrome 浏览器我不得不告诉你应该是 12px、120px。因为 chrome 设置的最小

**字体大小为 12px,意思就是说低于 12px 的字体大小会被默认为 12px,**当然这一尬境可以由 css3 解决,这里就不多说了。

chrome 默认的字体大小是 12px,也就是 1em 默认为 12px,如果最外层的父元素直接把 font-size 设为 1.5em,那么该元素的字体大小为 18px(12*1.5)。

rem

rem 是全部的长度都相对于根元素,根元素是谁? 元素。通常做法是给 html 元素设置一个字体大小,然后其他元素的长度单位就为 rem。

上代码:(html 代码如上,只是把 css 代码的元素长度单位变了)

html {
    font-size: 10px;
    }
div {
    font-size: 4rem; /*40px*/
    width: 30rem;  /*300px*/
    height: 30rem;
    border: solid 1px black;
}
p {
    font-size: 2rem; /*20px*/
    width: 15rem;
    height: 15rem;
    border: solid 1px red;
}
span {
    font-size: 1.5rem;
    width: 10rem;
    height: 10rem;
    border: solid 1px blue;
    display: block;
} 

img

所以你可以说出 span 的 font-size 具体值吗?

当用 rem 做响应式时,直接在媒体中改变 html 的 font-size 那么用 rem 作为单位的元素的大小都会相应改变,很方便。

看到这里我想我们都更深刻的体会了 em 和 rem 的区别(参照物不同)。

总结

在做项目的时候用什么单位长度取决于你的需求,我一般是这样的:

像素(px):用于元素的边框或定位。

em/rem:用于做响应式页面,不过我更倾向于 rem,因为 em 不同元素的参照物不一样(都是该元素父元素),所以在计算的时候不方便,相比之下 rem 就只有一个参照物(html 元素),这样计算起来更清晰。


via:


其他

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值