为什么当 position:absolute 应用于 header 时,导航中需要 float:left 以保持文本居中?
Why is float:left required in navigation to keep text center when position:absolute applied to header?
在header中观察到CSS position : absolute
的一个奇怪的事情是,除非下面的菜单中有float:left
,否则菜单的文本不会垂直居中,而是停留在最佳。您可以通过 运行 此页面中给出的全宽代码段来查看。我已经为 float:none in lower screen width
设置了一个媒体查询,它取消了更高 screen-widths 中的 float:left
。
现在,为什么会出现这种行为?当 position:absolute 应用于 header 和 vice-versa 时,为什么 float:left 保持菜单文本垂直居中?我在搜索时没有找到任何内容。
编辑 -
有些回答说这是由于 "collapsing" 的页边距造成的。但他们没有解释为什么 h1 of header
不是 "collapsing" 并且以这种方式表现?为什么只有 h1 of menu
是 "collapsing" ?它似乎更像是一些元素的选择重叠而不是折叠。
编辑2-
请答题者,如果为了解释的方便,要将摘录分解,除了部分摘录外,还应将完整的摘录或其修改部分放入他们的答案中。因为 divs 不是孤立行动的。答案应该有 header 和 position: absolute,它的 h1 和 margin-top 应用于 header 下面的 div 的 h1。
请看这个片段 -
div.header {
position: absolute;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: #000000;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
}
@media screen and (max-width: 766px){
.submenu {
float:none;
}
}
<div class="header">
<h1>HEADER </h1>
</div>
<div class="submenu">
<h1>MENU</h1>
</div>
编辑:
正如我在评论中解释的那样,header 中的 h1
不会折叠,因为它使用 position:absolute
- 正如您在下面看到的那样,它是修复以防止折叠边距。重叠只是因为你的 header 是绝对定位的,所以它会出现在页面中其他所有内容的顶部。
概括地说,当 垂直 边距触及 块 元素时,会发生 折叠边距它们之间没有分隔(例如边框或填充),没有浮动,没有绝对定位, 未固定并具有overflow:visible
(默认值)。还有一些其他情况,但这涵盖了绝大多数原因,包括您的原因。
回答
您看到的是折叠边距的效果。
CSS 规范说,当两个元素的垂直边距接触时,两个边距将合并为一个边距。
当第一个(或最后一个)child 和 parent 之间没有分隔时,parent/child 元素也会发生这种情况 - 在这种情况下,折叠边距最终会超出parent.
在您的情况下,您的h1
具有浏览器样式表的默认边距。这被折叠到它的 parent 的边距中,即默认情况下 submenu
元素,因为它是一个块元素。
防止边距折叠:
有多种方法可以防止 child 的边距折叠,包括:
- 浮动
- 位置:绝对。
- 将显示更改为以下之一:“table-cell”、“table-caption”或“inline-block”。
- 添加可见以外的溢出,例如
overflow:auto
- 在parent和child之间添加一个"separation",例如边框或填充。
当您将 float
添加到您的 child 时,这是防止边距折叠的方法之一,因此您的边距仍然有 space 出现在h1 的顶部包含单词 "Menu".
查看一些示例:
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 0px;
color:black;
height: 100px;
background-color: red;
float: none;
padding:0px;
}
.container { border:2px solid #ff0;}
.container:after {
content: "";
display: table;
clear: both;
}
h1{ margin:30px 0;}
.submenu.hasfloat {float: left;}
.submenu.hasoverflow {overflow: auto;}
<p>The top margin of this h1 is collapsed into the parent's margin. </p><p>The parent's top margin is 10px, and the h1 has a top margin of 30px, so when collapsed the parent now takes on the child's margin because it is larger - you can see the margin surrounded with the yellow border:</p>
<div class="container">
<div class="submenu">
<h1>Collapsed</h1>
</div>
</div>
<p>The top margin of this h1 isn't collapsing because the parent is <b>floated</b>:</p>
<div class="container">
<div class="submenu hasfloat">
<h1>Not collapsed</h1>
</div>
</div>
<p>The top margin of this h1 isn't collapsing because the parent has <b>overflow:auto</b> (i.e. any value other than visible):</p>
<div class="container">
<div class="submenu hasoverflow">
<h1>Not collapsed</h1>
</div>
</div>
示例:显示即使 header 不是绝对定位问题仍然存在。
div.header {
position: relative;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: #000000;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
}
@media screen and (max-width: 766px){
.submenu {
float:none;
}
}
<div class="header">
<h1>HEADER <small>- position:relative</small></h1>
</div>
<div class="submenu">
<h1>MENU <small>- top margin is still collapsing</small></h1>
</div>
参考资料:从以下位置阅读有关折叠边距的更多信息:
应用于 header 的 position: absolute
使 div 固定,而所有其他 div 变得相对可移动。所以,为了让其他人也固定下来,我们给他们一些其他的属性,比如 display:inline-block,float:left 等
此外,需要给绝对div下方的div一个margin-top来抵消折叠边距
请查看应用了这些修复的工作代码,其中包含 https://codepen.io/anon/pen/QqRgRB
中的所有 div
摘录如下-
div.header {
position: absolute;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: grey;
}
.menu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
display: inline-block;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 0px;
color:black;
height: 100px;
background-color: yellow;
display:inline-block;
padding:0px;
}
@media screen and (max-width: 766px){
.menu {
float:none;
}
}
body {
margin:0px;
}
<div class="header">
<h1>HEADER </h1>
</div>
<div class="menu">
<h1>MENU</h1>
</div>
<div class="submenu">
<h1>SUBMENU</h2>
</div>
在header中观察到CSS position : absolute
的一个奇怪的事情是,除非下面的菜单中有float:left
,否则菜单的文本不会垂直居中,而是停留在最佳。您可以通过 运行 此页面中给出的全宽代码段来查看。我已经为 float:none in lower screen width
设置了一个媒体查询,它取消了更高 screen-widths 中的 float:left
。
现在,为什么会出现这种行为?当 position:absolute 应用于 header 和 vice-versa 时,为什么 float:left 保持菜单文本垂直居中?我在搜索时没有找到任何内容。
编辑 -
有些回答说这是由于 "collapsing" 的页边距造成的。但他们没有解释为什么 h1 of header
不是 "collapsing" 并且以这种方式表现?为什么只有 h1 of menu
是 "collapsing" ?它似乎更像是一些元素的选择重叠而不是折叠。
编辑2-
请答题者,如果为了解释的方便,要将摘录分解,除了部分摘录外,还应将完整的摘录或其修改部分放入他们的答案中。因为 divs 不是孤立行动的。答案应该有 header 和 position: absolute,它的 h1 和 margin-top 应用于 header 下面的 div 的 h1。
请看这个片段 -
div.header {
position: absolute;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: #000000;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
}
@media screen and (max-width: 766px){
.submenu {
float:none;
}
}
<div class="header">
<h1>HEADER </h1>
</div>
<div class="submenu">
<h1>MENU</h1>
</div>
编辑:
正如我在评论中解释的那样,header 中的 h1
不会折叠,因为它使用 position:absolute
- 正如您在下面看到的那样,它是修复以防止折叠边距。重叠只是因为你的 header 是绝对定位的,所以它会出现在页面中其他所有内容的顶部。
概括地说,当 垂直 边距触及 块 元素时,会发生 折叠边距它们之间没有分隔(例如边框或填充),没有浮动,没有绝对定位, 未固定并具有overflow:visible
(默认值)。还有一些其他情况,但这涵盖了绝大多数原因,包括您的原因。
回答
您看到的是折叠边距的效果。
CSS 规范说,当两个元素的垂直边距接触时,两个边距将合并为一个边距。
当第一个(或最后一个)child 和 parent 之间没有分隔时,parent/child 元素也会发生这种情况 - 在这种情况下,折叠边距最终会超出parent.
在您的情况下,您的h1
具有浏览器样式表的默认边距。这被折叠到它的 parent 的边距中,即默认情况下 submenu
元素,因为它是一个块元素。
防止边距折叠:
有多种方法可以防止 child 的边距折叠,包括:
- 浮动
- 位置:绝对。
- 将显示更改为以下之一:“table-cell”、“table-caption”或“inline-block”。
- 添加可见以外的溢出,例如
overflow:auto
- 在parent和child之间添加一个"separation",例如边框或填充。
当您将 float
添加到您的 child 时,这是防止边距折叠的方法之一,因此您的边距仍然有 space 出现在h1 的顶部包含单词 "Menu".
查看一些示例:
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 0px;
color:black;
height: 100px;
background-color: red;
float: none;
padding:0px;
}
.container { border:2px solid #ff0;}
.container:after {
content: "";
display: table;
clear: both;
}
h1{ margin:30px 0;}
.submenu.hasfloat {float: left;}
.submenu.hasoverflow {overflow: auto;}
<p>The top margin of this h1 is collapsed into the parent's margin. </p><p>The parent's top margin is 10px, and the h1 has a top margin of 30px, so when collapsed the parent now takes on the child's margin because it is larger - you can see the margin surrounded with the yellow border:</p>
<div class="container">
<div class="submenu">
<h1>Collapsed</h1>
</div>
</div>
<p>The top margin of this h1 isn't collapsing because the parent is <b>floated</b>:</p>
<div class="container">
<div class="submenu hasfloat">
<h1>Not collapsed</h1>
</div>
</div>
<p>The top margin of this h1 isn't collapsing because the parent has <b>overflow:auto</b> (i.e. any value other than visible):</p>
<div class="container">
<div class="submenu hasoverflow">
<h1>Not collapsed</h1>
</div>
</div>
示例:显示即使 header 不是绝对定位问题仍然存在。
div.header {
position: relative;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: #000000;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
}
@media screen and (max-width: 766px){
.submenu {
float:none;
}
}
<div class="header">
<h1>HEADER <small>- position:relative</small></h1>
</div>
<div class="submenu">
<h1>MENU <small>- top margin is still collapsing</small></h1>
</div>
参考资料:从以下位置阅读有关折叠边距的更多信息:
应用于 header 的 position: absolute
使 div 固定,而所有其他 div 变得相对可移动。所以,为了让其他人也固定下来,我们给他们一些其他的属性,比如 display:inline-block,float:left 等
此外,需要给绝对div下方的div一个margin-top来抵消折叠边距
请查看应用了这些修复的工作代码,其中包含 https://codepen.io/anon/pen/QqRgRB
中的所有 div摘录如下-
div.header {
position: absolute;
left: 0%;
top: 0%;
width: 100%;
height: auto;
text-align: center;
color: #EE82EE;
background-color: grey;
}
.menu {
text-align: center;
width:100%;
margin:0;
margin-top: 72px;
color:black;
height: 100px;
background-color: red;
float: left;
padding:0px;
display: inline-block;
}
.submenu {
text-align: center;
width:100%;
margin:0;
margin-top: 0px;
color:black;
height: 100px;
background-color: yellow;
display:inline-block;
padding:0px;
}
@media screen and (max-width: 766px){
.menu {
float:none;
}
}
body {
margin:0px;
}
<div class="header">
<h1>HEADER </h1>
</div>
<div class="menu">
<h1>MENU</h1>
</div>
<div class="submenu">
<h1>SUBMENU</h2>
</div>