当前位置: 首页 > 面试题库 >

为什么overflow-x:hidden使我的绝对定位的元素变得固定?

隗嘉歆
2023-03-14
问题内容

我试图弄清楚,即使overflow-x: hidden将HTML页面的主体设置为,为什么将其设置为HTML页面的主体也会使我的元素成为现实。position: fixed``position: absolute

在此演示中可以更好地理解效果。

这是代码:

html,

body {

  width: 100%;

  height: 100%;

  padding: 0;

  margin: 0;

  overflow-x: hidden;/* If I remove this line everything is how I expect it to be! */

}



div.page {

  position: relative;

  width: 100%;

  height: 100%;

  min-height: 100%;

  border: 1px solid red;

  margin-bottom: 200px;

}



div.background {

  background: blue;

  position: absolute;

  width: 100%;

  height: 10%;

}


<div class='background'></div>

<div class='page'></div>

<div class='page'></div>

<div class='page'></div>

<div class='page'></div>

overflow-x: hidden和定位之间是什么关系?为什么设置该属性会导致我的元素变为position: fixed而不是position: absolute


问题答案:

元素仍然是position: absolute,但是由于和框模型之间的一些相当复杂的交互position,它看起来是固定的overflow。令人难以置信的是,这些行为都不是未指定的,也不是任何浏览器中的错误-
实际上,这完全是设计使然,即使有些违反直觉。

基本上可以归结为以下几点:

  • 除非将其绝对祖先定位,否则将绝对定位的元素锚定到初始包含块。(这就是为什么添加position: relative到body可以如另一个答案中所建议的那样。)

  • 您同时拥有width: 100%; height: 100%;html和body;这样可以防止初始包含块扩展到视口(可见区域)之外,因此初始包含块永远不会滚动。

  • 由于初始包含块不会滚动,因此绝对定位的元素也不会滚动。即使页面的其余部分确实滚动,这也会导致它看起来固定。

奇怪的是,这也适用于IE6。

更长的解释:

  • 除非将其绝对祖先定位,否则将绝对定位的元素锚定到初始包含块。

关于属性的规范overflow,其中附带包含您正在观察的同一问题的另一个示例,其中与的元素在overflow: scroll与绝对定位的后代元素进行交互时,声明如下:

此属性指定块容器元素的内容溢出元素框时是否被裁剪。它会影响所有元素内容的剪辑,但其包含块是该元素的视口或祖先的任何后代元素(及其各自的内容和后代)除外。

您绝对定位的元素是其后代,其后继包含块是初始包含块(也是html元素的包含块),因为html和body均未定位。这是根据规范的另一部分。这可以防止html和body上的溢出剪切对绝对定位的元素产生任何影响,因为它已锚定到初始包含块。

  • 您同时拥有width: 100%; height: 100%;html和body;这样可以防止初始包含块扩展到视口(可见区域)之外,因此初始包含块永远不会滚动。

然后,规格说明了以下内容,在同一部分的下方:

UA必须将在根元素上设置的“溢出”属性应用于视口。当根元素是HTML“ HTML”元素或XHTML“ html”元素,并且该元素具有HTML“
BODY”元素或XHTML“ body”元素作为子元素时,用户代理必须改为应用’overflow’属性如果根元素上的值是“
visible”,则从第一个此类子元素到视口。用于视口的“可见”值必须解释为“自动”。从中传播值的元素必须具有“可见”的“溢出”使用的值。

简单地说:

* 如果不是html `overflow: visible`,请将其应用于视口,然后将html转到`overflow: visible`。`overflow`赋予body 的值不受影响。

* 如果html是`overflow: visible`,但body不是,则将其应用于视口,然后将body转到`overflow: visible`。

(设定overflow-xoverflow-y比其他任何visible一个元件使所述速记overflow不再等于visible该元素)。

通常,这意味着视口应该与html和body一起自然滚动,因为一次只能存在一个滚动条。

但是…
您还同时给html和body设置了宽度和高度为100%!这意味着其容器的100%。body的容器是html,而html的容器是初始包含块。但是,由于实际上不能使用CSS控制视口的大小(完全由浏览器处理),因此剩下的两个元素被限制为视口高度的100%(也称为折叠)。视口本身不必扩展到折叠之外,因为它的内容都不需要比可见空间更多的空间(请注意,绝对不会考虑绝对定位的元素)。因此,视口不会生成滚动条(html也不会生成)。您看到的滚动条属于主体。

