如何让 flexbox 在计算中包含填充?

Posted

技术标签:

【中文标题】如何让 flexbox 在计算中包含填充?【英文标题】:How to get flexbox to include padding in calculations? 【发布时间】:2016-10-13 14:41:07 【问题描述】:

下面是两行。

第一行flex 1 的两个项目和flex 2 的一个项目。

第二行flex 1处的两个项目。

根据规范1A + 1B = 2A

但是当 padding 包含在计算中时,总和不正确,如下例所示。


问题

如何让弹性盒子在其计算中包含填充,以便示例中的盒子正确排列?

.Row
  display:flex;

.Item
  display:flex;
  flex:1;
  flex-direction:column;
  padding:0 10px 10px 0;

.Item > div
  background:#7ae;

.Flx2
  flex:2;
<div class="Row">
  <div class="Item">
    <div>1A</div>
  </div>
  <div class="Item">
    <div>1B</div>
  </div>
  <div class="Item Flx2">
    <div>1C</div>
  </div>
</div>

<div class="Row">
  <div class="Item">
    <div>2A</div>
  </div>
  <div class="Item">
    <div>2B</div>
  </div>
</div>

【问题讨论】:

【参考方案1】:

解决办法:

在子元素上设置margin,而不是在flex 项目上设置padding

.Row
  display:flex;

.Item
  display:flex;
  flex:1;
  flex-direction:column;

.Item > div
  background:#7ae;
  margin:0 10px 10px 0;

.Flx2
  flex:2;
<div class="Row">
  <div class="Item">
    <div>1A</div>
  </div>
  <div class="Item">
    <div>1B</div>
  </div>
  <div class="Item Flx2">
    <div>1C</div>
  </div>
</div>

<div class="Row">
  <div class="Item">
    <div>2A</div>
  </div>
  <div class="Item">
    <div>2B</div>
  </div>
</div>

问题:

计算是在没有padding 的情况下完成的。所以;将 padding 添加到 flex 元素不会给您预期的宽度 spec.

The specific article

例如,浮动的自动调整大小的弹性容器中弹性项目的可用空间是:

flex 容器包含块的宽度减去 flex 容器在水平维度上的边距、边框和填充 垂直维度无限

为什么不计算填充?这就是规范想要的。

确定flex 项的可用maincross 空间。对于每个维度,如果flex container的内容框的那个维度是一个确定的大小,使用那个;如果flex container 的该维度在minmax-content 约束下调整大小,则该维度中的可用空间就是该约束;否则,从该维度中 flex 容器的可用空间中减去 flex 容器的边距、边框和填充,并使用该值这可能会导致无限的价值。

如果你从元素的大小中减去paddingmargin,你会得到:

1A + 1B = 2A

但是,在你这样做之后,填充被添加到元素中。元素越多,填充越多。这不是在宽度中计算的,导致您的陈述是错误的。

【讨论】:

这不仅解决了我的问题,而且对理解 flex 也很有帮助。谢谢。 使用边距而不是内边距的问题是,当您将鼠标悬停在边距部分时,它不会算作您悬停在该元素上。 当您需要边框填充时,它也无济于事。我希望设置 box-sizing: border box; 会有所帮助,但没有这样的运气...... 不太清楚:您突出显示的规范部分说:"...从可用空间中减去 flex 容器的边距、边框和填充..." 但是填充不在弹性容器上。它在弹性项目上。 (嵌套的 flex 容器与问题无关。)所以我不确定这些摘录是否适用。【参考方案2】:

如何让 flexbox 在计算中包含填充?

在您的代码中,填充 包含在计算中。

根据规范1A + 1B = 2A

我不相信这是正确的。也许提供一个链接参考来解释。


flex-grow 属性

当您将flex: 1 应用于元素时,您使用的是flex 速记属性来表示:

flex-grow: 1 flex-shrink: 1 flex-basis: 0

flex-grow 告诉弹性项目消耗容器中的可用空间。

这是你的代码:

.Item 
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: 0 10px 10px 0;

在第一行,padding-right: 10px 应用于 三个 弹性项目。

在第二行中,padding-right: 10px 应用于 两个 弹性项目。

因此,第一行的可用空间减少了 10 像素。这会破坏网格的对齐方式。

对于分配空间(例如,您希望元素占据容器的剩余高度或宽度),请使用flex-grow

要精确调整弹性项目的大小,请使用 flex-basiswidthheight

这里有更多信息:

flex-grow not sizing flex items as expected How exactly does flex-grow work with flexbox?

【讨论】:

【参考方案3】:

您可以使用浮动的伪块元素而不是填充,如下所示: (在本例中为 30px 右内边距)

.Item:after 
  content: '';
  display: block;
  float: right;
  width: 30px;
  height: 100%;

【讨论】:

每个元素都有很多额外的标记。我认为这不是一个好的解决方案。

以上是关于如何让 flexbox 在计算中包含填充?的主要内容,如果未能解决你的问题,请参考以下文章

聊聊Flexbox布局中的flex的演算法

flexbox布局

我怎样才能让 Flexbox 孩子 100% 的高度是他们的父母?

Flexbox - 填充剩余空间[重复]

css3弹性盒模型(Flexbox)

React Native知识1-FlexBox 布局内容