I have two div elements sitting side by side. I want the left div to take remaining space of the width of the right div.
.text {
display: inline;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
background-color: red;
}
.icon {
display: inline-block;
width: 92px;
background-color: green;
}
.information {
width: 200px;
}
<div class="information">
<div class="text">Text Here</div>
<div class="icon">Image Here</div>
</div>
Everything I've tried, causes the icon div to resize/overflow based on the remaining space left from the text.
But I want my text div to overflow if the width on the icon div is more. Is there anyway to do this?
I can't set the width (using less or calc(totalWidth - iconWidth))
for the text div because the icon div's width can vary and I don't know what its value might be (the value of the icon's width is calculated in a mixin).
Fiddle link: https://jsfiddle.net/fdur0wd1/
Use flex on the parent, and set .text to flex-grow: 1 (or flex: 1 0 0 for short)
.text {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
background-color: red;
flex: 1 0 0;
}
.icon {
width: 92px;
background-color: green;
}
.information {
width: 200px;
display: flex;
}
<div class="information">
<div class="text">Text Here</div>
<div class="icon">Image Here</div>
</div>
Related
I'm a having a bit of an issue here. I have a flexbox container with children of different sizes. Based on quantity and their content children might overflow the parent.
What I want is the children to shrink so they try to fit in the parent container. I did that by adding shrink and overflow properties to the children. So far so good.
.container > div {
background-color: orange;
padding: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 1;
}
I end up with something like this:
Now I want them to shrink but up to a certain point (lets say 80px). I don't care if they end up overflowing the container but I don't want to render any smaller than 80px.
Of course, I added min-width: 80px to the children... but here is my problem. I want the children to shrink up to 80px but I don't want any of those that were smaller than 80px already (like Child1, Child4 and Child5) I don't want them to be enlarged by the min-width property (or, I want them to shrink further up to min-content)
In other words. I don't want this:
I would love to have something like this:
I tried doing something like min-width: min(min-content, 80px) but of course, didn't work.
Here is an small codepen with the issue: https://codepen.io/claudiofpen/pen/QWELVJO
.container {
width: 300px;
border: 1px solid black;
display: flex;
flex-direction: row;
padding: 5px;
}
.container > div {
background-color: orange;
padding: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex-shrink: 1;
min-width: min-content;
}
.container > div:not(:last-child) {
margin-right: 5px;
}
/* I don't want the following css classes, I cannot
tell in before hand which children are going to have
a larger content */
.container > div:nth-child(2),
.container > div:nth-child(3) {
min-width: 80px;
}
<div class="container">
<div>Child 1</div>
<div>Longer Child 2</div>
<div>Longer Child 3</div>
<div>Child 4</div>
<div>Child 5</div>
</div>
Temani Afif's solution solves the problem of ensuring that a text element will not shrink below the specified width unless its intrinsic width is already below that width (in which case it uses its intrinsic width as the rendered width). But it does not work unless the sum of the specified widths of all the child elements exceeds the container's width.
So I tried giving each outer elements a flex-grow parameter, so that they would grow above their specified width, if the container had room. But I also give the outer elements a maximum width set to their intrinsic maximum content width, so they would never grow beyond the actual size of the text. Thus I added the following styles to the wrapping div.
flex: 1 1 auto;
max-width: max-content;
With that tweak I believe it solves the entire problem. The elements expand fully if there is room in the container. As we add more elements the longer elements start to shrink. But they never shrink below their specified width, so the container overflows once all inserted elements have shrunk down to that width. But elements that started with a shorter width never flex at all.
I have added an example below.
.container {
width: 340px;
border: 1px solid black;
display: flex;
flex-direction: row;
padding: 5px;
}
.container>div {
background-color: orange;
padding: 5px;
flex: 1 1 auto;
width: 80px;
max-width: max-content;
}
.container>div>div {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
}
.container>div:not(:last-child) {
margin-right: 5px;
}
<h5>When the items fit they expand to their intrinsic length</h5>
<div class="container">
<div>
<div>Medium length</div>
</div>
<div>
<div>Tiny</div>
</div>
<div>
<div>Longer text element</div>
</div>
</div>
<h5>When the container limit is reached the longer elements start shrinking</h5>
<div class="container">
<div>
<div>Medium length</div>
</div>
<div>
<div>Tiny</div>
</div>
<div>
<div>Longer text element</div>
</div>
<div>
<div>Filler</div>
</div>
</div>
<h5>Adding more elements...</h5>
<div class="container">
<div>
<div>Medium length</div>
</div>
<div>
<div>Tiny</div>
</div>
<div>
<div>Longer text element</div>
</div>
<div>
<div>Filler</div>
</div>
<div>
<div>Filler</div>
</div>
</div>
<h5>When there is no room it overflows<br> The tiny element stays at its intrinsic width, but the bigger elements stop shrinking at the specified width</h5>
<div class="container">
<div>
<div>Medium length</div>
</div>
<div>
<div>Tiny</div>
</div>
<div>
<div>Longer text element</div>
</div>
<div>
<div>Filler</div>
</div>
<div>
<div>Filler</div>
</div>
<div>
<div>Filler</div>
</div>
</div>
With an extra wrapper you can do it:
.container {
width: 300px;
border: 1px solid black;
display: flex;
flex-direction: row;
padding: 5px;
}
.container > div {
background-color: orange;
padding: 5px;
flex-shrink: 1;
width: 80px;
}
.container > div > div {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
}
.container > div:not(:last-child) {
margin-right: 5px;
}
<div class="container">
<div><div>Ch 1</div></div>
<div><div>Longer Child 2</div></div>
<div><div>Longer Child 3</div></div>
<div><div>Child 4</div></div>
<div><div>Child 5</div></div>
</div>
Grid Solution
.container {
width: 300px;
border: 1px solid black;
display: grid;
grid-template-columns: max-content 80px 80px repeat(2,max-content);
padding: 5px;
}
You can use javascript to make the grid-template-column dynamic.
Here is the jquery (javascript) solution using flex
.container {
width: max-content;
border: 1px solid black;
display: flex;
padding: 5px;
}
$(".container > div").each(function(){
($(this).width() < 50) ?
$(this).css('width','max-content') :
$(this).css('flex','0 0 80px');
})
This is more dynamic than the grid solution. The only thing is that you will need to have a desired number in $(this).width() < 50 instead of fifty based on your content.
.wrapper {
background: tomato;
width: 100px;
display: flex;
}
.left {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.right {
}
<div class=wrapper>
<div class="left">
title title title title
</div>
<div class="right">
123
</div>
</div>
I have a DIV (wrapper) with 2 DIVs inside: left and right.
wrapper's width is known. I want to truncate text in left DIV if it doesn't fit. Text in right should be always visible. I tried several techniques here, but the only one is working is based on flex box. Unfortunately it doesn't work on IE10. I used -ms- prefixes, without success.
Is there any way to make it work on IE10?
I can't test this on IE10 myself, though since its -ms-flex defaults to 0 0 auto, you will need to add -ms-flex: 0 1 auto to the left, so it is allowed to shrink.
And as the default on IE11 and the rest of the browsers is 0 1 auto, they work as is.
Fiddle demo
Stack snippet
.wrapper {
background: tomato;
width: 100px;
display: -ms-flexbox; /* IE10 */
display: flex;
}
.left {
-ms-flex: 0 1 auto; /* IE10 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.right {
}
<div class=wrapper>
<div class="left">
title title title title
</div>
<div class="right">
123
</div>
</div>
Here is an idea without the use of flexbox but using display:table:
.wrapper {
background: tomato;
width: 100px;
display: table;
}
.left {
display: table-cell;
position: relative;
width: 100%;
}
.left span {
position: absolute;
top:0;
left:0;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.right {
display: table-cell;
}
<div class=wrapper>
<div class="left">
<span>
title title title title title title
</span>
</div>
<div class="right">
123
</div>
</div>
I have a two-column layout created with flexboxes.
In the right column, I have two rows, the first containing a header and the second containing the page content.
Within the header I have three columns, a button, some text, and a button.
I want the buttons to sit on the left and right of the column with the text taking up any additional room.
Finally, I want the text to have white-space:nowrap and text-overflow:ellipsis properties to truncate long titles.
My problem is this: I cannot get the text wrapping to work correctly in a flexbox that is nested in another flexbox, as shown in this fiddle:
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>
However, the exact same code works when the header is not nested within a flex box:
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>
How can I achieve what I want in the first fiddle?
Thanks
There are two issues in your code preventing the ellipsis from working:
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.
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>
revised fiddle
The values of :
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
Will work only if the content of your element exceeds it's width.
You can set the width of .header .content:
.header .content {
width: 50%;
}
And it will work as you expect it to:
http://jsfiddle.net/t82pqks4/
I hope this solution helps someone as nothing else I found worked because of how my page was a giant nested combination of flexbox. so min-width 0 didn't work, nothing I tried worked except this.
Inside the flex column that has the copy you want to wrap, you need to do this.
.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>
I have a inline-flex container with two inner blocks that must expand (without wrapping).
In the second block there is another inline-flex container with two inner inline-blocks that must never wrap their content.
What I need
Is to show the text-overflow: ellipsis when the width of the most-top container (div.width) is not enough for displaying all the inner blocks as white-space: nowrap.
The content of div.width must never overflow its container, in the case the content of the a link is too long.
Snippet
.splitbutton {
display: inline-flex;
border: 4px solid violet;
}
.default {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.default a {
/* white-space: nowrap; */
}
.button {
background-color: green;
padding: 5px;
}
.container1 {
white-space: nowrap;
}
.container1,
.container2 {
flex: 1 1 auto;
border: 3px double green;
}
.width {
border: 3px solid red;
/*width: 350px;*/
display: inline-flex;
flex-wrap: nowrap;
flex-direction: row;
}
<div class="width">
<div class="container1">
<span>Any kind of inline text</span>
</div>
<div class="container2">
<div class="splitbutton">
<div class="default">
Looooooooooooong text with many many spaces and letters
</div>
<span class="button">button</span>
</div>
</div>
</div>
Note
None of the present blocks can specify a specific fixed width!
The button must always stay visible (the ellipsis should eventually be applied to the a link element).
check this out
http://jsfiddle.net/38Hmp/
The dom structure is this
<div class="outer">
<div class="left">aaa</div>
<div class="middle">middlemiddlemiddlemiddlemiddlemiddle</div>
<div class="right">bbb</div>
</div>
outer is fixed width,
left and right to be on the left and right, respectively
all three sections contain variable width content.
The middle section should not overflow or push the right section out of the container.
Ideally the middle would have ellipses in the event of overflow.
I can't see how to avoid pushing the right section out in the event of long middle section without a max width, but that kills the variable width of the right section.
How do I resolve this?
Can you use flexbox?
It has the properties you need. Setting the growth property to 0 & shrink property to 1, perhaps?
-webkit-box-flex: 0;
-moz-box-flex: 0;
-webkit-flex: 0 1 auto;
-ms-flex: 0 1 auto;
flex: 0 1 auto;
And maybe you could play with it, here.
Incomplete but it can get you started
html
<div class="outer">
<div class="left">aaa</div>
<div class="inner">
<div class="right">bbb</div>
<div class="middle">middlemiddlemiddlemiddlemiddlemiddle</div>
</div>
</div>
css
.outer {
background-color: yellow;
height: 20px;
width: 200px;
}
.left {
float: left;
display: inline-block;
}
.inner {
float: right;
}
.middle {
float:left;
display: inline-block;
text-overflow: ellipsis;
}
.right {
float: right;
display: inline-block;
}
Ok I found a pure css solution.
http://jsfiddle.net/38Hmp/2/
<div class="outer">
<div class="left">aaa</div>
<div class="right">bbb</div>
<div class="middle">middlemiddlemiddlemiddlemiddlemiddle</div>
</div>
left and right both float (left and right) and middle has no float.
Its key that left and right go into the dom before middle.
css
.outer {
background-color: yellow;
height: 20px;
width: 200px;
}
.left {
float: left;
margin-right: 10px;
}
.middle {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.right {
float: right;
margin-left: 10px;
}