многоточие переполнения текста не работает во вложенном flexbox

У меня есть двухколоночный макет, созданный с помощью flexbox.

В правом столбце у меня есть две строки, первая из которых содержит заголовок, а вторая — содержимое страницы.

В заголовке у меня есть три столбца, кнопка, текст и кнопка.

Я хочу, чтобы кнопки располагались слева и справа от столбца, а текст занимал дополнительное место.

Наконец, я хочу, чтобы текст имел свойства white-space:nowrap и text-overflow:ellipsis для усечения длинных заголовков.

Моя проблема заключается в следующем: я не могу заставить корректно работать обтекание текстом в flexbox, который вложен в другой flexbox, как показано в этой скрипке:

http://jsfiddle.net/maxmumford/rb4sk3mz/3/

.container {
  display: flex;
  height: 100vh;
}
.left {
  width: 200px;
  background-color: yellow;
}
.right {
  flex: 1;
  background-color: blue;
  color: white;
}
.header {
  background: red;
  color: white;
  display: flex;
  flex-direction: row;
}
.header .content {
  white-space: nowrap;
  flex: 0 1 auto;
  text-overflow: ellipsis;
  overflow: hidden;
  min-width: 0;
}
.header .buttons {
  background: green;
  flex: 1 0 auto;
}
.header .content:hover {
  white-space: normal;
}
<div class="container">

  <div class="left">
    content left
  </div>
  <div class="right">
    <div class="header">
      <div class="buttons">buttons</div>
      <div class="content">
        This content is really long and should wrap with ellipses, but for some reason it doesn't work when it's nested in a container with display: flex
      </div>
      <div class="buttons">buttons</div>
    </div>
    content right
  </div>

</div>

Однако точно такой же код работает, когда заголовок не вложен во flex-бокс:

http://jsfiddle.net/maxmumford/p7115f2v/1/

.header {
  background: red;
  color: white;
  display: flex;
  flex-direction: row;
}
.header .content {
  white-space: nowrap;
  flex: 0 1 auto;
  text-overflow: ellipsis;
  overflow: hidden;
  min-width: 0;
}
.header .buttons {
  background: green;
  flex: 1 0 auto;
}
<div class="header">
  <div class="buttons">buttons</div>
  <div class="content">
    This content is really long and is wrapped correctly... This content is really long and is wrapped correctly... This content is really long and is wrapped correctly... This content is really long and is wrapped correctly... This content is really long
    and is wrapped correctly... This content is really long and is wrapped correctly... This content is really long and is wrapped correctly...
  </div>
  <div class="buttons">buttons</div>
</div>

Как я могу добиться того, чего хочу, на первой скрипке?

Спасибо


person Max Mumford    schedule 03.10.2016    source источник


Ответы (3)


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

  1. div.right содержит div.header, который, в свою очередь, содержит кнопку и текст.

    div.right — это гибкий элемент в основном контейнере (.container).

    По умолчанию гибкий элемент не может быть меньше размера его содержимого. Начальная настройка гибких элементов — min-width: auto.

    Это означает, что длина вашего текста, который не переносится, будет устанавливать минимальный размер для родительских flex-элементов. Один из способов позволить гибким элементам сжиматься за пределы своего содержимого — установить для гибких элементов значение min-width: 0.

    Вы уже сделали это для гибкого элемента .content, но его также необходимо установить для элемента .right.

  2. У вас есть элемент .content, установленный на flex: 0 1 auto.

    Это говорит гибкому элементу использовать размер содержимого (flex-basis: auto). Текст задает размер.

    Вместо этого установите ширину на 0 и позвольте гибкому контейнеру распределять пространство по мере необходимости. Это можно сделать с помощью flex: 1 1 0, который аналогичен flex: 1. .

.container {
  display: flex;
  height: 100vh;
}
.left {
  width: 200px;
  background-color: yellow;
}
.right {
  flex: 1;
  background-color: blue;
  color: white;
  min-width: 0;             /* NEW */
}
.header {
  background: red;
  color: white;
  display: flex;
  flex-direction: row;
}
.header .content {
  white-space: nowrap;
  flex: 1;                  /* ADJUSTMENT */
  text-overflow: ellipsis;
  overflow: hidden;
  min-width: 0;
}
.header .buttons {
  background: green;
  flex: 1 0 auto;
}
.header .content:hover {
  white-space: normal;
}
<div class="container">

  <div class="left">
    content left
  </div>
  <div class="right">
    <div class="header">
      <div class="buttons">buttons</div>
      <div class="content">
        This content is really long and should wrap with ellipses, but for some reason it doesn't work when it's nested in a container with display: flex
      </div>
      <div class="buttons">buttons</div>
    </div>
    content right
  </div>

</div>

пересмотренная скрипта

person Michael Benjamin    schedule 04.10.2016
comment
Для родительского объекта также может потребоваться установить значение min-width: 0px, если его размер вычисляется с помощью CSS. - person aero; 15.08.2018

Значения:

white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;

Будет работать, только если содержимое вашего элемента превышает его ширину.

Вы можете установить ширину .header .content:

.header .content {
    width: 50%;
}

И он будет работать так, как вы ожидаете:
http://jsfiddle.net/t82pqks4/

person Dekel    schedule 03.10.2016
comment
Спасибо, но это заставляет контейнер заголовка превышать ширину страницы, вызывая горизонтальную полосу прокрутки. - person Max Mumford; 04.10.2016
comment
Два jsfiddles в вашем вопросе очень разные (hover/left-menu/etc). Не могли бы вы объяснить, что именно вы ищете? Из вашего вопроса не так ясно. - person Dekel; 04.10.2016

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

Внутри столбца flex, в котором есть копия, которую вы хотите обернуть, вам нужно сделать это.

.row {
  display: flex;
}

.col1 {
 position: relative;
 flex: 1 1 70%;
 overflow: hidden;
}

.nested {
  width: 100%;
  position: absolute;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.col2 {
  flex: 1 1 30%;
  padding-left: 1rem;
}
<div class="row">
  <div class="col1">
     <div class="nested">This is my really long copy that will push it out of the screen, and will not respect the elippse no matter what I do!!!</div>
  </div>
  <div class="col2">
    Last Text
  </div>
</div>

person user1015434    schedule 22.12.2020