Width:100%和width:100vw之间有什么区别?

85
我需要将一个 iframe 适配到屏幕高度。显然,我想在宽度上使用 100%,但由于这不起作用,所以我使用了 100vh。 但是 vh 像 vw 一样并不完全等于 100%。 在我的笔记本电脑上通过 Chrome 渲染时,100% 的宽度可以完美呈现,而 vw 多出了约一厘米的宽度,需要水平滚动条才能显示完整。

1
顺便提一下,对于高度而言,在某些移动浏览器中,100vh > 100%,这曾经困扰过我。 - Rick
5个回答

153

vw和vh分别代表视口宽度和视口高度。

使用width: 100vw而不是width: 100%的区别在于,100%会使元素适应所有可用空间,而视口宽度具有特定的度量标准,在这种情况下为可用屏幕的宽度,包括文档边距。

如果设置样式body { margin: 0 },则对于一个作为body子元素的元素,100vw应该与100%行为相同。

附加说明

在您的网站中将vw作为单位用于所有内容,包括字体大小和高度,将使得该网站始终按比例显示到设备屏幕宽度,无论其分辨率如何。这使得确保您的网站在工作站和移动设备上完全一致变得非常容易。

您可以在body CSS中设置font-size: 1vw(或适合您项目的任何大小),并且以rem为单位指定的所有内容都将根据设备屏幕自动缩放,因此很容易将现有项目甚至框架(例如已经使用rem作为单位的Bootstrap)转换为此概念。


32
请注意,width: 100% 是相对于具有布局的第一个父元素而言的。因此,如果您在具有特定宽度的另一个元素内部具有 width: 100% 的元素,则子元素仅会占用该父元素的总宽度。 - Reinier Kaper
14
我注意到将一个元素设置为100vw会在垂直滚动条可见时导致水平滚动条出现。根据Can I use的数据,只有Firefox能通过从100vw中减去滚动条宽度来表现正确。对于其他浏览器,你需要使用100% - Nolonar
2
这是不正确的。当前编辑草案文档规定,视口长度必须忽略滚动条,而MDN另外记录在overflow设置为auto时才会生效;如果overflow设置为scroll(始终显示滚动条),则视口长度会考虑滚动条(我自己没有在草案中看到)。 100%是指父元素而不是视口本身,并且在任何情况下都不会忽略滚动条。 - Kissaki
2
据我所见,边距的区分是错误的。当我将子元素设置为100%宽度或100vw宽度,并从body中添加或删除边距时,它们的行为方式相同。 - Kissaki
2
"100vw应该和100%一样,除非右侧出现了滚动条。" - Metatron5

60

Havenard的答案似乎并不严格正确。我发现vw填充了视口宽度,但没有考虑滚动条。因此,如果您的内容比视口更高(使您的站点具有垂直滚动条),则使用vw会导致小的水平滚动条。我必须将width: 100vw 替换为 width: 100%以去掉水平滚动条。


3
当使用100vw作为CSS属性时,如果同时存在多个元素,则可能出现水平溢出问题。该属性意味着元素的宽度应等于视口的宽度。解决此问题的一种方法是在具有100vw属性的元素上添加overflow-x: hidden,以防止水平滚动条的出现。 - Eli

7
你可以通过添加max-width来解决这个问题:
#element {
   width: 100vw;
   height: 100vw;
   max-width: 100%;
}

当你使用 CSS 代码 width: 100vw; 来让包装器全宽时,你会发现页面出现了水平滚动条,这是因为 htmlbody 标签的 paddingmargin 会增加包装器的尺寸,解决方法是添加 max-width: 100%


请问您能描述一下这个问题吗? - corn on the cob
当您使用CSS使用代码width: 100vw;使包装器全宽时,您会注意到页面上出现了水平滚动条,这是因为htmlbody标签的填充和边距添加到了包装器大小中,因此解决方案是添加max-width: 100% - Tahseen Alaa

2

@Havenard的回答为这个问题提供了完美的解释。此外,这还提供了一个差异的可视化表示。

当您拥有带有滚动条和一个应该适合屏幕整个宽度的元素的站点时,您将能够注意到100vw100%之间的关键区别。

选项1

下面是同样的一个例子。
在下面的代码中,我所做的一切就是在悬停时将<h1>标签的宽度从100vw更改为100%

body {
  /* margin: 0; */
}

.scroll {
  height: calc(110vh);
}

h1 {
  width: 100vw;
  /* width: 100%;*/
  text-align: right;
  outline: 5px solid black
}

h1:hover {
  width: 100%;
}

h1:before {
float: left;
  content: "100vw "
}

h1:hover:before {
  content: "100% "
}
<div class="scroll">
  <p>Hover over the below block</p>
  <h1>Width</h1>
</div>

如果运行以上代码片段并将鼠标悬停在文本上,您会注意到两件事情:
  1. 水平滚动条消失了
  2. 整个文本将对您可见
注意:在运行上述片段后,您可以在浏览器 devtools 中玩弄以上代码,以查看它如何影响元素。

选项2(Chrome和Edge

.scroll{
height: calc(110vh);
display: flex;
align-items: baseline;
}

h1{
width: 100vw;
/* width: 100%; */
text-align:right;
outline: 10px solid black
}
<div class="scroll">
    <h1>Test</h1>
  </div>

另一种在您自己的项目中直观地看到差异的方法是将display:flex样式设置为具有100vw的元素。

当您在浏览器开发工具中突出显示这些元素时,您会注意到元素右端有一个向左箭头。此外,您还可以看到突出显示的元素的阴影跨越滚动条,表明它正在考虑整个屏幕宽度(包括滚动条宽度)。

100vw vs 100% visual difference


其他与此问题类似的问题包括:

  1. 100vw 会导致水平溢出,但只在超过一个时出现?
  2. CSS 单位 - vh/vw 和 % 有什么区别?
  3. 防止 100vw 造成水平滚动条

0

body {
  /* margin: 0; */
}

.scroll {
  height: calc(110vh);
}

h1 {
  width: 100vw;
  /* width: 100%;*/
  text-align: right;
  outline: 5px solid black
}

h1:hover {
  width: 100%;
}

h1:before {
float: left;
  content: "100vw "
}

h1:hover:before {
  content: "100% "
}
<div class="scroll">
  <p>Hover over the below block</p>
  <h1>Width</h1>
</div>


1
你应该添加解释。 - Super Kai - Kazuya Ito

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