为什么CSS中的margin/padding百分比总是根据宽度计算?

mqp*_*mqp 127 css w3c

如果你看一下CSS盒子模型规范,你会看到以下内容:

[margin]百分比是根据生成的框的包含块的宽度计算的.请注意,对于"margin-top"和"margin-bottom"也是如此.如果包含块的宽度取决于此元素,则在CSS 2.1中未定义结果布局. (强调我的)

这确实是事实.但为什么呢?究竟是什么迫使任何人以这种方式设计它?你可以很容易地想到你想要的场景,比如某个东西总是从页面顶部降低25%,但是很难想出为什么你想要垂直填充相对于水平大小的父母.

这是我所指的现象的一个例子:

<div style="border: 1px solid red; margin: 0; padding: 0; width: 200px; height: 800px;">
  This div is 200x800.
  <div style="border: 1px solid blue; margin: 10% 0 0 10%;">
    This div has top-margin of 10% and left-margin of 10% with respect to its parent.
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/8JDYD/

Rya*_*nal 59

将我的评论转移到答案,因为它具有逻辑意义.但请注意,这是毫无根据的猜想.为什么规范以这种方式编写的实际推理在技术上仍然是未知的.

元素高度由子节点的高度定义.如果元素具有padding-top:10%(相对于父高度),那将影响父级的高度.由于孩子的身高取决于父母的身高,而父母的身高取决于孩子的身高,因此我们要么是身高不准确,要么是无限循环.当然,这只会影响偏移父级===父级的情况,但仍然如此.这是一个很难解决的奇怪案例.

更新:最后几句话可能不完全准确.叶元素(没有子元素的子元素)的高度会影响其上方所有元素的高度,因此会影响许多不同的情况.

  • 为什么W3C会不断这样做?显然,W3C的"语义"相当于必须迎合那些无法逻辑思考的人,这是没有意义的.这就像是抱怨世界上人们混淆和愚蠢,然后传播更多的混乱和愚蠢.你提供的推理没有意义:相同的参数适用于宽度,但这样做很好.所需要的只是设置确定高度的上下文和方向,除非父项的高度以像素或不可变的方式设置,然后没有太大的问题. (7认同)
  • 我不认为无限计算是原因。一个简单的原因是:使用 `width` 会导致同样的问题。 (3认同)
  • 这种依赖是一个代数公式,它有一个解决方案,并且**不会导致无限循环,除非你选择以不尊重它的方式解决它.假设父高是"h_p".填充顶部10%将使子高度为"h_c = h_ci + 0.1h_p",其中"h_ci"是子的内部高度,并且不依赖于父高度.对于一个孩子,您只需从等式'h_p = h_ci + 0.1h_p` =>`h_p = h_ci/0.9`中找到父高.无论您有多少孩子,即使是不同的填充,您也可以随时执行此操作.它只有一个未知(`h_p`)和一个等式. (2认同)

Chu*_*ars 28

为"N%"裕度(和填充)是相同的为边距/容限右/边距/利润率左,所有四个都必须相对于相同的基.如果顶部/底部使用与左/右不同的底部,那么"n%"边距(和填充)在所有四个边上都不会意味着相同的东西.

(另请注意,相对于宽度具有顶部/底部边距会启用奇怪的CSS hack,允许您指定具有不变宽高比的框...即使重新调整框也是如此.)

  • "n%边际(和填充)并不意味着所有四方都是一样的" - 但为什么那会是一个问题呢? (4认同)

Joy*_*Joy 5

在玩过这个JSFiddle(在 Chrome 46.0.2490.86 上)并参考这篇文章(用中文写的)后,我投票支持 @ChuckKollars 的答案。


反对无限计算猜想的一个主要原因是:usingwidth面临同样的无限计算问题。

看一下这个JSFiddleparent显示的是inline-block,它可以在其上定义边距/填充。具有child保证金价值20%。如果我们按照无限计算猜想:

  1. 的宽度child取决于parent
  2. 的宽度parent取决于child

但结果,Chrome 在某处停止了计算,结果是:

在此输入图像描述

如果你尝试在 JSFiddle 上水平展开“结果”面板,你会发现它们的宽度不会改变。请注意, 中的内容child被包装成两行(而不是一行),为什么?我猜 Chrome 只是在某个地方硬编码了它。如果你编辑child内容使其变得更多(JSFiddle),你会发现只要水平有额外的空间,Chrome就会将内容保留两行。

所以我们可以看到:有一些方法可以防止无限计算


我同意这样的猜想:这种设计只是为了保持四个margin/padding值基于相同的度量。

这篇文章(中文写的)还提出了另一个原因:是因为阅读/排版的方向。我们从上到下阅读,宽度固定,高度无限(实际上)。