如何在带有嵌套flexbox的flexbox子项之间平均分配宽度?

时间:2019-06-12 18:49:50

标签: html css flexbox

我正在为正在构建的网站使用一些CSS3。我正在尝试制作一个使用flexbox使其所有子级具有相等宽度的“容器”类。这可以正常工作,但是当我在另一个“容器”中放置一个“容器”和一个普通元素时,两个子元素的宽度不相等。

我不确定为什么它不起作用,因为它适用于不是容器的任何元素。

HTML:

<div class="container">
  <div class="container">
    <div class="content-box">
      One Sixth
    </div>
    <div class="content-box">
      One Sixth
    </div>
    <div class="content-box">
      One Sixth
    </div>
  </div>
  <div class="content-box">
    One half
  </div>
</div>

CSS:

.container {
    display: flex;
    align-items: flex-start;
}

.container > * {
    flex-basis: 100%;
    min-width: 0;
}

.container > :not(:first-child) {
    margin-left: 2%;
}

Codepen示例:https://codepen.io/NetworkOverflow/pen/XLbdqa

2 个答案:

答案 0 :(得分:1)

问题是,当您将容器放入容器中时,它会增加边距,因此您会在右侧看到两倍的空间。

我会将您的容器设置为justify-content: space-between;,这会将内容元素推到外部边缘。我使用flex:1而不是flex-basis来告诉浏览器每个元素应该占用相同的空间。

您的CSS变为:

.container {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
}

.container > * {
    flex: 1;
    margin-left: 2%;
    min-width: 0;
}

.container > *:first-child {
    margin-left:0;
}

/* not needed
.container > :not(:first-child) {
    margin-left: 2%;
}
*/

更新:

根据用法,添加“大小调整”类有时会很有帮助,该类根据项目的数量强制使用flex-basis。这是一个codepen示例。

.third {
  flex-basis: calc(33.3333% - 2%);
}
.half {
  flex-basis: calc(33.3333% - 2%);
}

答案 1 :(得分:1)

您要为将所有元素设置为flex-basis: 100%而付出代价。

由于您要告诉所有元素(无论它们具有多少同级元素)要占据容器的整个宽度,因此您强制flex-shrink计算容纳所有元素的必要空间。 / p>

这涉及到一个相对复杂的flexbox算法,当您将填充和box-sizing: border-box都考虑在内时,这两种算法都变得更加复杂。

此处说明了算法:How does flex-shrink factor in padding and border-box?

最快,最简单的解决方案是指定容器的实际宽度。

对于说明问题的行(带有容器以及容器中的容器),不要将它们设置为flex-basis: 100%并触发flex-shrink,而是将它们设置为flex-basis: 50%。现在避免了flex-shrink流程,您将得到想要的东西。

我将其添加到您的代码中

.container > .demo50 {
  flex-basis: 50%;
}

revised demo

div.content {
  float: left;
  width: 100%;
  height: 100%;
  background-color: var(--background-color2);
  padding: 2% 10%;
}

div.banner {
  background-color: var(--scheme-color2);
  box-shadow: 0px 0px 50px 10px rgba(23, 196, 167, 0.5);
  padding: 1rem;
  text-align: center;
  margin-bottom: 2em;
}

.content-box {
  background-color: var(--background-color1);
  box-shadow: 0px 0px 10px 5px rgba(84, 84, 84, 1);
  padding: 1rem;
  overflow-wrap: break-word;
  margin-bottom: 2em;
}

.container {
  display: flex;
  align-items: flex-start;
}

.container > * {
  flex-basis: 100%;
  min-width: 0;
}

.container > :not(:first-child) {
  margin-left: 2%;
}

.two-thirds {
  flex-basis: calc(100% / 3 * 2);
}

.container > .demo50 {
  flex-basis: 50%;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

:root {
  --background-color1: #707070;
  --background-color2: #424242;
  --background-color3: #afafaf;
  --scheme-color1: #20f9d5;
  --scheme-color2: #17c4a7;
  --scheme-color3: #89e5d6;
  --text-color: #e3edeb;
}

body {
  font-family: "Open Sans", sans-serif;
  color: var(--text-color);
}
<div class="content">
  <div class="container">
    <div class="banner">
      <h1>Example</h1>
    </div>
  </div>
  <div class="container">
    <div class="content-box">
      <p>Using 'flex-basis: 100%' seems to work perfectly well for evenly sizing and spacing elements in a row. However, when you put a .container inside a .container and attempt to do something like you see two rows below, the .container element and the
        element that follows do not space themselves at half and half width.</p>
    </div>
  </div>
  <div class="container">
    <div class="content-box">
      One Half
    </div>
    <div class="content-box">
      One Half
    </div>
  </div>
  <div class="container">
    <div class="container demo50">
      <div class="content-box">
        One Sixth
      </div>
      <div class="content-box">
        One Sixth
      </div>
      <div class="content-box">
        One Sixth
      </div>
    </div>
    <div class="content-box demo50">
      One half
    </div>
  </div>
  <div class="container">
    <div class="content-box">
      One Third
    </div>
    <div class="content-box">
      Two Thirds
    </div>
    <div class="content-box">
      Three Thirds
    </div>
  </div>
  <div class="container">
    <div class="content-box two-thirds">
      Two Thirds
    </div>
    <div class="content-box">
      One Third
    </div>
  </div>
  <div class="container">
    <div class="content-box">
      One Third
    </div>
    <div class="content-box two-thirds">
      Two Thirds
    </div>
  </div>
</div>