【问题标题】:How are the widths of nested absolutely positioned elements determined?嵌套绝对定位元素的宽度是如何确定的?
【发布时间】:2013-07-12 08:49:47
【问题描述】:

例子:

<style>
     div {
         position:absolute; left:auto; right:auto; width:auto;
         margin:0; padding:0; border:0;
     }
</style>
<div id="containingBlock">
    foo
    <div id="inner">this is my text</div>
</div>

要确定两个div的宽度,我们需要http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width中的shrink-to-fit算法 *

让我们从#inner开始:

  • 得到首选的最小宽度

     this
     is
     my
     text
    |----| preferred minimum width
    
  • 获取首选宽度

     this is my text
    |---------------| preferred width
    
  • 将两者与可用宽度进行比较

    computed width = min(max(preferred minimum width, available width),
                         preferred width)
    

    简单。但是什么是可用宽度?因为我们没有边距/填充/边框,它只是containingBlock 的宽度。但是现在我们得到了一个无限循环,因为同样的算法再次适用:

  • 获取包含块的首选最小宽度

     foo
     +-------+
     | inner |
     +-------+
    |--?????--| preferred minimum width
    

换句话说:要得到inner的宽度,我们必须知道containingBlock的宽度,反之亦然。

实际上,在这种情况下,浏览器似乎只是假设available width = 0http://jsfiddle.net/pxvJJ/6/。 但这不在规范中,还是我遗漏了一些明显的东西?

* (请注意,此规范尚未被 CSS3 取代)

【问题讨论】:

  • 绝对位置将从正常文档流中删除。所以#containingBlock 的首选最小宽度不关心#inner 的处理宽度。 #inner 的可用宽度基于其第一个祖先,这导致文本 foo 的长度。
  • @RenéGeuze 我看不到。 可用宽度的计算精确定义in 10.3.7:求解方程'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block,设置width后为left=right=0
  • @Pumbaa80 - 这不是 RenéGeuze 所说的(我认为)。他是说内部块(或其内容)不参与计算包含块的首选最小宽度(或首选宽度),让包含块收缩包裹剩下的东西(即“foo”文本),从而打破依赖循环。
  • @Alohci - 现场。我确实试图解释它不是一个无限循环,因此宽度不仅仅是一些准随机假设。对于无法找到必要的词语来写出一个全面的可接受的答案,我深表歉意。在我看来,这是一个很好的问题,我喜欢对规格和浏览器行为进行深入研究。
  • 感谢您的澄清。我想这就是浏览器实际所做的,所以@RenéGeuze 是对的。事实上,“CSS 2.1 没有定义确切的算法。”,由于上述情况,这种算法需要跳过没有明确宽度的绝对定位的子节点。

标签: css


【解决方案1】:

如果我们仔细阅读规范,我们将find that

CSS 2.1 没有定义确切的 [shrink-to-fit] 算法。

应该是这样的

类似于使用自动表格布局算法计算表格单元格的宽度

is implementation-dependent

因此,上面的示例表明,在实现直接算法时,将 #inner 从包含块的首选最小宽度的计算中排除可能是一个好主意,我们最终会得到这个:

|---| preferred minimum width
 foo
 +-------+
 | inner |
 +-------+
|--?????--|

这可能是浏览器所做的。


话虽如此,问题是:哪些元素确实真正有助于 containsBlock 的首选最小宽度

让我们看看如果#inner 拥有position:static; width: auto 会发生什么。这个案子就更难了。同样,the specs 给出约束

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = 包含的宽度阻止

这次不允许收缩以适应。而且,再次,它无法解决。或者可以吗?很有趣,它可以!让我们看看实际发生了什么:http://jsfiddle.net/pxvJJ/12/

显然,静态定位的 div 的处理方式不同。所以我想确定包含块宽度的算法是这样的:

  1. 确定在正常流程中包含的所有块框的首选宽度
  2. 设置包含块的宽度 = 这些首选宽度的最大值
  3. 计算所有包含框的宽度,现在包含块的宽度已知

我仍然对(所有)浏览器为什么这样做感到困惑。在这方面,似乎没有理由区别对待绝对定位的元素。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多