【问题标题】:Why does a percentage margin cause a new line?为什么百分比保证金会导致换行?
【发布时间】:2014-07-29 13:25:15
【问题描述】:
<div style = "float : left; background-color: #dd3fb8;">
    <a style = "margin-left : 10%;">a</a> 
    <a>b</a> 
    <a>c</a> 
</div>

在上面的示例中,字母“c”将在新行上,但如果我将“margin-left”设置为 px 单位,“c”将与“a”和“b”在同一行。为什么会这样?

【问题讨论】:

  • 这取决于为 10% 计算的像素数与您为这些单位使用的像素数之间的差异
  • @tlindell:看起来不像。如果您指定一个荒谬的像素值,例如 500px,它的行为仍然与 10px 相同,即使它明显远大于 10% 的边距。

标签: html css margin


【解决方案1】:

不幸的是,CSS2.1 规范似乎对此没有明确的答案。事实上,我想说这完全属于未定义行为的范畴。

以下是我能找到的相关点:

  • 没有指定宽度的浮动将shrink to fit their contents。对于只有内联内容的浮点数,需要使浮点数刚好足够宽以将其内容放在一行上(尽管有明确的换行符),仅此而已。

  • 百分比边距计算based on the width of the containing block

    注意上面写着:

    如果包含块的宽度取决于此元素,则结果布局在 CSS 2.1 中未定义。

    ...但据我所知,所有浏览器的行为都是一致的。

    话虽如此,这个说法之所以适用,是因为内联元素的边距落在浮动的内容范围内,可以说浮动的宽度(内联元素的包含块)取决于在 this 元素上(有边距的元素)。

根据以上几点,我可以推断

  • 当边距指定为百分比时,计算浮动的宽度而不考虑边距,因为不可能计算边距直到浮动的宽度已经确定.

    然后根据浮动的使用宽度计算边距,字母“c”由于被“a”上的边距向前推动而换行。 浮动的宽度没有变化。

    同样,根本没有指定这种行为,因此从技术上讲,它并不违反规范。不过,这似乎是明智的。

  • 当边距指定为像素值时,首先计算边距。然后在考虑这个边距的情况下计算浮动的宽度(请记住,水平边距确实适用于内联元素)。根据缩小以适应算法,这是首选宽度:刚好足够在一行中包含所有内联元素。

    与百分比边距不同,这是非常明确的,因为实现首先计算边距的绝对值应该没有问题。

我很难将其称为任何浏览器中的错误,尤其是因为它们的行为一致。

最后,当然,您可以完全避免这种未定义的行为,只需在可能的情况下为您的浮动指定明确的宽度。但是,它确实有助于理解为什么你应该这样做。

【讨论】:

  • 为什么我的回答与手头的问题无关?浮动元素应该具有明确设置的宽度(除非它是替换元素,如图像)。这可确保浮动按预期运行,并有助于避免某些浏览器中的问题。如果浮动框的大小超过可用的水平空间,浮动框将向下移动。
  • 我想知道为什么大多数有经验的贡献者也会在没有给它足够的时间和理由的情况下投反对票
  • @Dipaks:你的回答基本上是说,“给你的浮动元素一个固定的宽度来避免这个问题”,但它并没有解释问题。它的原因本身。
  • @Dipaks:没错,我事先不可能知道它是相关的不知何故(re:不给浮动宽度)。但是您的回答并没有试图解释 为什么 它可能是相关的,老实说,您似乎完全回避了这个问题。这不是一个有用的答案,尤其是对于询问为什么的 OP。因此,虽然我的推理确实可以更具体一些(为此我深表歉意),但我相信我的反对意见仍然有效。
  • “如果浮动框的大小超过了可用的水平空间,浮动框会下移”——这其实是题外话,因为它是不是在此处向下移动的浮动框,而是它的内联后代之一。而且您随该行提供的链接也没有涉及此处所讨论的具体问题,而只是对float 的一般解释。
【解决方案2】:

由于您的div 是浮动的,并且它的widthauto(隐式),所以http://www.w3.org/TR/CSS21/visudet.html#float-width 适用:

如果 'width' 计算为 'auto',则使用的值为“shrink-to-fit”宽度。

“shrink-to-fit”宽度的基本意思是,让元素的宽度与它的内容一样宽。

现在没有margin-left,这没问题:所有三个a 元素都是内联元素,每个元素都包含一个特定字符 - 很容易确定它们各自的宽度并将它们相加。

但是现在你想要一个margin-left 百分比,事情变得复杂了——如果我们看一下the definition for margin-left,它会说:

百分比:指包含块的宽度

现在,这让我们有点麻烦,因为包含块的宽度(由浮动的div 元素建立)是根据其内容计算的——但是现在这个margin-left改变该内容的整体宽度,但它本身取决于包含块的width,它本身会影响...

这是两个相互依赖的测量的经典问题……因此基本上无法解决

http://www.w3.org/TR/CSS21/box.html#margin-properties 说,

 百分比是根据生成框的包含块的宽度计算的。 […]
如果包含块的宽度取决于此元素,则结果布局在 CSS 2.1 中未定义。


编辑:与 BoltClock 在他的回答中所说的基本相同,只是花了我一点时间......

【讨论】:

    【解决方案3】:

    链接的左边距为 10%,多少的 10%?父元素向左浮动,这意味着它没有自己的宽度,而是与其内容一样扩展。如果您尝试模仿浏览器如何计算结果框,您会发现自己陷入了困境:

    • 让内容(以及容器)的宽度为 30 像素
    • 为链接添加 30px 的 10% = 3px 左边距
    • 生成的容器宽度为 30 + 3 = 33px

    这会创建一个循环,其中边距随着外部宽度的增加而增加,而外部宽度随着边距的增加而增加(33px 的 10% = 3.3px 意味着容器宽度从 33px 变为 33.3px 等等)。对于这样的计算,结果行为是未定义的(正如CBroe 所指出的那样)。

    浏览器似乎避免了循环并坚持使用 30px 宽度。计算后引入的 3px 边距导致第三个链接流入第二行。浏览器再次通过坚持 30px 宽度来避免循环。

    【讨论】:

      猜你喜欢
      • 2011-04-23
      • 2013-10-29
      • 2018-11-02
      • 2022-01-24
      • 2013-10-30
      • 1970-01-01
      • 2015-09-19
      • 1970-01-01
      • 2016-04-14
      相关资源
      最近更新 更多