使用视口元标记实现最小宽度

72
我希望我的网页的视口宽度等于设备宽度,只要设备宽度大于450像素,否则为450像素(我的布局可以动态缩放,但在宽度小于450像素时不太好看)。

以下两个meta标签在平板电脑上效果良好,其中设备宽度 > 450像素:

<!-- uses device width -->
<meta name="viewport" content="width=device-width" />

<!-- use of initial-scale means width param is treated as min-width -->
<meta name="viewport" content="width=450, initial-scale=1.0" />

然而,在手机上(例如设备宽度为320px),前者对于内容来说太细了;而后者会导致浏览器缩放,因此用户必须手动缩小才能看到内容。或者,这个meta标签在手机上效果很好。
<meta name="viewport" content="width=450" />

但是它没有充分利用平板电脑可用的额外宽度。

非常感谢任何帮助/想法(如果有区别的话,我正在使用GWT)。

7个回答

39

所以您想要动态更改 viewport 标签的宽度。

这里是代码:

<meta id="myViewport" name="viewport" content="width = 380">
<script>
window.onload = function () {
    var mvp = document.getElementById('myViewport');
    mvp.setAttribute('content','width=580');
}
</script> 

See:http://www.quirksmode.org/mobile/tableViewport.html


9
这个代码完美地运行了:<script>if (window.innerWidth < 450) { /* 将函数内容放在此之上*/}</script>。这个网页here提供了更多细节,而这个网页 here 则是有关视口的精彩解释。感谢大家的帮助和指引。 - Tom G
1
这个怎么解决问题呢?将视口宽度设置为固定大小并不被解释为最小尺寸!例如,在 iPad 上,不会给网站更多的空间。此外,答案中建议的代码不完整。 - Andy
@Andy 没有人提供完整的项目代码。伪代码对程序员来说足以掌握概念。如果你想要,告诉我一声。我会给你完整的代码。 - Suresh Atta
1
@sᴜʀᴇsʜᴀᴛᴛᴀ 这不是伪代码,而是 JavaScript 代码。它只是不完整,因此不是解决方案。 - Andy
1
请查看我的答案获取完整的代码。我真的不明白隐藏5行代码的意义。此外,在onload之前更改视口是没有必要的。 - CpnCrunch
还要注意,您必须使用screen.width,因为window.innerWidth在iPhone上给出了不正确的值。就我所知,screen.width在所有设备上似乎都能正常工作。 - CpnCrunch

25

试试这个:

<meta id="vp" name="viewport" content="width=device-width, initial-scale=1">
<script>
window.onload = function() {
    if (screen.width < 450) {
        var mvp = document.getElementById('vp');
        mvp.setAttribute('content','user-scalable=no,width=450');
    }
}
</script>

请注意,我已经交换了initial-scale=1,因为我认为你把它搞反了。当width=device-width时,您希望将initial-scale设置为1,以便页面恰好适合窗口大小。当您设置特定的视口宽度时,不要将初始缩放比例设置为1(否则页面将开始缩放)。


您在底部的“注释”是$$,谢谢。 - gmustudent
另外,最近的iOS版本似乎需要使用user-scalable=no,否则有时会忽略或覆盖您设置的宽度。我已经更新了答案。 - CpnCrunch
1
不要使用 user-scalable=no,因为它不可访问(尽管大多数浏览器实际上会忽略它并允许您缩放)。请改用 minimum-scale=1 - Tofandel

5

使用@media标签和CSS。它能够产生神奇的效果。虽然它不能为视口提供最小宽度,但这是首选的方法。

以下是我为视口所做的内容:

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

然后我调整与视口相连的面板的大小:

@media all and (max-width: 1024px) {
    /*styles for narrow desktop browsers and iPad landscape */
       .myContentPanel{
         width: 450;
    }    
}


@media all and (max-width: 320px) {
   /*styles for iPhone/Android portrait*/
      .myContentPanel {
         width: 320;
    }

}

