how to truncate last element if needed - css

I have a div with different number of span inside depending on my code, my problem is, sometimes the last span does not fit the space and everything lost the align, what I want to do is applied my "truncate" class to the last element if needed, there is an example:
<div class="truncate">
<span> ONE </span>
<span> TWO </span>
<span> THREE </span>
<span> FOUR </span>
</div>
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
with this configuration, and also aplying "truncate" everything moved to left, and I stop watching "one" instead "four" as I want, either the "..." are not shown.
I also tried aplied truncate to the last child with same result:
.truncate:last-child {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Where is my mistake?

Check out the :last-child pseudo-class.

Might not be relevant to you now, but I had this problem, and I solved it with flex-shrink: 0 which tells certain elements never to shrink, which means that last element shrinks.
See example: https://jsfiddle.net/68usz20p/2/
div {
display: flex;
overflow: hidden;
width: 175px;
border: 1px solid red;
}
div span:not(:last-child) {
margin-right: 1ch;
flex-shrink: 0;
}
div span:last-child {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

You can using css :last-child Selector
.truncate span:last-child {
display:none; visibility:hidden;
}
<div class="truncate">
<span> ONE </span>
<span> TWO </span>
<span> THREE </span>
<span> FOUR </span>
</div>
Preview at https://jsfiddle.net/itsselvam/yt9srxLo/

Related

How to shrink a child to fit the outer-most flex-container in a deep hierarchy? [duplicate]

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
CSS ellipsis inside flex item
(1 answer)
Closed 4 years ago.
I am trying to hide overflow in a label that is the child of a deeply nested flex-container. Below are two simple snippets to illustrate the problem:
Single container (works):
#parent-flexbox {
display: flex;
width: 200px;
}
label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div id="parent-flexbox">
<label>long text that should be hidden because it is wider than the parent container</label>
</div>
Nested container (doesn't work):
#parent-flexbox {
width: 200px;
}
#parent-flexbox, #child-flexbox {
display: flex;
}
label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div id="parent-flexbox">
<div id="child-flexbox">
<label>long text that should be hidden because it is wider than the parent container</label>
</div>
</div>
To solve this I could add an explicit width like max-width: 100% to every container in the hierarchy. This is a terrible solution that I'm hoping is unnecessary! My current best fitting solution, but not much better, is these two rules for the immediate parent of the label: {position: absolute; max-width: 100%}. I want to avoid using absolute position because this comes with problems of its own. This JSFiddle shows the absolute position solution (lines outcommented default).
How can I achieve the same as this JSFiddle without A) using position: absolute and B) targetting all containers in the hierachy to give them max-width: 100% or min-width: 0?
The issue here is that the nested container is overflowing the first container and that's why overflow hidden is not working as you expect since there is no overflow with label.
I added border so you can better see:
#parent-flexbox {
width: 200px;
}
#parent-flexbox, #child-flexbox {
display: flex;
border:1px solid green;
}
label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div id="parent-flexbox">
<div id="child-flexbox">
<label>long text that should be hidden because it is wider than the parent container</label>
</div>
</div>
To avoid this you may apply overflow:hidden to the containers:
#parent-flexbox {
width: 200px;
}
#parent-flexbox, #child-flexbox {
display: flex;
overflow: hidden;
}
label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div id="parent-flexbox">
<div id="child-flexbox">
<label>long text that should be hidden because it is wider than the parent container</label>
</div>
</div>
I don't think you can fix this without targeting the containers. And since your are applying display:flex to all of them, you can add another property with it.

text-overflow: ellipsis; not working with mat-expansion-panel

