Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent a child element from overflowing its parent in flexbox [duplicate]

Tags:

html

css

flexbox

I'm working on a web app that shows a large grid of cards, the height of which is inherently variable.

In the interests of aesthetics, we were using jQuery's .matchHeight() to equalise the height of cards within each row.

The performance of that didn't scale well, so today I've been migrating to a flex-box based solution which is so much faster.

However, I've lost a behaviour - the content of the card header should be truncated with an ellipsis if it won't fit.

Goals:

  1. 3 columns
  2. Column widths vary to fill parent
  3. Constant spacing between columns
  4. Heights equalised within a row

How do I arrange for the container size to be respected and the text-overflow: ellipsis; and white-space: nowrap; to be honoured?

(No jQuery tag as we're moving away from that)

My solution in it's current form, which achieves all of my goals apart from the truncation:

https://codepen.io/anon/pen/QvqZYY

#container {                   display: flex;                   flex-direction: row;                   flex-wrap: wrap;                                     justify-content: flex-start;    /* Bias cards to stack from left edge       */                   align-items: stretch;           /* Within a row, all cards the same height  */                                     border: thin solid gray;               }               .card-wrapper {                   width: 33.33%;                   display: flex;                   background: #e0e0ff;               }               .card {                   flex-grow: 1;                   margin: 7px;                   display: flex;                   flex-direction: column;                   border: thin solid gray;                   background: #e0ffff;               }               .card div {                   border: thin solid gray;               }               .card div:nth-child(1) {                   white-space: nowrap;                   text-overflow: ellipsis;               }               .card div:nth-child(2) {                   flex-grow: 2;               } 
<div id="container">               <div class="card-wrapper">                   <div class="card">                       <div>Title</div>                       <div>Multiline<br/>Body</div>                       <div>Footer</div>                   </div>               </div>               <div class="card-wrapper"><div class="card"><div>Really long rambling title that pushes beyond the bounds of the container, unless your screen is really, really wide</div><div>Body</div><div>Footer</div></div></div>               <div class="card-wrapper"><div class="card"><div>Title</div><div>Body</div><div>Footer</div></div></div>               <div class="card-wrapper"><div class="card"><div>Title</div><div>Body</div><div>Footer</div></div></div>               <div class="card-wrapper"><div class="card"><div>Title</div><div>Body</div><div>Footer</div></div></div>           </div> 
like image 512
Chris Avatar asked May 05 '17 16:05

Chris


People also ask

How do you stop a child DIV from overflowing parent DIV?

You could simply set the container to flexbox. Another option would be using CSS table, some extra HTML code is needed. And max-height doesn't work with table layout, so use height instead.

Which flex property is used to prevent child element to flow out of parent width?

To override this behavior, use min-width: 0 or overflow: hidden .

Why are my flex items overflowing?

The initial value of the flex-wrap property is nowrap . This means that if you have a set of flex items that are too wide for their container, they will overflow it.


1 Answers

An initial setting on flex items is min-width: auto. This means that a flex item, by default, cannot be smaller than the size of its content.

Therefore, text-overflow: ellipsis cannot work because a flex item will simply expand, rather than permit an overflow. (Scroll bars will not render either, for the same reason.)

To override this behavior, use min-width: 0 or overflow: hidden. More details.

#container {    display: flex;    flex-wrap: wrap;    border: thin solid gray;  }    .card-wrapper {    width: 33.33%;    display: flex;    background: #e0e0ff;  }    .card {    flex-grow: 1;    margin: 7px;    display: flex;    flex-direction: column;    border: thin solid gray;    background: #e0ffff;    overflow: hidden;        /* NEW */  }    .card div {    border: thin solid gray;  }    .card div:nth-child(1) {    white-space: nowrap;    text-overflow: ellipsis;    overflow: hidden;        /* NEW */  }    .card div:nth-child(2) {    flex-grow: 2;  }
<div id="container">    <div class="card-wrapper">      <div class="card">        <div>Title</div>        <div>Multiline<br/>Body</div>        <div>Footer</div>      </div>    </div>    <div class="card-wrapper">      <div class="card">        <div>Really long rambling title that pushes beyond the bounds of the container, unless your screen is really, really wide</div>        <div>Body</div>        <div>Footer</div>      </div>    </div>    <div class="card-wrapper">      <div class="card">        <div>Title</div>        <div>Body</div>        <div>Footer</div>      </div>    </div>    <div class="card-wrapper">      <div class="card">        <div>Title</div>        <div>Body</div>        <div>Footer</div>      </div>    </div>    <div class="card-wrapper">      <div class="card">        <div>Title</div>        <div>Body</div>        <div>Footer</div>      </div>    </div>  </div>
like image 154
Michael Benjamin Avatar answered Oct 07 '22 16:10

Michael Benjamin