I can\'t seem to wrap my head around having this container in an md card.
In my material cards, I have this:
&
I fixed it by providing negative left margin to md-card-title
<md-card-title style="margin-left:-8px;">
This behavior is the result of Angular 2/4's view encapsulation, which in Emulated
mode will only inject (via style
elements) component styles that match elements actually in your view template.
So if you try to override a .mat-*
style like so:
.mat-card-header-text {
height: auto;
margin: 0;
}
but your HTML looks like this:
<md-card-header>
<md-icon md-card-avatar>face</md-icon>
<md-card-title>{{user.name}}</md-card-title>
<md-card-subtitle>{{user.status | userStatus}}</md-card-subtitle>
</md-card-header>
then the .mat-card-header-text
rule won't be injected into the DOM, since the injector doesn't see such an element in your template.
The simplest workaround is to directly include the div.mat-card-header-text
element in your template:
<md-card-header>
<md-icon md-card-avatar>face</md-icon>
<div class="mat-card-header-text">
<md-card-title>{{user.name}}</md-card-title>
<md-card-subtitle>{{user.status | userStatus}}</md-card-subtitle>
</div>
</md-card-header>
Edit: as you pointed out, this generates an extra empty div.mat-card-header-text
, so it's not an ideal solution. The only way to fix that is if you create your own card component based on md-card
(possibly using component inheritence), but at that point you'd just modify the component's CSS directly.
Otherwise, you can switch the view encapsulation mode for your component to None
:
import { ViewEncapsulation } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'user-card',
templateUrl: 'user-card.component.html',
styleUrls: ['user-card.component.css'],
encapsulation: ViewEncapsulation.None
})
...
Though if you do that, the :host
selector will no longer work, so you'll need to replace it with the selector you specified in the @Component
decorator:
user-card {
...
}
This extra div is actually quite annoying. As it turns out though, you can use shadow-piercing to apply a style to it without changing the CSS emulation mode. You can do this using the ::ng-deep combinator as such:
::ng-deep .mat-card-header-text {
/* CSS styles go here */
margin: 0px; // for example to remove the margin
}
You can also just replace the whole header with your own CSS classes instead:
<mat-card>
<div class="your-header">
<div class="your-title">
Your title here
</div>
</div>
<mat-card-content>
Stuff goes here
</mat-card-content>
</mat-card>
Fixed it using the following css and html:
md-card-title > span {
background-color: #fff;
background-color: rgba(255, 255, 255, 0.5);
position: absolute;
margin-top: -81px;
margin-left: -24px;
font-size: 20px;
padding: 10px;
}
<div class="main" mat-padding fxLayout="row" fxLayoutWrap="no-wrap" fxLayoutAlign="center start" fxLayoutGap="15px">
<md-card class="mat-elevation-z2" mat-whiteframe="8" (click)="goToArticle(article)" *ngFor="let article of articleStore.articles() | async">
<img md-card-image src="{{ article.getCover() }}">
<md-card-title fxFlex>
<span>{{ article.title }}</span>
</md-card-title>
<md-card-content>
<p>{{ article.description }}</p>
</md-card-content>
</md-card>
</div>
Using <md-card-header></md-card-header>
gives some odd spacing issues. Not sure if this is a bug or not.