【问题标题】:Margin-Top push outer div downMargin-Top 将外部 div 向下推
【发布时间】:2011-02-10 10:47:26
【问题描述】:

我有一个标题 div 作为包装 div 中的第一个元素,但是当我在标题 div 内的 h1 中添加上边距时,它会将整个标题 div 向下推。我意识到每当我对页面上的第一个可见元素应用上边距时都会发生这种情况。

这是一个示例代码 sn-p。谢谢!

div#header{
	width: 100%;
	background-color: #eee;
	position: relative;
}

div#header h1{
	text-align: center;
	width: 375px;
	height: 50px;
	margin: 50px auto;
	font-size: 220%;
	background: url('../../images/name_logo.png') no-repeat;
}
<div id="header">
	<h1>Title</h1>
	<ul id="navbar"></ul>
</div>

【问题讨论】:

    标签: html css xhtml


    【解决方案1】:

    我没有确切解释为什么会发生这种情况,但我已通过将 top-margin 更改为 top-padding 或将 display: inline-block 添加到元素样式来解决此问题。

    编辑:这是我的理论

    我觉得这与边距如何折叠(合并)有关。

    来自W3C Collapsing Margins

    在本规范中,表达式 折叠边距意味着 相邻边距(没有非空 内容、填充或边界区域或 间隙将它们分开)的两个或 更多的盒子(可能在一个旁边 另一个或嵌套)结合形成一个 单边距。

    我的理论是,由于您的第一个元素靠近正文,因此两个边距组合并应用于正文:这会强制正文的内容从应用的折叠边距下方开始,以符合 box model

    在某些情况下,边距不会塌陷,这可能值得一试(来自Collapsing Margins):

    * floated elements
    * absolutely positioned elements
    * inline-block elements
    * elements with overflow set to anything other than visible (They do not collapse margins with their children.)
    * cleared elements (They do not collapse their top margins with their parent block’s bottom margin.)
    * the root element
    

    【讨论】:

    • 此外,具有折叠边距(内部)的元素上的填充或边框将取消折叠。
    • 这对我有用 - 我的容器中有绝对元素(下拉菜单),所以溢出:自动不起作用。
    【解决方案2】:

    overflow:auto放入父div
    see more in this link

    【讨论】:

    • overflow:hidden 更适合 90% 的情况。
    • 为什么会溢出:隐藏更好?
    • @peterchon - 因为自动会导致滚动条
    • 不再起作用了,@SW4 在这个link 中的答案更好
    • overflow: hiddenoverflow: auto 可能会导致不必要的副作用,其中一些您可能第一眼看不到。我发现将margin 更改为padding 可以解决问题,如下面的答案所示。不过,仍然不明白为什么会出现整个问题。
    【解决方案3】:

    这是避免父子元素之间的边距折叠的一些方法。使用更适合您其他样式的那个:

    • display 设置为block 以外的其他值。
    • float 设置为none 以外的其他值。
    • 删除边距,并改用padding。例如,如果您有 margin-top: 10px,请替换为 padding-top: 10px;
    • 删除边距,并使用positionabsoluterelative)与topbottom等属性代替。例如,如果您有margin-top: 10px,则替换为position: relative; top: 10px;
    • paddingborder 添加到 元素的边距折叠一侧。边框可以是 1 像素且透明。
    • overflow 设置为visible 以外的 元素。

    【讨论】:

      【解决方案4】:

      今天遇到这个问题。

      当我跟随更多元素时,overflow: hidden 没有按预期工作。

      所以我尝试更改父 div 的显示属性,display: flex 工作!!!

      希望这可以帮助某人。 :)

      【讨论】:

        【解决方案5】:

        向父元素顶部添加一点填充可以解决此问题。

        .parent{
          padding-top: 0.01em;
        }

        如果您需要父元素内部的元素在父元素外部可见,这很有用,例如创建重叠效果。

        【讨论】:

          【解决方案6】:

          display: flex 在这种情况下可以工作。给父元素display: flex;,然后根据您的要求给h1标签提供边距。

          【讨论】:

            【解决方案7】:

            我知道这是一个老问题,我遇到过很多次。问题是这里的所有修复都是黑客攻击,可能会产生意想不到的后果。

            首先,对于根本问题有一个简单的解释。由于边距折叠的工作方式,如果容器内的第一个元素具有上边距,则该上边距有效地应用于父容器本身。您可以通过以下方式自行测试:

            <div>
                <h1>Test</h1>
            </div>
            

            在调试器中,将其打开并悬停在 div 上。您会注意到 div 本身实际上放置在 H1 元素的上边距 停止 处。此行为是浏览器有意为之。

            所以有一个简单的解决方法,而不必求助于奇怪的黑客,就像这里的大多数帖子一样(没有侮辱的意图,这只是事实) - 只需回到原来的解释 - ...if the first element inside a container has a top margin... - 紧随其后,因此您需要容器中的第一个元素 NO 具有上边距。好的,但是如何在不添加不会影响文档语义的元素的情况下做到这一点?

            简单!伪元素!你可以通过一个类或预定义的 mixin 来做到这一点。添加:before伪元素:

            通过类的 CSS:

            .top-margin-fix::before {   
                content: ' ';
                display: block;
                width: 100%;
                height: .0000001em;
            }
            

            有了这个,按照上面的标记示例,你可以这样修改你的 div:

            <div class="top-margin-fix">
                <h1>Test</h1>
            </div>
            

            为什么会这样?

            容器中的第一个元素,如果它没有上边距,则设置下一个元素上边距的开始位置。通过添加:before 伪元素,浏览器实际上在父容器中添加了一个非语义(换句话说,有利于 SEO)元素在您的第一个元素之前

            问。为什么高度:.0000001em?

            A.浏览器需要一个高度才能将边距元素向下推。这个高度实际上为零,但它仍然允许您向​​父容器本身添加填充。由于它实际上为零,因此它也不会对容器的布局产生影响。漂亮。

            现在你可以添加一个类(或者更好,在 SASS/LESS 中,一个 mixin!)来解决这个问题,而不是添加奇怪的显示样式,当你想用你的元素做其他事情时会导致意想不到的后果,有目的地消除元素的边距和/或用填充或奇怪的位置/浮动样式替换它,这些样式实际上并不是为了解决这个问题。

            【讨论】:

            • .0000001em 在 IE11 中被四舍五入到零,破坏了你的修复。当我将其更改为 .01em 时,它可以工作。
            • 我想 .01em 将足以仍然有效地为零。好点子。从好的方面来说,现在是 2018 年,我们中的很多人很快就会放弃对 IE11 的支持,尤其是最近宣布 MS 将再次构建新的浏览器(除了这次,基于 Chromium,这意味着它 - 理论上- 不会完全烂)。 :D
            【解决方案8】:

            发生这种情况是因为边距崩溃。 当子元素触及父元素的边界并且其中任何一个都应用了边距时:

            1. 最大的利润将获胜(应用)。

            2. 如果其中任何一个有边距,那么两者将共享相同的。

            解决方案

            1. 为父级应用边框,使父级和子级分开。
            2. 对父级应用填充,使父级和子级分开。
            3. 应用溢出而不是在父级上可见。
            4. 使用 before 或 after 在父 div 中创建虚拟元素,可以不同的边距应用子元素和父元素。
            5. 在应用边距的子元素和父元素之间创建一个html元素也可以将它们分开。

            【讨论】:

              猜你喜欢
              • 2013-08-26
              • 2012-01-21
              • 2013-09-22
              • 1970-01-01
              • 1970-01-01
              • 2011-01-23
              • 1970-01-01
              • 1970-01-01
              • 2018-01-15
              相关资源
              最近更新 更多