How to Truncate String Inside a Direction Column Flexbox Child

CSS Truncate text within a flexbox parent with flex-direction column

When you give align-items: center the text overflows the parent and the width is not constrained and so ellipsis will not appear.

If you remove align-items: center it works because align-items: stretch is the default - but the image get stretched out now:

.parent {  border: 1px solid red;  display: flex;  /*align-items: center;*/  flex-direction: column;  width: 300px;}
.text { white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis;}
<div class="parent">   <img src="http://placekitten.com/g/200/200" />  <div class="text">    Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum   </div></div>

Prevent a child element from overflowing its parent in flexbox

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>

text-overflow ellipsis not working in nested flexbox

There are two issues in your code preventing the ellipsis from working:

  1. div.right contains div.header, which in turn contains the button and text.

    div.right is a flex item in the main container (.container).

    By default, a flex item cannot be smaller than the size of its content. The initial setting on flex items is min-width: auto.

    This means that the length of your text, which is not wrapping, will set a minimum size for parent flex items. One way to enable flex items to shrink past their content is to set a flex item to min-width: 0.

    You've done this already for the .content flex item, but it needs to be set on the .right item, as well.

  2. You've got the .content element set to flex: 0 1 auto.

    This tells the flex item to use the size of the content (flex-basis: auto). The text sets the size.

    Instead, set the width to 0 and let the flex container distribute space, as necessary. You can do this with flex: 1 1 0, which is the same as 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>

Text not wrapping inside a flex container

I have a solution that seems to work but I do not that it is 100% correct, here is a fiddle:

https://jsfiddle.net/2xxorq4n/1/

And here is the CSS code:

body {
width: 90%;
margin: 3em auto;
background-color: #aaa;
}
section {
border:1px solid black;
}
.title {
text-align: center;
background-color: #eee;
}
.image {
background-color: #ccc;
}
.image img {
display: block;
max-height: 100%;
max-width: 100%;
}
.text {
background-color: #96AED1;
}
/* FLEX STYLES */
section {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.title, .image, .text {
flex: 1 100%;
}
@media all and (min-width: 600px) {
.image { flex: 1 auto; }
}
@media all and (min-width: 800px) {
.text { flex: 800 0px; }
.image { order: 1; }
.text { order: 2; }
}

Specifically, I do not think that this is correct: .text { flex: 800 0px; }. Although it seems to work, I do not think that it is supposed to work like that as the example on css tricks website which provides further information on Flexbox usage shows flex: 2 0px;:

https://css-tricks.com/snippets/css/a-guide-to-flexbox/

Vertical-align doesn't work on flex item

One solution is to define each flex item as its own flex container in order to vertically center its contents with align-items:center. To keep text-overflow working, add a child element to each flex item, which can then be truncated with ellipses.

I can't offer a succinct explanation as to why text-overflow doesn't work with display:flex, and neither can David Wesst. In his words:

It turns out that there really isn't a clean way to do this. If you're wondering how I came to that conclusion you can stop because I didn't. Those responsible for the specification did, and you can read the full conversation that started with a Mozilla bug report and leads to a whole mail group discussion about why it should (or, in this case, should not) be implemented as part of the spec.

Here's a working example:

.container {  width: 400px;  height: 400px;  font-weight: 700;  border: 1px solid #d9d9d9;  display: flex;  flex-direction: column;}
.item { display: flex; align-items: center; flex: 1; background-color: cyan;}
.item span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis;}
.item:nth-of-type(2n) { background-color: aliceblue;}
<div class="container">  <div class="item"><span>Hello, I'm very very long string! Hello, I'm very very long string!</span></div>  <div class="item"><span>Hello</span></div>  <div class="item"><span>Hello</span></div>  <div class="item"><span>Hello</span></div></div>

CSS crop string in the middle

Here is a clean CSS solution using the data-* attribute and two ::after pseudo-elements. I also added an optional hover and show all text (the #fileName::after pseudo element needs to be removed when the full text is shown).

Example 1

#fileName {
position: relative;
width: 100px;
}

#fileName p {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}

#fileName:after {
content: attr(data-filetype);
position: absolute;
left: 100%;
top: 0;
}

/*Show on hover*/

#fileName:hover {
width: auto
}

#fileName:hover:after {
display: none;
}
<div id="fileName" data-filetype="txt">
<p>This is the big name of my file.txt</p>
</div>


Related Topics



Leave a reply



Submit