Apply text-overflow when no more space for nowrap-inline - html

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).

Related

element with overflow:hidden still has it's full width

If you run the snippet below, everything looks like it's working. But if you inspect the text within the border in your dev-tools, and hover over the element you'll see the width of the text is still full length. This is a problem when trying to make that container responsive. How can I hide the overflow, and use text-overflow: ellipsis while having it's width be representative of what we see?
.container {
width: 300px;
border: 1px solid #000;
display: flex;
flex-direction: row;
}
.text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class="container">
<span class="text">
<a>
looooooooooooooooooooooooooooooooooooooooooooooooooooooooog text
</a>
</span>
<button>hello</button>
</div>
You can remove the <span> and add the .text class to your <a> tag. Your CSS was not applied to your text because of the <a> tags
.container {
width: 300px;
border: 1px solid #000;
display: flex;
flex-direction: row;
}
.text {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class="container">
<a class="text">
looooooooooooooooooooooooooooooooooooooooooooooooooooooooog text
</a>
<button>hello</button>
</div>

HTML/CSS - Limiting span lengths and lining up multiple spans

I have a few spans in a fixed width container.
One of the spans is longer than the others and changes in size at different times. I'm trying to limit this span to a maximum width so that the 3 spans fit on one line.
What I have so far works, but the problem is the span that is limited in length is slightly offset and the spans don't line up perfectly. What should I do to make all 3 spans fit on one line and align with each other so they look normal?
JSfiddle: https://jsfiddle.net/579cwmbv/
Code:
.container {
width: 350px;
display: inline-block;
}
.spanContainer {
display: inline-block;
}
.long {
overflow: hidden;
text-overflow: ellipsis;
max-width: 156px;
display: inline-block;
white-space: nowrap;
}
.short {
display: inline-block;
}
<div class='container'>
<div class='spanContainer'>
<span class='short'>Results near </span>
<span class='long'>"Seattle, WA, 98005, United States"</span>
<span class='short'>Change</span>
</div>
</div>
Try using flex
.spanContainer {
display: flex;
justify-content: space-evenly;
align-items: center;
}
If you format the spans in the same way as each other they line up:
.container {
width: 350px;
display: inline-block;
}
.spanContainer {
display: inline-block;
}
.long,
.short {
overflow: hidden;
text-overflow: ellipsis;
max-width: 156px;
display: inline-block;
white-space: nowrap;
}
<div class='container'>
<div class='spanContainer'>
<span class='short'>Results near </span>
<span class='long'>"Seattle, WA, 98005, United States"</span>
<span class='short'>Change</span>
</div>
</div>

Vertical-align doesn't work on flex item

I tried to vertically centralize plain text inside a flex box element.
I decided to use property display:table-cell with vertical-align: middle. But it doesn't seem to work properly in flexbox elements.
How can I centralize it vertically, ideally without using a wrapper or positioning, and while still truncating long text with ellipses?
.container {
width: 400px;
height: 400px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
display: table-cell;
vertical-align: middle;
flex: 1 1;
background-color: cyan;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item">Hello, I'm very very long string! Hello, I'm very very long string!</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
</div>
View On CodePen
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>
Also see:
Setting ellipsis on text from a flex container
When you make an element a flex container (with display: flex or display: inline-flex), all in-flow children become flex items.
All flex items have their display value controlled by the container. It doesn't matter what you specify, the container overrides it.
So when you give a flex item display: table-cell, the browser ignores it. Here's what it looks like in Chrome Dev Tools:
Style Tab
Computed Tab
A flex container "blockifies" flex items, causing them to assume many qualities of block-level elements (source).
But the vertical-align property applies only to inline-level and table-cell elements (source).
That's why it doesn't work.
Regardless, vertical-align, even if it worked, is a totally unnecessary hack in this case. There are flex properties designed for aligning content in flex items.
.container {
width: 500px;
height: 500px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
flex: 1 1;
display: flex;
justify-content: center; /* horizontal alignment, in this case */
align-items: center; /* vertical alignment, in this case */
background-color: cyan;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
</div>
Related posts:
How to vertically align text inside a flexbox?
Setting ellipsis on text from a flex container
Blockquote ...float, clear and vertical-align have no effect on a flex item.
according to https://css-tricks.com/snippets/css/a-guide-to-flexbox/
See How to vertically align text inside a flexbox? for a possible solution.
You have to define those items also as flex containers, using the following CSS for them (no table-cell display...):
display: flex;
flex-direction: column;
justify-content: center;
.container {
width: 400px;
height: 400px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
display: flex;
flex-direction: column;
justify-content: center;
flex: 1 1;
background-color: cyan;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item">Hello, I'm very very long string! Hello, I'm very very long string!</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
</div>

Cause first div to overflow based on width of second div

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>

text-overflow ellipsis not working in nested flexbox

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>