Почему внутренняя ширина гибкого трубопровода переполнена?

#html #css #flexbox

Вопрос:

Друзья. Рассмотрим простой следующий пример, который показался мне не таким простым. Наверное, я что-то упускаю.

 .wrapper {
  display: flex;
}

.box {
  display: flex;
}

.width {
  /*    width: auto; */
  width: 150px;
  background: green;
}

.box>* {
  flex: 0 0 auto;
  max-width: 50%;
  border: 1px solid red;
} 
 <div class="wrapper">
  <div class="box">
    <div>
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div>Two</div>
    <div>Three</div>
  </div>
</div> 

Кодовый набор

.wrapper элемент имеет display: flex , а также .box элемент.

div с шириной класса имеет явно заданную ширину 190 пикселей; это больше, чем ширина содержимого, но все равно эта ос div перекрывает свой контейнер

Если вы установите ширину на авто или удалите дисплей: flex из .wrapper div, все в порядке, почему ?

Комментарии:

1. вам нужно подробное объяснение или простое исправление?

2. Объяснение. Я хочу понять, как рассчитывается ширина .box -> div, а также самого контейнера .box

Ответ №1:

Удалите max-width: 50% настройку из последнего правила. Это противоречит width: 190px настройкам для .width класса.

Конфликт заключается в том , что width параметр для .width класса применяется к дочернему элементу первого гибкого элемента, а не к самому этому гибкому элементу, поэтому дочерний элемент шире, чем элемент гибкого элемента, разрешенный max-width: 50% настройкой.

 .wrapper {
  display: flex;
}

.box {
  display: flex;
}

.width {
  /*    width: auto; */
  width: 190px;
  background: green;
}

.box>* {
  flex: 0 0 auto;
  border: 1px solid red;
} 
 <div class="wrapper">
  <div class="box">
    <div>
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div>Two</div>
    <div>Three</div>
  </div>
</div> 

Если вы примените width настройку непосредственно к первому дочернему элементу flex, ситуация изменится, т. е. ширина 190 пикселей сохранена не будет:

 .wrapper {
  display: flex;
}

.box {
  display: flex;
}

.width {
  /*    width: auto; */
  width: 190px;
  background: green;
}

.box>* {
  flex: 0 0 auto;
  border: 1px solid red;
  max-width: 50%;
} 
 <div class="wrapper">
  <div class="box">
    <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    <div>Two</div>
    <div>Three</div>
  </div>
</div> 

Комментарии:

1. я знаю о максимальной ширине. но как рассчитывается ширина .box > div, если вы сохраняете максимальную ширину ? пример разметки такой же, как и в начальной загрузке, отсюда мой вопрос. html: .строка(дисплей: гибкий) > .col-6(максимальная ширина: 50%) .col-6(максимальная ширина: 50%). Представьте, что внутри есть элемент с фиксированной шириной. Вы получите тот же результат переполнения

2. пожалуйста, обратите внимание на дополнение к моему ответу (второй абзац)

3. Я отметил это, ty. max-width не конфликтует, он скорее захватывает свойство width, не позволяя ему расти более чем на 50%. Но 50% чего ? Из .коробчатого контейнера и какова его ширина ? Рассчитано его дочерью ? Один из его дочерних элементов-чистый <div> с другим div шириной 190 пикселей внутри. Вот что меня беспокоит. Почему бы не сделать ширину .box на основе максимального содержимого, как указано в спецификации, и не увеличить его, а не переполнять

4. Да, я согласен, это не логичное поведение. Я только что попробовал несколько вещей, но также не могу получить более удовлетворительного результата. Хотя обычно контейнеры flex имеют заданную ширину, так как в большинстве случаев одной из основных целей является распределение дочерних элементов flex по всей ширине (или высоте) родительского элемента.

Ответ №2:

Вы сталкиваетесь со сложным расчетом ширины из-за циклической зависимости

Чтобы лучше понять, вам нужно сравнить до и после добавления max-width

 .wrapper {
  display: flex;
  margin:5px;
}

.box {
  display: flex;
  border:4px solid blue;
}

.width {
  width: 150px;
  background: green;
}

.box>* {
  flex: 0 0 auto;
  border: 1px solid red;
} 
 <div class="wrapper">
  <div class="box">
    <div>
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div>Two</div>
    <div>Three</div>
  </div>
</div>

<div class="wrapper">
  <div class="box">
    <div style="max-width: 50%;">
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div style="max-width: 50%;">Two</div>
    <div style="max-width: 50%;">Three</div>
  </div>
</div> 

Обратите внимание, что в обоих случаях синий прямоугольник ( .box элемент) имеет одинаковую ширину, основанную на ширине дочернего элемента (150 пикселей авто авто).

