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:
div.right
containsdiv.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.You've got the
.content
element set toflex: 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 asflex: 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
How to Have a Horizontal Multiple Colour Gradient on Text Using CSS3/HTML 5
Removing Page Scrollbars in IE8 (Overflow:Hidden Not Working)
How to Dynamically Load a CSS File into a Flex Application
Enforce Print Page Breaks with CSS
Is It Posible to Make an Input Checkbox a Bootstrap Glyphicon
Why Can't I Beat an Id with Multiple Classes
Selector for All a Tag Descendants
Element Opacity But Not Border
How to Layer Box-Shadows Using Z-Index
Safari Page-Break-Inside:Avoid Not Working
Style Type="Text/Css" ... What Else Is There
Css: Skew a Buttons Border, Not the Text
How to Maintain a Circlur Shape of Element with Dynamic Content
CSS Animated Circles - Stop Center Content from Rotating