如果未设置widthheight属性,则它们将默认设置为auto,从而导致html和body都随其内容扩展,并且大小始终与初始包含块所覆盖的整个区域相同,包括折叠以下的区域。这样可以防止主体生成滚动条,因为它始终会拉伸以适合其内容,因此您只能看到视口滚动条,并且绝对定位的元素将与页面的其余部分一起滚动。

  • 由于初始包含块不会滚动,因此绝对定位的元素也不会滚动。 即使页面的其余部分确实滚动,这也会导致它看起来固定。

滚动时会发生什么,就是您实际上在滚动body元素。由于绝对定位的元素锚定在永远不会滚动的初始包含块上,因此它似乎是固定的而不是滚动。

顺便说一句,这也是为什么当元素根本不滚动时该元素看起来与滚动条重叠的原因。滚动条属于主体,它位于绝对定位的元素下方。如果从html和body中删除overflow-x声明或widthand
height声明,则看到的滚动条将改为属于视口。但是,如果放置身体,滚动条仍属于身体,但是元素也成为身体的子元素,因此它不会与滚动条重叠。



 类似资料:
  • 问题内容: 我只是在学习CSS的定位。基于我发现有用的文章,我开始玩转。 使用以下代码,我无法理解为什么绝对灰盒div不在其相对父级之外。我希望灰色框位于容器的左上角。 在以下情况下,也无法理解为什么灰色框不在左上角,而是在橙色框留下的空白处之后移动。我刚刚将灰色框移到了容器div中的第二位。 我发现的所有详细文档(例如MDN)和教程仅演示了2-3个框的非常简单的示例。 问题答案: 为了正确理解这

  • 问题内容: 这是我要完成的工作: 我需要一个按钮,该按钮与div的右侧保持一定距离,并且无论视口的大小如何,该按钮始终与div的侧面保持相同的距离,但是会随窗口滚动。 因此,始终是div右侧的x像素,而始终是视口顶部的y像素。 这可能吗? 问题答案: 水平放置固定元素(基于另一个元素) ( 免责声明 :此处提供的解决方案在技术上并非如问题标题所述为“绝对水平 ”,而是实现了OP最初想要的功能,固定

  • 问题内容: 我发现当我固定一个元素固定的位置时,父元素是否相对放置都没关系,它相对于窗口的位置是否固定? CSS HTML 问题答案: 让我为两个可能的问题提供答案。请注意,您现有的标题(和原始帖子)提出的问题与您在编辑和后续评论中寻求的问题不同。 要将元素相对于父元素“固定”放置,您需要在子元素上,并且要在 父元素 上使用默认或静态以外的任何位置模式。 例如: 这将相对于parentDiv的位置

  • 问题内容: 我有一个名为.side-el的div,我希望该位置为:fixed; 行为,但是一旦我将位置固定后,宽度就会从右边的位置开始交替变化。正确的宽度将是flexbox设置的宽度。我怎样才能实现这个目标? 问题答案: 这是一种受引导启发的方法: 这给您的伸缩盒空间提供了呼吸,这是伸缩盒的工作。如果弹性方向是列,则可以改用。 之所以起作用,是因为当您为元素提供固定位置并且a 和0或a top和b

  • 经常看到绝对定位元素有一个空的div包着,其实是可以省略的,为什么这么写?,这么做是为了什么? 下面是例子 https://ant.design/components/modal-cn https://robertsspaceindustries.com/starmap

  • 问题内容: SO上有很多问题涵盖了如何解决此问题的答案(添加),但没有一个试图真正解释标题运动背后的原因。我更奇怪为什么会这样。 可以认为固定标头停留在浏览器窗口的顶部,并且不应由于另一个未定位,非子,非父div(又称为同级)而移动。Esp。因为固定的标头不在正常的文档流中。 假设: 混淆源于固定元素是相对于浏览器窗口的想法。这是正确的,但是是使用视口计算的。视口是使用常规文档流中的元素计算的。由