为什么一个元素有位置:固定移动与未定位的兄弟?

ste*_*jay 14 html css css-position css3

关于如何解决这个问题(添加top: 0),有很多关于SO的问题,但没有一个问题试图解释标题运动背后的原因.我更好奇为什么会这样.

<header>Project Header</header> 
<main class="container" id="layout-mainContent">
    <div class="row" id="first-row">somecontent</div>
</main>

header {
   position: fixed;
}

#layout-maincontent {
   margin-top: 90px;  //moves header down.
}
Run Code Online (Sandbox Code Playgroud)

类似问题清单,但没有任何理由:

  1. 最顶层的"固定"位置div与非位置div一起移动
  2. 保证金影响其他固定元素头寸
  3. margin-top div导致固定标题div向下移动

认为固定标题粘在浏览器窗口的顶部并且不应该因为另一个非定位的非子,非父div(也称为兄弟)而移动似乎是合理的.ESP.因为固定标题超出正常文档流程.关于固定定位的MDN

假设: 混淆源于固定元素相对于浏览器窗口的想法.这是事实,但是使用视口计算.视口使用常规文档流中的元素计算.因为文档流中的第一个div是非标题div,所以视口在应用margin-top之后开始.这只是猜测,我很乐意看到有人确认或纠正我.

Mic*_*l_B 22

使用position: fixed,您的header元素将从文档流中删除.

第一个in-flow元素main,margin-top: 90px在您的代码中.

此元素的父级body通常具有默认值margin: 8px(请参阅HTML默认样式表).

由于CSS 边距折叠,body元素margin-top: 8px将与main元素折叠margin-top: 90px.

结果,现在具有相同边距的两个元素都向下移动了90px.

html {
    background-color: green;
    height: 100%;
 }

body {
    background-color: pink;
    height: 100%;
}

header {
   position: fixed;
   border: 1px solid red;
}

main {
  margin-top: 90px;
  background-color:yellow;
}
Run Code Online (Sandbox Code Playgroud)
<header>Project Header</header> 
<main class="container" id="layout-mainContent">
    <div class="row" id="first-row">somecontent</div>
</main>
Run Code Online (Sandbox Code Playgroud)

的jsfiddle

固定标题移动的原因如下:

  • 虽然元素的包含块position: fixed是视口...
  • 的CSS偏移性(top,bottom,leftright)具有的初始值auto,其保持在那里它通常将是如果它是在文档流动的元件.
  • 换句话说,当你将元素设置为position: absoluteposition: fixed(另一种形式position: absolute)时,你指定了你想要的定位类型...... 但是你没有把它放在任何地方.
  • 直到您定义元素实际定位的偏移量为止.
  • 要将标题移动到视口的顶部,请使用top: 0.

html {
    background-color: green;
    height: 100%;
 }

body {
    background-color: pink;
    height: 100%;
}

header {
   position: fixed;
   border: 1px solid red;
   top: 0px; /* NEW */
}

main {
  margin-top: 90px;
  background-color:yellow;
}
Run Code Online (Sandbox Code Playgroud)
<header>Project Header</header> 
<main class="container" id="layout-mainContent">
    <div class="row" id="first-row">somecontent</div>
</main>
Run Code Online (Sandbox Code Playgroud)

的jsfiddle