How do you deal with a div with mat-card-header-text on card material2?

I can't seem to fool my head with the container in the md map.

In my material cards, I have this:

<div class="mat-card-header-text"> </div>

      

I've seen other people notice this. This causes a 40px space to the left of my title. No CSS seems to affect it.

I am using Angular 4.x and Material2.

+11
angular angular-material


source to share


9 replies


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>

      



Usage <md-card-header></md-card-header>

gives some odd spacing problems. Not sure if this is a bug or not.

0


source to share


This extra div is actually pretty annoying. However, as it turns out, you can use shadow piercing to style 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
}

      



Instead, you can simply replace the entire title with your own CSS classes:

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

      

+20


source to share


I fixed it by providing negative left margin for md-card-title

<md-card-title style="margin-left:-8px;">

      

+4


source to share


This behavior is the result of Angular 2/4 view encapsulation , which in mode Emulated

will only inject (through style

) component styles that match the elements in your template.

So if you try to override the style .mat-*

like this:

.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 rule .mat-card-header-text

won't be injected into the DOM since the injector doesn't see such an element in your template.

The simplest workaround is to include the element directly div.mat-card-header-text

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 creates an extra blank div.mat-card-header-text

, so this is not a perfect solution. The only way to fix this is if you create your own map component based on md-card

(perhaps using component inheritance ), but at this point you just modify the CSS component 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
})
...

      

Although if you do this, the selector :host

will no longer work, so you will need to replace it with the selector specified in the decorator @Component

:

user-card {
   ...
}

      

+3


source to share


make a class for the mat-card container and add

border-collapse:collapse;

      

worked wonders for me.

0


source to share


If you want to support a version with and without an image in the header, this is one possible solution. The idea is to toggle the class that captures the field when the image is not available (set via the input reference in the example). This way the map looks good with and without an image.

Html:

<mat-card>
  <mat-card-header [ngClass]="{'fix-margin': !link}">
    <mat-card-title>{{content}}</mat-card-title>
    <mat-card-subtitle>{{content}}</mat-card-subtitle>
    <img *ngIf="link" mat-card-avatar [src]="link">
  </mat-card-header>
  <mat-card-content>
    {{content}}
  </mat-card-content>
  <mat-card-actions>
    <button mat-button>SHOW</button>
  </mat-card-actions>
</mat-card>

      

Css

.fix-margin {
  margin: 0 -8px;
}

      

Ts.

export class component {
  @Input() content;
  @Input() link;    
}

      

0


source to share


Maurice's answer on the spot:

border-collapse:collapse;

One line solves this problem.

0


source to share


I know this is an old question, but still it's a problem today. The way I solved it overridden it like this in the ts file:

ngAfterViewInit() {
    document.getElementsByClassName('mat-card-header-text')[0].setAttribute('style', 'margin: 0 0');
  }

      

0


source to share


According to their recent recommendation https://angular.io/guide/component-styles , this worked for me:

 :host /deep/ .mat-card-header-text {
     margin: 0;
 }

      

0


source to share







All Articles
Loading...
X
Show
Funny
Dev
Pics