还设置了"Initial-Scale=1.0"时,从视口元标记中删除"width=Device-Width&Quot;的副作用

2022-06-16 00:00:00 css meta-tags viewport meta

虽然<meta name="viewport">标签不是标准化的,但它"由于事实上的支配地位而受到大多数移动浏览器的尊重"。

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

我的主要问题是:

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

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

或者问,这两个@viewportcss 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状态:

widthheight视区<META>属性被转换为widthheight描述符,min-width/min-height值设置为extend-to-zoommax-width/max-height值为视区的长度。

他们还给出了一个example:

<META>元素:

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

翻译为:

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

width shorthand descriptor描述为:

这是同时设置min-widthmax-width的速记描述符。一个<viewport-length>值将同时将min-widthmax-width设置为该值。两个<viewport-length>值将min-width设置为第一个值,max-width设置为第二个值。

因此,width: extend-to-zoom 500px;等同于min-width: extend-to-zoom; max-width: 500px;是顺理成章的。

只剩下100vw部分。在section 10.4中,它们解释:

device-widthdevice-height分别转换为100vw和100vh

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

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

这是verbatim example:

<META>元素:

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

翻译为:

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

我这里的另一个问题是值到底是什么?

documentation on it及其resolution procedure很难掌握。如果有人能在这方面给我一些进一步的例子,我们将不胜感激。


除了上面的所有内容,我还创建了一个快速站点https://romellem.github.io/temp-site/viewport/-来测试一些视窗配置。

即:

  • content="width=device-width, initial-scale=1.0"
  • content="initial-scale=1.0"

这可能有助于测试。


解决方案

在深入了解您的问题之前,让我们先回顾一下viewport元标记最初存在的原因。以下是我收集到的信息。


为什么需要viewport标记?

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

狭小的视窗对于设计为美观的文档来说是个问题 在桌面浏览器中。其结果是移动浏览器供应商使用 固定的初始包含块大小不同于 视区大小,接近典型桌面浏览器窗口的大小。 除了滚动或平移之外,还经常使用缩放来更改 在概述文档和放大特定区域之间 要阅读并与之交互的文档。

在移动设备(和其他较小的设备)中,initial containing block通常大于视区。例如,屏幕宽度为640px的移动设备的初始包含块可能为980px。在这种情况下,初始的包含块被缩小到640px,以便它可以适合移动屏幕。此640px宽度(屏幕宽度)是与我们的讨论相关的视区的initial-width

所以...为什么我们需要这个viewport标记?现在,我们有media queries,它允许我们为移动设备进行设计。但是,此媒体查询取决于实际视区的宽度。在移动设备中,用户代理自动将初始视区大小设置为不同的固定大小(通常大于初始视区大小)。因此,如果移动设备的视区宽度是固定的,我们在媒体查询中使用的css规则将不会被执行,因为视区的宽度永远不会改变。使用viewport标记,可以控制实际视区的宽度(在由UA设置样式后)。Quoted from MDN:

然而,对于使用媒体查询针对窄屏幕进行优化的页面,这种机制就不太好了-例如,如果虚拟视区是980px,则永远不会使用640px或480px或更低的媒体查询,从而限制了此类响应式设计技术的有效性。

请注意,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

您的问题是扩展到缩放的确切值是什么?从我收集的信息来看,它是用于支持视区自身扩展以适应给定缩放级别的查看区域的值。换句话说,它是根据指定的缩放值更改的视区大小值。举个例子?假设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和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之后(即extend-to-zoom)max-widthmin-width的值。我们可以继续the next procedure。因为min-widthmax-width不是auto,所以我们将在程序中使用第一个if,从而将初始的实际视点width设置为MAX(min-width, MIN(max-width, initial-width)),相当于MAX(640, MIN(640, 640))。这将解析为初始实际视区的640width
  • 转到the next procedure。在本步骤中,width不是auto。值不变,我们最终得到的实际视区width640px

让我们选择前者。

  • width被设置,这将导致max-width100%(在我们的情况下为640px),并且min-width@viewport规则中。
  • initial-scale1.0。这意味着zoom值也是1.0
  • 让我们resolve extend-to-zoom。如果您仔细执行这些步骤(几乎与上面相同),您将得到max-width640pxmin-width640px
  • 你现在大概可以看到这个模式了。我们将得到640px的实际视区宽度。

那么感知到的差异是什么?基本上没有。他们两个都做着同样的事情。希望我的解释能帮上忙;-)如果有什么不对劲的地方,一定要告诉我。

相关文章