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

dri*_*hev 5 html css

我想弄清楚,为什么设置overflow-x: hidden到一个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%;
}
Run Code Online (Sandbox Code Playgroud)
<div class='background'></div>
<div class='page'></div>
<div class='page'></div>
<div class='page'></div>
<div class='page'></div>
Run Code Online (Sandbox Code Playgroud)

什么是关系overflow-x: hidden和定位?为什么设置该属性的事业我的元素,成为position: fixed替代position: absolute

Bol*_*ock 23

元素仍然存在position: absolute,但由于框架模型之间的一些相当复杂的交互position,它似乎是固定的overflow.令人难以置信的是,这些行为中没有一个是未指定的或任何浏览器中的错误 - 它实际上完全是设计的,如果有点违反直觉.

它基本归结为以下内容:

  • 除非定位任何祖先,否则绝对定位的元素将锚定到初始包含块.(这就是为什么在另一个答案中建议添加position: relative到身体的工作原因.)

  • 你有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"元素作为子元素时,用户代理必须改为应用"溢出"属性从第一个这样的子元素到视口,如果根元素上的值是"可见的".用于视口时的"可见"值必须解释为"自动".传播值的元素必须具有"可见"的"溢出"的已使用值.

    更简单地说:

    • 如果没有html overflow: visible,请将其应用于视口,然后将html转换为overflow: visible.overflow赋予身体的价值不受影响.

    • 如果html是overflow: visible,但是body不是,请将其应用于视口,然后将body转换为overflow: visible.

    (设置overflow-xoverflow-yvisible元素之外的任何内容都会导致速记overflow不再等于visible该元素.)

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

    但是......你还给html和body一个宽度和高度100%!这意味着100%的容器.body的容器是html,html的容器是初始包含块.但是由于你实际上不能使用CSS来控制视口的大小 - 这完全由浏览器处理 - 你将两个元素约束为视口高度的100%(也称为折叠).视口本身不必扩展到折叠以外,因为它的内容都不需要比可见空间更多的空间(请注意绝对定位的元素永远不会被考虑在内).因此视口不会生成滚动条(也不会生成html); 您看到的滚动条属于正文.

    如果你没有设置widthheight属性,那么它们将默认为auto,导致html和body都与其内容一起扩展,并且总是与初始包含块所覆盖的整个区域相同,包括折叠下方的区域.这可防止身体不断产生滚动条,因为它总是会延伸到适合的内容,所以你只能看到视滚动条,而绝对定位的元素将与页面的其余部分滚动.

  • 由于初始包含块不滚动,因此绝对定位的元素也不会滚动.即使页面的其余部分滚动,这也会使其显示为固定.

    滚动时会发生什么,那就是你真的滚动了body元素.由于绝对定位的元素锚定到从不滚动的初始包含块,因此它似乎是固定的而不是滚动.

    顺便说一下,这也是元素在完全不滚动时看起来与滚动条重叠的原因.滚动条属于body,位于绝对定位的元素下方.如果删除overflow-x声明或widthheightHTML和身体的声明,你看到滚动条属于视代替.但是,如果您定位body,滚动条仍然属于body,但该元素也会成为body的子元素,因此它不会与滚动条重叠.


zak*_*lle 5

您需要添加position: relativebody. 你div.background已经在position: absolute上面了,这导致它粘在 HTML 文档的顶部。如果您不希望这样,则需要提供其父级(在本例中为 body 标记)position: relative

演示 #1: http: //tinkerbin.com/nmI74RpC

或者,您可以删除position: absolutefrom div.background,但我不确定这会如何影响布局的其余部分。

演示#2:http://tinkerbin.com/PP5PpbuC