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

前端之家收集整理的这篇文章主要介绍了html – 为什么overflow-x:hidden使我的绝对定位元素变得固定?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想弄清楚,为什么设置overflow-x:hidden到HTML页面的主体会使我的元素位置:固定,即使我将它设置为position:absolute.

在这个demo中可以更好地理解这种效果.

这是代码

HTML:

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

CSS:

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 {
  positon: relative;
  width: 100%;
  height: 100%;    
  min-height: 100%;
  border: 1px solid red;
  margin-bottom:200px;
}

div.background {
  background: blue;
  position: absolute;
  width: 100%;
  height: 20%;
}

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

解决方法

元素仍然是位置:绝对,但由于位置,溢出和盒子模型之间的一些相当复杂的相互作用,它看起来是固定的.令人难以置信的是,这些行为中没有一个是未指定的或任何浏览器中的错误 – 它实际上完全是设计的,如果有点违反直觉.

它基本归结为以下内容

>绝对定位的元素将锚定到视口,除非定位其任何祖先. (这就是为什么adding position: relative to body works as suggested in another answer.)
>你有宽度:100%;身高:100%;在html和body上;这可以防止视口扩展到其可见区域之外,因此视口永远不会滚动.
>由于视口不滚动,因此绝对定位的元素也不会滚动.即使页面的其余部分滚动,这也会使其显示为固定.

奇怪的是,this works on IE6 too.

更长的解释:

>绝对定位的元素将锚定到视口,除非定位其任何祖先.

溢出属性上的spec,它偶然包含你正在观察的同一问题的另一个例子,其中一个带溢出的元素:scroll与一个绝对定位的后代元素交互,声明如下:

This property specifies whether content of a block container element is clipped when it overflows the element’s Box. It affects the clipping of all of the element’s content except any descendant elements (and their respective content and descendants) whose containing block is the viewport or an ancestor of the element.

你的绝对定位元素是一个后代,其包含块是视口(也是html元素的包含块),因为html和body都没有定位.这是根据another section of the spec.这可以防止html和body上的溢出剪切对您的绝对定位元素产生任何影响,因为它锚定到视口.
>你有宽度:100%;身高:100%;在html和body上;这可以防止视口扩展到其可见区域之外,因此视口永远不会滚动.

规范然后在同一部分进一步说明以下内容

UAs must apply the ‘overflow’ property set on the root element to the viewport. When the root element is an HTML “HTML” element or an XHTML “html” element,and that element has an HTML “BODY” element or an XHTML “body” element as a child,user agents must instead apply the ‘overflow’ property from the first such child element to the viewport,if the value on the root element is ‘visible’. The ‘visible’ value when used for the viewport must be interpreted as ‘auto’. The element from which the value is propagated must have a used value for ‘overflow’ of ‘visible’.

更简单地说:

>如果html不溢出:可见,请将其应用于视口,然后将html转为overflow:visible.赋予身体的溢出值不受影响.
>如果html溢出:可见,但实体不是,然后将body转为overflow:visible.

(将overflow-x或overflow-y设置为元素causes the shorthand overflow to no longer be equal to visible for that element以外的任何值.)

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

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

如果您没有设置宽度或高度属性,那么它们将默认为auto,导致html和body都与其内容一起展开,并且始终与整个视口区域的大小相同,包括折叠下方的区域.这可以防止身体生成滚动条,因为它将始终拉伸以适合其内容,因此您只能看到视口滚动条,绝对定位的元素将与页面的其余部分一起滚动.
>由于视口不滚动,这也会使其显示为固定.

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

顺便说一下,这也是元素在不滚动时看起来与滚动条重叠的原因.滚动条属于body,位于绝对定位的元素下方.如果从html和body中删除overflow-x声明或width和height声明,则您看到的滚动条将属于视口.但是,如果您定位body,滚动条仍然属于body,但该元素也会成为body的子项,因此它不会与滚动条重叠.

原文链接:https://www.f2er.com/html/232116.html

猜你在找的HTML相关文章