Flexbox дочерний с "переполнением: скрытым" переполнением полей дедушки

Я пытаюсь вложить два дочерних элемента в оболочку, которая задает боковые поля, чтобы между его содержимым и сторонами экрана было свободное пространство, когда дисплей узкий, и max-width для дисплея широко.

Второй дочерний элемент имеет некоторое переполнение, которое должно быть видно, в то время как первый дочерний элемент должен находиться строго внутри поля содержимого оболочки. При удалении первого ребенка второй ребенок ведет себя так, как ему хочется. Однако, когда я добавляю первого дочернего элемента, он полностью игнорирует поля оболочки, растягивая окно содержимого оболочки и разрывая вместе с ним второй дочерний элемент.

Применение overflow: hidden к оболочке устраняет проблему с полями, но обрезает второго потомка. Применение полей к первому дочернему элементу не привело к его коллапсу с родительским элементом, поскольку в новом контексте форматирования блока.

Единственный обходной путь, который я нашел, - это сделать:

.wrapper {
    > * {
        margin-left: 1.5rem;
        margin-right: 1.5rem;
    }
}

и увеличьте максимальную ширину обертки на 3rem, но я надеялся, что найдется какое-то решение, которое не потребует от меня сдвига поля от обертки до ее дочерних элементов.

https://codepen.io/HybridCore/pen/jjoWmd

body {
  background-color: #000;
  color: #FFF;
  display: flex;
  justify-content: center;
}

.wrapper {
  margin: 0 1.5rem;
  max-width: 40rem;
  width: 100%;
}

.fit_content_box {
  display: flex;
  align-items: center;
}

.L {
  min-width: 0;
  flex: 1 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.R {
  margin-left: 1rem;
  height: 1rem;
  width: 1rem;
  background-color: #FFF;
}

.overflow {
  display: flex;
  justify-content: space-between;
}

.overflow>div {
  width: 0;
  display: flex;
  justify-content: center;
}
<body>
  <div class="wrapper">
    <div class="fit_content_box">
      <p class="L">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

      <div class="R"></div>
    </div>

    <div class="overflow">
      <div>
        <p>0</p>
      </div>
      <div>
        <p>12</p>
      </div>
      <div>
        <p>24</p>
      </div>
    </div>
  </div>
</body>

Ответ 1

В основном у вас есть две проблемы:

  1. Вы устанавливаете width:100% на обертку, и это не учитывает поля, поэтому у вас будет логическое переполнение, и, поскольку тело является гибким контейнером с justify-content:center, поле будет переполнено в равной степени с обеих сторон, почему вы думаете, что оно не применено.
  2. Вы столкнулись с ограничением min-width flexbox, которое заставляет вас установить width:100%, считая его хорошим решением. Это же ограничение также препятствует сжатию элемента ниже указанного вами значения 100% (связано: Почему гибкий элемент ограничен родительским размером?)

Чтобы это исправить, вам нужно удалить width:100% из оболочки и рассмотреть вместо этого min-width:0. Вы также можете удалить min-width, примененный к .L, и вам нужно учитывать flex-shrink:0 в .R (или заменить его ширину на min-width)

body {
  background-color: #000;
  color: #FFF;
  display: flex;
  justify-content: center;
}

.wrapper {
  margin: 0 1.5rem;
  max-width: 40rem;
  min-width:0;
}

.fit_content_box {
  display: flex;
  align-items: center;
}

.L {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.R {
  margin-left: 1rem;
  flex-shrink:0;
  height: 1rem;
  width: 1rem;
  background-color: #FFF;
}

.overflow {
  display: flex;
  justify-content: space-between;
}

.overflow>div {
  width: 0;
  display: flex;
  justify-content: center;
}
<body>
  <div class="wrapper">
    <div class="fit_content_box">
      <p class="L">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

      <div class="R"></div>
    </div>

    <div class="overflow">
      <div>
        <p>0</p>
      </div>
      <div>
        <p>12</p>
      </div>
      <div>
        <p>24</p>
      </div>
    </div>
  </div>
</body>

Ответ 2

Похоже, что источником проблемы является white-space: nowrap, который применяется к элементу содержимого (.L) внутри первого дочернего элемента (.fit_content_box).

.L {
    border: solid 1px #FF0000;
    min-width: 0;
    flex: 1 0;
    overflow: hidden;
    white-space: nowrap;    <--- trouble maker
    text-overflow: ellipsis;
}

Если вы удалите эту строку кода, ваши боковые поля на .wrapper работать как положено.

Итак, ключевые вопросы:

  • Почему свойство white-space в grand-child (.L) сжимает боковые поля прародителя (.wrapper)?
  • Почему свойство white-space не сжимает боковые поля, когда они применяются к родителю (.fit_content_box)?
  • Почему overflow свойство, когда применяется к гранд-родителю (.wrapper), со значением, кроме visible, позволяет наценки крепко держаться на внучатом ребенке (.L)?

Вы написали:

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

На самом деле, это не проблема обычного обвала маржи, потому что:

  1. Мы говорим о горизонтальных полях, и горизонтальные поля никогда не разрушаются, и

  2. Мы работаем внутри гибкого контейнера, и поля внутри гибкого контейнера никогда не разрушаются.

Поэтому, хотя полное понимание проблемы может лежать в контексте блочного (или гибкого) форматирования, я не уверен, почему поля родительского поля не разрушаются.

Это насколько я получил по этому вопросу. Я сделаю больше исследований, когда у меня будет время. Или, может быть, кто-то еще может забрать его отсюда.