当还设置 "initial-scale=1.0" 时从视口元标记中删除 "width=device-width" 的副作用

Side effects of removing "width=device-width" from viewport meta tag when "initial-scale=1.0" is also set

虽然 <meta name="viewport"> 标签未标准化,但 "is respected by most mobile browsers due to de-facto dominance."

它不是真正的 Web 标准的一个缺点是详细文档不像其他标准那样可用。 CSS Working Group有这方面的规范,所以我主要是用这个作为权威著作。

我的主要问题是:

以下声明之间的感知差异是什么?

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="viewport" content="initial-scale=1.0">

换句话说,这两个@viewport CSS at-rules有什么区别:

/* Translated from <meta name="viewport" content="width=device-width, initial-scale=1.0"> */
@viewport {
    zoom: 1.0;
    min-width: extend-to-zoom;
    max-width: 100vw;
}
/* Translated from <meta name="viewport" content="initial-scale=1.0"> */
@viewport {
    zoom: 1.0;
    min-width: extend-to-zoom;
    max-width: extend-to-zoom;
}

我是如何得出那些 @viewport 翻译的:

width=device-widthmin-width: extend-to-zoom; max-width: 100vw;

CSS Device Adaptation Module Level 1 document 状态:

The width and height viewport <META> properties are translated into width and height descriptors, setting the min-width/min-height value to extend-to-zoom and the max-width/max-height value to the length from the viewport.

他们还给出了 example:

This <META> element:

<meta name="viewport" content="width=500, height=600">

translates into:

@viewport {
    width: extend-to-zoom 500px;
    height: extend-to-zoom 600px;
}

width shorthand descriptor描述为:

This is a shorthand descriptor for setting both min-width and max-width. One <viewport-length> value will set both min-width and max-width to that value. Two <viewport-length> values will set min-width to the first and max-width to the second.

所以按理说width: extend-to-zoom 500px;等价于min-width: extend-to-zoom; max-width: 500px;.

那只剩下 100vw 部分了。在 section 10.4 内,他们解释说:

device-width and device-height translate to 100vw and 100vh respectively

所以我们终于可以看到 width=device-width 是如何翻译成 min-width: extend-to-zoom; max-width: 100vw; 的。

initial-scale=1.0zoom: 1.0; width: extend-to-zoom;

这个是 verbatim example:

This <META> element:

<meta name="viewport" content="initial-scale=1.0">

translates into:

@viewport {
    zoom: 1.0;
    width: extend-to-zoom;
}

我这里的另一个问题是, 究竟是什么 extend-to-zoom 值?

documentation on it and its resolution procedure 很难掌握。如果有人能指出我关于这方面的更多示例,将不胜感激。


除了上述所有内容之外,我还建立了一个快速站点 - https://romellem.github.io/temp-site/viewport/ - 用于测试一些视口配置。

即:

这可能有助于测试。

在我们深入研究您的问题之前,让我们首先回顾一下 viewport 元标记存在的原因。这是我收集的。


为什么我们需要 viewport 标签?

视口是可以看到 Web 内容的区域。通常,呈现的页面(网页内容)比视口大。因此,我们通常使用滚动条来查看隐藏的内容(因为视口无法显示所有内容)。 Quoted from CSS Device Adaptation Module Level 1:

The narrow viewport is a problem for documents designed to look good in desktop browsers. The result is that mobile browser vendors use a fixed initial containing block size that is different from the viewport size, and close to that of a typical desktop browser window. In addition to scrolling or panning, zooming is often used to change between an overview of the document and zoom in on particular areas of the document to read and interact with.

在移动设备(和其他较小的设备)中,视口的 initial containing block is usually larger than the viewport. For example, a mobile device that has a screen width of 640px might have an initial containing block of 980px. In this case, the initial containing block is shrunk to 640px so that it can be fit into the mobile screen. This 640px width (screen width) is what is called initial-width 将与我们的讨论相关。

