小编典典

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

css

我试图弄清楚,即使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


阅读 929

收藏
2020-05-16

共1个答案

小编典典

元素仍然是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声明,则看到的滚动条将改为属于视口。但是,如果放置身体,滚动条仍属于身体,但是元素也成为身体的子元素,因此它不会与滚动条重叠。

2020-05-16