Как равномерно распределить ширину между дочерними элементами flexbox с помощью вложенных flexbox? - PullRequest
0 голосов
/ 12 июня 2019

Я работаю над 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%;
}

Пример кодекса: https://codepen.io/NetworkOverflow/pen/XLbdqa

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Вы платите цену за установку всех элементов на flex-basis: 100%.

Поскольку вы говорите всем элементам, независимо от того, сколько у них братьев и сестер, они могут занимать всю ширину контейнеравы заставляете flex-shrink вычислять пространство, необходимое для размещения их всех.

Это включает в себя относительно сложный алгоритм flexbox, который становится еще более сложным, когда вы учитываете заполнение, и box-sizing: border-box, оба из которыхсуществует в вашем коде.

Алгоритм объяснен здесь: Как изгибается и сокращается коэффициент в отступах и рамке?

Самым быстрым и простым решением было быукажите действительную ширину контейнеров.

Для строки, иллюстрирующей проблему (с контейнером и контейнером внутри контейнера), вместо установки их на flex-basis: 100%, что вызывает flex-shrink, установите ихдо flex-basis: 50%.Теперь процесс flex-shrink исключен, и вы получаете то, что хотите.

Я добавил это к вашему коду:

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

пересмотренная демоверсия

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>
1 голос
/ 12 июня 2019

Проблема в том, что когда вы помещаете контейнер внутрь контейнера, он добавляет поле, чтобы вы увидели двойной пробел справа.

Я бы установил для вашего контейнера значение 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%);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...