I'd like to apply text-overflow: ellipsis; to the mat-panel-description of a mat-expansion-panel:
.mat-expansion-panel-header-description {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
}
While the overflow is hidden, there are no ellipsis. See the following screenshot of this stackblitz:
Wrapping is intentionally prevented since I don't want the description to wrap onto a second line. The long URL is also intentional:
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Panel Title
</mat-panel-title>
<mat-panel-description>
https://stackblitz.com/edit/angular-gsxyhn?file=app%2Fexpans ion-overview-example.html
</mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
</mat-accordion>
I think you will come to find out that if you just put text in flex containers you can run into problems. I think it is best if you have a container element to hold your text and will help you in this case.
Once the content is placed in some container, there is one thing that needs to be done to get the ellipsis to show up... add min-width: 0; to the mat-expansion-panel-header-description class.
<span class="mat-content">
<mat-panel-title class="mat-expansion-panel-header-title">
<div>Panel Title</div>
</mat-panel-title>
<mat-panel-description class="mat-expansion-panel-header-description">
<div>https://stackblitz.com/edit/angular-gsxyhn?file=app%2Fexpans ion-overview-example.html</div>
</mat-panel-description>
</span>
.mat-expansion-panel-header-title {
flex: 0 0 auto; /* make this not grow or shrink */
margin-right: 16px;
}
.mat-expansion-panel-header-description {
flex: 1 1 auto; /* make this grow and shrink */
min-width: 0; /* see link to see why this is needed */
margin-right: 16px;
}
.mat-expansion-panel-header-description > div {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
I solved it changing the child's visibility property.
Take a look here.
Ellipsis won't work on a visibility: hidden element, or any of its children inheriting this property.

Can I put Ellipsis on the Left and Periods on the Right?

Moving the Ellipsis (...) to the left is done easily with:
.overflow-box{
direction: rtl;
text-overflow: ellipsis;
overflow: hidden;
}
But what if there's punctuation at the end, like a period (.) or question mark? It's also displayed on the left. I'd still like to see the period on the right. Is there an easy way around this?
Demo: https://jsfiddle.net/JoelMac/Lx4L15o3/5/
One way is to put the content of the div in a span with dir="ltr", forcing the content to be rendered in the standard order while still cutting off to the left as desired.
div {
width: 300px;
white-space: nowrap;
border: solid 1px #000;
margin-bottom: 10px;
direction: rtl;
text-overflow: ellipsis;
overflow: hidden;
}
<div>
<span dir="ltr">This is a sentence that is too long to fit in the space provided.
The ellipsis is where I want it.</span>
</div>
<div>
<span dir="ltr">Where is the question mark?</span>
</div>
However, this is not the only possible solution. As #reiallenramos's answer shows, you can also insert ‎ at the end of the content; that will work too.
An added benefit of the latter approach is that you won't need to change the markup; you can do it wholly in CSS, as follows:
div {
width: 300px;
white-space: nowrap;
border: solid 1px #000;
margin-bottom: 10px;
direction: rtl;
text-overflow: ellipsis;
overflow: hidden;
}
div::after {
content:'\200E';
}
<div>
This is a sentence that is too long to fit in the space provided.
The ellipsis is where I want it.
</div>
<div>
Where is the question mark?
</div>
This would then be my preferred method, but you can choose whatever you want.
tl;dr: append ‎ to the end of your text like this
<div>
Where is the question mark?‎
</div>
Looks like a duplicate of Why is a trailing punctuation mark rendered at the start with direction:rtl?
Punctuations really do behave this way according to this.

Show only the first letters, three dots and the last N letter of a span

If I've a very long text like this (for example in a table):
<p class='line'>
<span class='fixed1'>FIXED</span>
<span class='long_text'>This is my very very very very long text</span>
<span class='fixed2'>FIXED</span>
</p>
By default the <p> width is 100% and if the text is longer than the screen it's showed on multi lines. Instead I want it in a single line where only the last N letter are showed.
Here some example:
Screen large enough:
FIXED This is my very very very very long text FIXED
Screen not enough large, text overflow.
FIXED This is my ve... text FIXED
I can obtain something similar using:
span.long_text {
overflow: hidden;
text-overflow: ellipsis;
}
Is it possible to obtain the effect I described? How?
You can use white-space: nowrap to force it to stay in a single line.
text-overflow: ellipsis will replace the end of your content with '...' when overflow occurs. However span must be a block for text-overflow to work, so set its display property to inline-block or block.
Demo: https://jsfiddle.net/1bmdu5xd/
Ellipsis only work with single line things so that's OK here. The problem is with those "N letter".
Here's a starter with :after (you must have your N last letters in some CSS. Suboptimal => https://codepen.io/PhilippeVay/pen/vWMePJ?editors=0100
.line {
display: flex;
border: 1px solid black;
width: 240px;
}
.line > * {
white-space: nowrap;
}
.long_text {
position: relative;
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
background: yellow;
padding-right: 2rem;
}
.long_text::after {
content: "g text";
position: absolute;
right: 0;
}
<p class='line'>
<span class='fixed1'>FIXED</span>
<span class='long_text'>This is my very very very very long text</span>
<span class='fixed2'>FIXED</span>
</p>
It could be content: attr(data-last-letters) and <span class='long_text' data-last-letters="g text"> which now works in most browsers.
Or background-image: -moz-element(#someId); that copy-paste an element elsewhere and that only works in Firefox (for the past 7 years: won't work cross-browser anytime soon I guess).

Multiline ellipsis with <br> tags only adds ellipsis to first line in IE11/Edge

In Chrome and Firefox both lines show an ellipsis at the end. However in IE11/Edge only the first line has an ellipsis and the second line is simply cutoff. Is there anyway to get IE11/Edge to work similar to Chrome/Firefox?
body {
font-family: 'Arial';
}
div.wrapped-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100px;
}
<div class="wrapped-text">
This is a test of wrapped<br>
text that should overflow
</div>
For anyone in the same situation I've found the only way to get this to work is to change the HTML a little so that each line in the div is wrapped in its own div - and those child divs get the css to add the ellipsis.
body {
font-family: 'Arial';
}
div.wrapped-text {
width: 100px;
}
div.wrapped-text > div {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
<div class="wrapped-text">
<div>This is a test of wrapped</div>
<div>text that should overflow</div>
</div>

Resources