为什么百分比差额会导致换行?

时间:2014-06-09 02:28:02

标签: html css margin

<div style = "float : left; background-color: #dd3fb8;">
    <a style = "margin-left : 10%;">a</a> 
    <a>b</a> 
    <a>c</a> 
</div>

在上面的例子中,字母&#34; c&#34;会在新线上,但如果我设置&#34; margin-left&#34;到px单位,&#34; c&#34;将与&#34; a&#34;在同一条线上和&#34; b&#34;。为什么会这样?

3 个答案:

答案 0 :(得分:13)

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

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

  • 没有指定宽度的浮点数将为shrink to fit their contents。对于仅具有内联内容的浮动,浮动需要做得足够宽以使其内容适合单行(尽管有明确的换行符)而不再需要。

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

    请注意:

      

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

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

    话虽如此,这句话适用的原因是因为内联元素的边距落在float的内容边界内,可以说float的宽度(内联元素的包含块)取决于在这个元素(具有边距的元素)上。

根据以上几点,我可以演绎

  • 当保证金指定为百分比时,浮动的宽度是在不考虑保证金的情况下计算的,因为无法计算保证金直到浮动的宽度已确定。

    然后根据浮动的使用宽度计算边距,并且字母“c”由于被“a”上的边距向前推动而换行到新线。 浮动的宽度不会改变。

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

  • 当将边距指定为像素值时,首先计算边距。然后考虑此边距计算浮动的宽度(请记住,水平边距确实适用于内联元素)。根据收缩拟合算法,这是首选宽度:宽度足以包含单行上的所有内联元素。

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

我很难在任何浏览器中将其称为错误,特别是因为它们都表现得一致。

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

答案 1 :(得分:9)

由于div已展开,其widthauto(隐式),http://www.w3.org/TR/CSS21/visudet.html#float-width适用:

  

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

“缩小到适合”宽度基本上意味着,让元素与其内容所需的宽度一样宽。

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

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

  

百分比:指包含块的宽度

现在,由于包含块(由浮动的div元素建立)的宽度是基于其内容计算的,因此我们在中留下了一些pickle - 但是现在这个margin-left更改该内容的总宽度,但它本身依赖于包含块的width,它本身会影响...

这是两个依赖相互依赖的测量的经典问题 ......基本上不可解决

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

  

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


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

答案 2 :(得分:4)

该链接的左边距为10%, 多少 的10%?父元素向左浮动,这意味着它没有自己的宽度,而是扩展其内容。如果您试图模仿浏览器计算结果框的方式,您会发现自己处于修复状态:

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

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

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