显然,你也可以有中间尺寸...

这里是另一个例子的更多信息


嗨,感谢您的快速回复。我知道媒体查询可以用来改变CSS并改变内容div的大小。但我真的不明白这如何影响视口?例如,我尝试了您建议的方法(删除了视口元标记),但当我在我的手机上查看时(Android),它只是使内容变小,并且周围有很多空白空间。 - Tom G
嗨Tom,看一下修改后的答案。昨晚太晚了...无论如何...我使用CSS来设置面板在视口上的大小(而不是视口本身,它被设置为屏幕大小)。因此,在较小的屏幕上,如果内容不适合,则面板将滚动以显示内容。旋转屏幕时也很好用。 - user1258245
被接受的答案中的JavaScript方法正是我所寻找的(改变视口而不是布局)。谢谢,虽然我之前不知道媒体查询。 - Tom G
但是你接受的答案在Firefox移动版中不起作用,而且谁知道还有哪些其他情况... - jacmkno
@jacmkno 你有没有注意到使用像素时没有“px”后缀?也许这就是原因。 - galva

5
其他回答中给出的JavaScript代码在Firefox中无法正常工作,但是如果您删除meta标签并插入一个新的标签,则它将可以工作。
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
if (screen.width < 450){
    var viewport = document.querySelector("meta[name=viewport]");
    viewport.parentNode.removeChild(viewport);

    var newViewport = document.createElement("meta");
    newViewport.setAttribute("name", "viewport");
    newViewport.setAttribute("content", "width=450");
    document.head.appendChild(newViewport);
}
</script>

或者总是将它插入JavaScript中:

<script>
var viewport = document.createElement("meta");
viewport.setAttribute("name", "viewport");
if (screen.width < 450) {
    viewport.setAttribute("content", "width=450");
} else {
    viewport.setAttribute("content", "width=device-width, initial-scale=1");
}
document.head.appendChild(viewport);
</script>

为了我的健康,我编写了一个polyfill,只需向viewport meta标签添加min-width属性:

在viewport metatag中设置min-width

使用这个方法,你只需要这样做:

<meta name="viewport" content="width=device-width, initial-scale=1.0, min-width=450" />
<script type="text/javascript" src="viewport-min-width.js"></script>

1
你应该在页面中始终包含 viewport meta(例如1),因为 Google 不喜欢它缺失(例如2)。 - Rauli Rajande

1
简而言之,在视口上设置min-width是没有必要的,因为你可以在bodyhtml元素上进行设置,使它们及其内容比视口更宽。用户将能够滚动或缩小内容。
body {
  min-width: 450px;
}

我在Android Chrome上进行了一些测试,如果视口宽度设置为除device-width之外的任何值,则会缩放某些元素的字体。此外,shrink-to-fit=yes有助于使页面最初缩小。最后,这种方法支持桌面浏览器,这些浏览器可能具有奇怪的窗口大小或当前缩放设置(两者都会影响报告的视口尺寸),但不遵守视口meta标记。

1
扩展@Brendan和其他人的答案。视口大小不会在方向(纵向、横向)改变时自动调整。为了解决这个问题,在方向改变时添加一个事件监听器并再次调整大小。
<script>
      const resize = () => {
        if (screen.width < 450) {
          var viewport = document.querySelector("meta[name=viewport]");
          viewport.parentNode.removeChild(viewport);
    
          var newViewport = document.createElement("meta");
          newViewport.setAttribute("name", "viewport");
          newViewport.setAttribute(
            "content",
            "width=450, maximum-scale=1.0, user-scalable=no"
          );
          document.head.appendChild(newViewport);
        }
      };
      resize();
      window.addEventListener("orientationchange", resize);
</script>

-2

我刚刚移除了initial-scale=1,现在在Android Chrome和内置浏览器上完美运行。不再出现意外的缩放了!:)

<meta name='viewport' content='width=device-width'>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接