如何计算保证金百分比值

Posted

技术标签:

【中文标题】如何计算保证金百分比值【英文标题】:How is the margin percentage value calculated 【发布时间】:2022-01-24 03:57:13 【问题描述】:

我知道margin的百分比值基于其包含块的宽度。

当我为框的边距分配了准确的值,并且边距框没有溢出父元素时,它按预期工作。

但是当我分配百分比值时,margin-rightmargin-inline-end 将会增长,就像在 Firefox 或 Chrome

中的 margin-right: auto;

那么,这是规范要求,还是浏览器实现中的巧合。

var exact = document.querySelector('.exact')
var percent = document.querySelector('.percent')

exact.innerText = 'Computed margin-right: ' + getComputedStyle(exact).getPropertyValue('margin-right')
percent.innerText = 'Computed margin-right: ' + getComputedStyle(percent).getPropertyValue('margin-right')
body 
  margin: 0;


.wrap 
  margin: 20px auto;
  width: 200px;
  height: 200px;
  background-color: cadetblue;
  border: 1px solid transparent;


.box 
  width: 100px;
  height: 100px;
  background-color: antiquewhite;


.exact 
  margin: 20px;


.percent 
  margin: 10%
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>margin right</title>
</head>

<body>
  <div class="wrap">
    <div class="box exact"></div>
  </div>
  <div class="wrap">
    <div class="box percent"></div>
  </div>
</body>

</html>

【问题讨论】:

这取决于元素的父元素的display: 属性。 另外,如果一个元素曾经被所有不同的大小相关属性过度约束,那么margin: 属性的值is ignored and it's treated as auto 可以解释你所看到的。 @dai “过度约束”是什么意思?在这两种情况下,边距框都不会溢出父内容 但是当我分配百分比值时,margin-right 或 margin-inline-end 会增长,就像 margin-right: auto;无论是在 Firefox 还是 Chrome 中 --> 向我们展示产生这种结果的代码 @temani-afif 我已经编辑了问题:) 【参考方案1】:

我认为对此没有一个非常令人满意的答案。但我会带你了解可用的信息。

首先,更正您关于 Chrome 和 Firefox 行为相同的断言。至少在 Windows 上,它们没有。对于百分比边距情况,Chromium 浏览器报告的边距值是 20px,而 Firefox 报告的是 80px

现在,关于过度约束:对于in-flow, non-replaced block level elements,例如您的示例中的divs,此等式必须适用于已使用的属性值。

margin-left + border-left-width + padding-left + width + 
padding-right + border-right-width + margin-right = width of containing block

插入您分配的值以及等式左侧的默认值,我们得到两个示例

20px + 0px + 0px + 100px + 0px + 0px + 20px = 140px.

等式的右边

200px

所以等式表示:140px = 200px。

这显然是错误的,因此至少需要更改其中一个值才能使等式成立。当布局方向是从左到右时,改变的是margin-right值。因此 margin-right 属性的值被更改为 80px。所有浏览器都正确地进行了这种调整,并且已经这样做了多年。


但要求相等性仅适用于属性的使用值计算的值不需要保留。因此,如果getComputedValue() 返回计算值,他们应该报告未调整的值。 margin-right 的规范告诉我们计算的值是“指定的百分比或绝对长度”。因此,对于指定长度的示例,它将报告“20px”,而对于指定百分比的示例,它将报告“10%”的边距值。

然而,CSSOM 规范告诉我们“getComputedValue”只是一个名称,为了向后兼容,它实际上返回了resolved value。解析的值有时是计算值,有时是使用值,在某些特殊情况下两者都不完全一样。

对于margin-right,它表示对于您的示例,解析的值是使用的值。 margin-right 值的使用值应包括计算值的两个适应值。 (i) 如果尚未将该值转换为像素值,并且 (ii) 应应用过度约束调整。所以 getComputedValue() 在这两个例子中都应该返回 80px 作为 margin-right。


因此,虽然 Chrome 和 Firefox 都报告了第一次调整的结果,总是报告像素值,但 Chrome 和 Firefox 都不会对指定长度的示例应用过度约束的调整,只有 Firefox 会为百分比指定示例。那么究竟发生了什么?很抱歉,这就是我们进行猜测的地方。

在处理遗留行为时,浏览器实际上并没有以线性方式遵循规范。实际发生的是,他们试图做最兼容网络的事情。 (即对现有网页造成最少问题的行为)。然后他们将此信息反馈给规范编写者,然后规范可以更新以匹配。有时,对于什么是最兼容网络的行为可能存在分歧。有时会出现新信息,从而改变人们对最适合网络的行为的看法。

在某些情况下,这可能会导致一些不正当的解决方案。 可以想象,但仅此而已,Firefox 开发人员已决定报告边距使用值之前对长度指定值和的过度约束调整在对指定边距右值百分比进行过度约束调整后,可提供最佳的网络兼容行为。并且 Chromium 开发人员要么不同意,要么不想复制这种不直观的结果。当然,这种对浏览器行为细节的分歧并不罕见。有时,浏览器制造商会尝试实现简单的事情,看看他们从网络开发社区得到了多少回击。

无论如何,最终 CSSOM 规范很可能会被修改以更好地反映浏览器的功能。该决议最终是什么还有待观察。

【讨论】:

感谢您在繁杂的规范中找到解决问题的线索,对于像我这样的初学者来说太晦涩难懂了。

以上是关于如何计算保证金百分比值的主要内容,如果未能解决你的问题,请参考以下文章

使用 MySQL 计算百分比值

margin/padding百分比值的计算

R计算数据框中的百分比值

我应该如何在核心数据中存储从 UISlider 读取的百分比值?

如何使 ConstraintLayout 使用百分比值?

保证金最高百分比是如何计算的?