Здесь происходит то, что max-width:50% требуется разрешить ссылку, и эта ссылка является .box элементом, НО ширина .box зависит от его содержимого (потому что это гибкий элемент), поэтому у нас есть cylce. В этом случае браузер сначала проигнорирует максимальную ширину, вычислит ширину .box , а затем применит с max-width:50% учетом вычисленной ширины .box .

Ваш первый элемент составляет более 50% от общей ширины, поэтому применение max-width:50% к нему приведет к его сокращению, и у вас будет переполнение (150 пикселей > 50% (150 пикселей авто авто) )

Если бы один из других элементов был больше, вы, возможно, не столкнулись бы с переполнением, потому что 150 пикселей будут меньше 50%

 .wrapper {
  display: flex;
  margin:5px;
}

.box {
  display: flex;
  border:4px solid blue;
}

.width {
  width: 150px;
  background: green;
}

.box>* {
  flex: 0 0 auto;
  border: 1px solid red;
} 
 <div class="wrapper">
  <div class="box">
    <div>
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div>Two Two Two Two Two Two</div>
    <div>Three</div>
  </div>
</div>

<div class="wrapper">
  <div class="box">
    <div style="max-width: 50%;">
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div style="max-width: 50%;">Two Two Two Two Two Two</div>
    <div style="max-width: 50%;">Three</div>
  </div>
</div> 

Если удалить display:flex , проблема не возникнет, потому .box что больше нет гибкого элемента, и его ширина больше не зависит от его содержимого. Он имеет полную ширину по умолчанию:

 .wrapper {
  margin:5px;
}

.box {
  display: flex;
  border:4px solid blue;
}

.width {
  width: 150px;
  background: green;
}

.box>* {
  flex: 0 0 auto;
  border: 1px solid red;
} 
 <div class="wrapper">
  <div class="box">
    <div>
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div>Two</div>
    <div>Three</div>
  </div>
</div>

<div class="wrapper">
  <div class="box">
    <div style="max-width: 50%;">
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div style="max-width: 50%;">Two</div>
    <div style="max-width: 50%;">Three</div>
  </div>
</div> 

Как вы можете видеть max-width:50% , теперь он больше ширины вашего элемента, поэтому переполнения нет.

При использовании width:auto у вас не возникнет проблем, потому что авто для элемента блока означает использование всей доступной ширины, поэтому ваш элемент будет уменьшаться, а div внутри также будет уменьшаться вместе с ним.

 .wrapper {
  margin:5px;
  display: flex;
}

.box {
  display: flex;
  border:4px solid blue;
}

.width {
  background: green;
}

.box>* {
  flex: 0 0 auto;
  border: 1px solid red;
} 
 <div class="wrapper">
  <div class="box">
    <div>
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div>Two</div>
    <div>Three</div>
  </div>
</div>

<div class="wrapper">
  <div class="box">
    <div style="max-width: 50%;">
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div style="max-width: 50%;">Two</div>
    <div style="max-width: 50%;">Three</div>
  </div>
</div> 

Вот пример с изменяемым размером вашего внутреннего div, чтобы вы могли поиграть и посмотреть, как он себя ведет:

 .wrapper {
  margin:5px;
  display: flex;
}

.box {
  display: flex;
  border:4px solid blue;
}

.width {
  background: green;
  width:300px;
  resize:horizontal;
  overflow:hidden;
}

.box>* {
  flex: 0 0 auto;
  max-width:50%;
  border: 1px solid red;
} 
 <div class="wrapper">
  <div class="box">
    <div>
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
    <div>Two</div>
    <div>Three</div>
  </div>
</div> 

У вас всегда будет переполнение, когда W > 50%*(W auto) где авто ссылается на автоматическую ширину других элементов.

Давайте сделаем auto=0 это, удалив других дивов

 .wrapper {
  margin:5px;
  display: flex;
}

.box {
  display: flex;
  border:4px solid blue;
}

.width {
  background: green;
  width:300px;
  resize:horizontal;
  overflow:hidden;
}

.box>* {
  flex: 0 0 auto;
  max-width:50%;
  border: 1px solid red;
} 
 <div class="wrapper">
  <div class="box">
    <div>
      <div class="width">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
    </div>
  </div>
</div> 

Всегда переполнение, потому W > 50%*W что это всегда правда!

Комментарии:

1. Тай за такое подробное объяснение. Я никогда раньше не задумывался о расчетах ширины велосипедной дорожки. Это очень хорошее знание, о котором стоит подумать. Я вернусь позже к вашему ответу, обдумаю его и отмечу в качестве ответа.