为什么不顶部:0相对于身体的绝对定位元素?

Cro*_*Toa 17 html css specifications css-position

您可以在下面的代码中看到,h1向下推动身体,绝对定位的块.absolute不会粘在顶部.但是你也可以看到同一个块粘在其父级的顶部.wrapper.为什么?

我不是在问这个伎俩; 我知道如何,例如填充而不是边缘到h1,或clearfix到父级等等.

我只对一件事情感兴趣:为什么h1保证金推低了body,但是没有推倒.wrapper

body {
  position: relative;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: silver;
}

.absolute {
  position: absolute;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  background-color: darkblue;
}

.wrapper {
  position: relative;
  overflow:hidden;
  width: 50%;
  height: 200px;
  overflow: hidden;
  background-color: yellow;
}

.wrapper > .absolute {
  background-color: darkcyan;
}
Run Code Online (Sandbox Code Playgroud)
<div class="absolute"></div>
<h1>Some title</h1>

<div class="wrapper">
  <div class="absolute"></div>
  <h1>Some title</h1>
</div>
Run Code Online (Sandbox Code Playgroud)

好的,我会尽量更清楚.如果你点击下面的链接,你可以看到我的JSFiddle.有background-color: silverbody标签.当我查看代码检查器时,我发现由于h1边距,body标签开始略低.但从background-color顶部开始.这意味着代码检查员在骗我,身体从顶部开始.但是,为什么一个绝对定位的元素是一个body不是从顶部开始的直接孩子呢?

的jsfiddle

Bol*_*ock 13

如所提到的,顶层的包含块绝对定位的元素是body作为body相对地定位.当h1 折叠边缘与其折叠body,这会导致边距影响body,进而影响它所包含的绝对定位元素.相反,如果body 没有相对定位,绝对定位的元素将锚定到初始包含块,并且粘贴到视口的顶部,不受任何有效边距的影响body(因为body它不再是其包含块).

至于为什么银色背景渗透到body元素之外,那就是设计:

3.11.1.画布背景和根元素

根元素的背景成为画布的背景,其背景绘画区域扩展到覆盖整个画布.但是,任何图像的大小和位置都相对于根元素,就像它们仅为该元素绘制一样.(换句话说,背景定位区域是根元素确定的.)根元素不会再次绘制此背景,即其背景的使用值是透明的.

3.11.2.画布背景和HTML <body>元素

对于其根元素是HTML HTML元素或XHTML html元素的文档:如果根元素上的"background-image"的计算值为"none"且其"background-color"为"transparent",则用户代理必须传播从该元素的第一个HTML BODY或XHTML body子元素计算背景属性的值.BODY元素的背景属性的使用值是它们的初始值,传播的值被视为在根元素上指定它们.建议HTML文档的作者指定BODY元素的画布背景而不是HTML元素.

根元素的默认背景颜色始终为transparent,因此在html元素上设置背景颜色可防止银色背景从body元素中渗出(您将看到检查器实际上不会对您说谎):

html {
  background-color: white;
}

body {
  position: relative;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: silver;
}

.absolute {
  position: absolute;
  top: 0;
  left: 0;
  width: 50px;
  height: 50px;
  background-color: darkblue;
}

.wrapper {
  position: relative;
  overflow:hidden;
  width: 50%;
  height: 200px;
  overflow: hidden;
  background-color: yellow;
}

.wrapper > .absolute {
  background-color: darkcyan;
}
Run Code Online (Sandbox Code Playgroud)
<div class="absolute"></div>
<h1>Some title</h1>

<div class="wrapper">
  <div class="absolute"></div>
  <h1>Some title</h1>
</div>
Run Code Online (Sandbox Code Playgroud)


Ser*_*sov 7

这是因为利润率下降.如何禁用它,你可以阅读一些文章/答案,例如,.
您正在使用overflow: hidden.wrapper,和禁止折叠该块利润.从规格:

除"可见"以外的"溢出"框的边距不会随其子边距而崩溃.

但它似乎overflow: hidden不起作用<body>,因为如果我设置
height: 0/ max-height: 0它也不起作用:

body {
    height: 0;
    max-height: 0;
}
Run Code Online (Sandbox Code Playgroud)
<div>Some test text</div>
Run Code Online (Sandbox Code Playgroud)

我认为这是因为(来自规范):

UA必须将根元素上的"溢出"属性集应用于视口.当根元素是HTML"HTML"元素或XHTML"html"元素,并且该元素具有HTML"BODY"元素或XHTML"body"元素作为子元素时,用户代理必须改为应用"溢出"属性从第一个这样的子元素到视口,如果根元素上的值是"可见的".

这就是为什么<body>首次<h1>崩溃之间的利润率(来自MDN):

父级和第一个/最后一个子级
如果没有边框,填充,内联内容或间隙margin-topmargin-top与其第一个子块分隔,或者没有边框,填充,内联内容,高度,最小高度最大值-margin-bottom高度将块margin-bottom与其最后一个子块分开,然后这些边缘崩溃.折叠的保证金最终在父母之外.

这就是原因之间的边距<html><body>不崩溃的原因(来自规范):

根元素框的边距不会折叠.

我还注意到,如果<html>有默认值background-color<body>指定了background-color+ margin,则背景颜色填充整个空间<html>,例如:

html, body {
    height: 100%;
}

body {
    margin: 20px;
    background-color: yellow;
}
Run Code Online (Sandbox Code Playgroud)

但是如果设置background-color<html>,它就像普通块一样工作,例如:

html, body {
    height: 100%;
}

html {
    background-color: red;
}

body {
    margin: 20px;
    background-color: yellow;
}
Run Code Online (Sandbox Code Playgroud)

总结一下,我建议您使用其他方法来禁用折叠边距,或者为其添加另一个包装器<body>,例如:

body {
    margin: 0;
    padding: 0;
}

.body-wrapper {
    position: relative;
    overflow: hidden;
    background-color: silver;
}

.absolute {
    position: absolute;
    top: 0;
    left: 0;
    width: 50px;
    height: 50px;
    background-color: darkblue;
}

.wrapper {
    position: relative;
    width: 50%;
    height: 200px;
    overflow: hidden;
    background-color: yellow;
}

.wrapper > .absolute {
    background-color: darkcyan;
}
Run Code Online (Sandbox Code Playgroud)
<div class="body-wrapper">
    <div class="absolute"></div>
    <h1>Some title</h1>

    <div class="wrapper">
        <div class="absolute"></div>
        <h1>Some title</h1>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)


Qua*_*cal 6

这是这种现象的另一个例子margin-collapsing.

我会试着解释发生了什么:

当您div.absolute使用绝对位置移动时,它会将其拉出内容流.这导致第一个h1充当其父亲的第一个孩子,body在这种情况下.

h1"保证金然后被倒塌体,由于保证金崩溃.这就是为什么top: 0;不在视口的左上角.它位于左上方body.

如果你需要让它工作,那么添加一个html {position: relative; overflow: hidden:}.

  • 既然你们都继续前进,[不介意我这样做](http://stackoverflow.com/questions/33594788/why-doesnt-top-0-work-on-absolutely-positioned-element-relative-与车身/ 33597266#33597266)... (2认同)