I am unable to force mat-card-title
to stay in one line and cut off the extra text.
I have tried the css class below (text-oneline).
<mat-card>
<mat-card-header>
<mat-card-title class="text-oneline">Heeeeeellllllloooo</mat-card-title>
<mat-card-subtitle>World!</mat-card-subtitle>
</mat-card-header>
<img mat-card-image [src]="icon_url" alt="App Icon">
<mat-card-content>
<p>Some Text</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>Hello</button>
</mat-card-actions>
</mat-card>
.text-oneline {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
Right now, the text is longer than the card. I would like the text to stop and not overflow the card.
I want the text to fill all available space but not go over the width of the mat-card.
Example: https://angular-mat-card-example-4cb2wk.stackblitz.io
Solution:
The code by לבני מלכה works great, but only after window.resize is triggered. The simples solution I found was editing mat-card-header
.
mat-card-header {
display: flow-root;
}
Wrap you card in div
and set elementRef to div as #card
Then set width to header
as the card's width [style.width.px]="width - 50"
Set the width param on resize (window:resize)="width=card.getBoundingClientRect().width"
See working code
<div #card (window:resize)="width=card.getBoundingClientRect().width">
<mat-card>
<mat-card-header>
<mat-card-title class="text-oneline" [style.width.px]="width - 50">Heeeeeellllllloooo</mat-card-title>
<mat-card-subtitle>World!</mat-card-subtitle>
</mat-card-header>
<img mat-card-image [src]="icon_url" alt="App Icon">
<mat-card-content>
<p>Some Text</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>Hello</button>
</mat-card-actions>
</mat-card>
</div>
CSS
.text-oneline {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
I can offer two solutions one of which I don't really want to give, but it's a solution.
The solution I recommend you to use is to remove the wrapping <mat-card-header>
<mat-card>
<mat-card-title class="text-oneline">Heeeeeellllllloooo</mat-card-title>
<mat-card-subtitle>World!</mat-card-subtitle>
<img mat-card-image [src]="icon_url" alt="App Icon">
<mat-card-content>
<p>Some Text</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>Hello</button>
</mat-card-actions>
</mat-card>
This will change the layout a little bit, but you can solve this by adding your own css classes or wrap it with your own div, just don't use <mat-card-header>
because it does something that's not easy to circumvent, but not impossible like you'll see in my second, not so recommended, solution.
In this second solution you move the .text-online
class onto the <mat-card-header>
like so:
<mat-card>
<mat-card-header class="text-oneline">
<mat-card-title >Heeeeeellllllloooo</mat-card-title>
<mat-card-subtitle>World!</mat-card-subtitle>
</mat-card-header>
<img mat-card-image [src]="icon_url" alt="App Icon">
<mat-card-content>
<p>Some Text</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>Hello</button>
</mat-card-actions>
</mat-card>
and your css changes to:
.text-oneline ::ng-deep * {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
I do NOT recommend you use this second solution!
Using ::ng-deep is considered very bad practive because it's deprecated and shouldn't be used anymore, but as of today Angular has not provided an alternative. More info
for this use CSS word-break: break-all
refer following code block
<mat-card>
<mat-card-header>
<mat-card-title style="word-break: break-all">Heeeeeellllllloooo</mat-card-title>
<mat-card-subtitle>World!</mat-card-subtitle>
</mat-card-header>
<img mat-card-image [src]="icon_url" alt="App Icon">
<mat-card-content>
<p>Some Text</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>Hello</button>
</mat-card-actions>
</mat-card>