所以....为什么我们需要这个 viewport 标签?那么,现在,我们有 media queries which allows us to design for mobile devices. However, this media query depends on the actual viewport's width. In mobile devices, the user agent automatically styles the initial viewport size to a different fixed one (usually larger than the initial viewport size). So if the viewport's width of a mobile device is fixed, the CSS rules we use in media queries won't be executed simply because the viewport's width never changes. Using the viewport tag, we can control the actual viewport's width (after being styled by the UA). Quoted from MDN:

However, this mechanism is not so good for pages that are optimized for narrow screens using media queries — if the virtual viewport is 980px for example, media queries that kick in at 640px or 480px or less will never be used, limiting the effectiveness of such responsive design techniques.

请注意,viewport 标签也可以更改实际视口的高度,而不仅仅是宽度


viewport 标签的 width

viewport 标签中的 width 被翻译成 @viewport 规则中的 max-width。当您将 width 声明为 device-width 时,它会在 @viewport 规则中转换为 100%Percentage value是根据视口的initial-width解析的。因此,如果我们仍然使用上面的示例,max-width 将解析为 640px 的值。正如您所发现的,这仅指定了 max-widthmin-width 将自动为 extend-to-zoom


extend-to-zoom

您的问题是 extend-to-zoom 的值到底是什么?根据我收集到的信息,它是用于支持视口扩展自身以适应给定缩放级别的查看区域的值。换句话说,它是根据指定的缩放值更改的视口大小值。一个例子?鉴于 UA 样式表的 max-zoom 值为 5.0initial-width320px<meta name="viewport" content="width=10"> 将解析为初始实际宽度 64px.这是有道理的,因为如果一个设备只有 320px 并且只能缩放 5x 正常值,那么最小视口大小将是 320px divided by 5,这意味着一次只能显示 64px(而不是 10px,因为那需要放大 32 倍!)。算法将使用此值来确定如何扩展(更改)min-widthmax-width 值,这将在确定实际视口宽度方面发挥作用。


综合起来

所以本质上,<meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="viewport" content="initial-scale=1.0"> 之间有什么区别?只需重做算法的步骤 (this and this)。让我们先做后者(没有 width 属性的那个)。 (我们假设视口的 initial-width640px。)

  • width 未设置,这导致 max-widthmin-width@viewport 规则中成为 extend-to-zoom
  • initial-scale1.0。这意味着 zoom 值也是 1.0
  • 让我们resolve extend-to-zoom。脚步:
    1. extend-zoom = MIN(zoom, max-zoom)MIN 操作解析为非 auto 的值。这里,zoom1.0max-zoomauto。这意味着 extend-zoom1.0
    2. extend-width = initial-width / extend-zoom。这很容易;将 640 除以 1。您得到 extend-width 等于 640
    3. 因为extend-zoom是非auto,我们将跳到第二个条件。 max-width 确实是 extend-to-zoom,这意味着 max-width 将被设置为 extend-width。因此,max-width = 640
    4. min-width也是extend-to-zoom,意思是把min-width设置为max-width。我们得到 min-width = 640
  • resolving the non-auto (i.e. the extend-to-zoom) values for max-width and min-width. We can proceed to the next procedure 之后。因为 min-widthmax-width 不是 auto,我们将在程序中使用第一个 if,从而将初始实际视口 width 设置为 MAX(min-width, MIN(max-width, initial-width)),相当于 MAX(640, MIN(640, 640))。对于您的初始实际视口 width
  • ,这将解析为 640
  • 继续 the next procedure。在这一步中,width 不是 auto。该值未更改,我们最终得到 640px
  • 的实际视口 width

让我们做前者。

  • width 已设置,这导致 max-width100%(在我们的例子中为 640px)并且 min-widthextend-to-zoom @viewport 规则。
  • initial-scale1.0。这意味着 zoom 值也是 1.0
  • 让我们resolve extend-to-zoom。如果你仔细按照步骤(几乎与上面相同),你最终会得到 640pxmax-width640px.
  • min-width
  • 你现在大概可以看出规律了。我们将得到 640px.
  • 的实际视口宽度

那么感知差异是什么? 本质上none。他们两个做同样的事情。希望我的解释对您有所帮助 ;-) 如果有任何不妥,请告诉我。