viewport概念

本文详细介绍了移动设备上的viewport概念,包括layoutviewport、visualviewport和idealviewport,并探讨了如何通过meta标签来控制viewport,以实现idealviewport。讨论了initial-scale的缩放原理及其默认值,以及如何解决JavaScript延迟问题,特别是与用户缩放相关的300ms延迟。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. viewport概念

移动设备上的viewport就是**设备的屏幕上能用来显示网页内容的区域。**viewport不局限于浏览器可视区域的大小,可能比浏览器的可视区域大,也可能小。默认情况下,移动设备上的viewport大于浏览器可视区域,原因:考虑到移动设备的分辨率相对于桌面电脑来说都比较小,所以为了能在移动设备上正常显示传统为桌面浏览器设计的网页,移动设备上的浏览器都会把自己默认的viewport设为980px或1024px,但是结果可能是浏览器出现横向滚动条。

一些设备浏览器默认viewport宽度

media_01.png

1.1 PPK对关于三个viewport的理论

​ PPk认为,移动设备上有三个viewport

  • layout viewport

    如果把移动设备上浏览器的可视区域设为viewport的话,某些网站就会因为viewport太窄而显示错乱,所以这些浏览器就决定默认情况下把viewport设为一个较宽的值比如980px,这样的话,即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。PPK把这个浏览器默认的viewport叫做layout viewport

    可以通过document.documentElement.clientWidth来获取

  • visual viewport

    layout viewport宽度大于浏览器可视区域的宽度的,所以还需要一个viewport来代表浏览器可视区域的大小,ppk称为visual viewport

  • ideal viewport

    一个完美的适配移动设备的viewport称为ideal viewport 完美适配值得是:1. 不需要用户缩放和横向滚动条就能正常查看网站的所有内容。2. 显示的文字的大小是合适。

    ideal viewport没有一个固定的尺寸,不同设备拥有不同的idea viewport,作为最适合移动设备的viewport,ideal viewport的宽度等于移动设备的屏幕宽度,只要在css中把某一元素的宽度设为ideal viewport的宽度,那么这个元素的宽度就是设备屏幕的宽度。

1.2 查看viewport尺寸

主流浏览器的默认viewport大小

浏览器尺寸
Safari iPhone980px
Opera850px
Android WebKit800px
IE974px

viewport_01.png

1.3 利用meta标签对viewport进行控制

移动设备默认的viewport是layout viewport,也就是那个比屏幕要宽的viewport,但在进行移动设备网站的开发时,我们需要的是ideal viewport。那么怎么才能得到ideal viewport呢?这就该轮到meta标签出场了。

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

该meta标签的作用是让当前viewport的宽度等于设备的宽度,同时不允许用户手动缩放.如果你不这样的设定的话,那就会使用那个比屏幕宽的默认viewport,也就是说会出现横向滚动条。

这个name为viewport的meta标签到底有哪些东西呢,又都有什么作用呢?

meta viewport 标签首先是由苹果公司在其safari浏览器中引入的,目的就是解决移动设备的viewport问题。后来安卓以及各大浏览器厂商也都纷纷效仿,引入对meta viewport的支持,事实也证明这个东西还是非常有用的。

属性值

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

此外,在安卓中还支持 target-densitydpi 这个私有属性,它表示目标设备的密度等级,作用是决定css中的1px代表多少物理像素

属性值说明
target-densitydpi值可以为一个数值或 high-dpi 、 medium-dpi、 low-dpi、 device-dpi 这几个字符串中的一个
1.4 设置viewport为ideal viewport中几种方式
  • 设置width

    <meta name=“viewport” content=“width=device-width”>

    所有浏览器都能把当前的viewport宽度变成ideal viewport的宽度,但要注意的是,在iphone和ipad上,无论是竖屏还是横屏,宽度都是竖屏时ideal viewport的宽度。

  • 设置缩放initial-scale

    <meta name=“viewport” content=“initial-scale=1”>

    缩放是相对于ideal viewport来进行缩放的,当对ideal viewport进行100%缩放的时候,也就是缩放值为1,也就是当前大小为ideal viewport。

    但是windows phone 上的IE 无论是竖屏还是横屏都把宽度设为竖屏时ideal viewport的宽度。

  • 同时设置width和initial-sacle

    <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的宽度。

最完美的写法应该是,两者都写上去,这样就 initial-scale=1 解决了 iphone、ipad的毛病,width=device-width则解决了IE的毛病。

1.5 initial-scale缩放方式以及默认值

缩放是相对于ideal viewport来缩放的,缩放值越大,当前viewport的宽度就会越小,反之亦然。例如在iphone中,ideal viewport的宽度是320px,如果我们设置 initial-scale=2 ,此时viewport的宽度会变为只有160px了,也就是放大了一倍,原来1px的东西变成2px了,但是1px变为2px并不是把原来的320px变为640px了,而是在实际宽度不变的情况下,1px变得跟原来的2px的长度一样了,所以放大2倍后原来需要320px才能填满的宽度现在只需要160px就做到了。

所以:

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

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

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

而initial-scale默认值不一定为1。原因:当为1的时候是ideal viewport宽度,但是一般浏览器都是layout viewport宽度,也即980 1024等,所以如果要达到ideal viewport需要自己去设置。

1.6 解决JS延迟问题

设置 user-scalable=no 时可以解决js300延迟的问题,你也可以理解为当设置 user-scalable=yes 时,系统要识别两只手指,所以要有个宽容时间。

假设允许缩放,也即存在300ms延迟

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=yes" />
</head>
<body>
<style>
    body {
        width: 100vw;
        height: 100vh;
    }
</style>
<script>
  let i = 1
  document.body.addEventListener('click', () => console.log(i++))
</script>
</body>
</html>

可以看出,第一次进行了打印,当多次点击进行缩放时,由于有宽容时间,所以并没有立即打印,而是等待了一会儿才打印

viewport_02.gif

假设允许缩放,不存在300ms延迟

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0,user-scalable=no" />
</head>
<body>
<style>
    body {
        width: 100vw;
        height: 100vh;
    }
</style>
<script>
  let i = 1
  document.body.addEventListener('click', () => console.log(i++))
</script>
</body>
</html>

可以看出,此时连续点击,直接打印,而不会延迟等待

viewport_03.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值