Components: Add Customize Css Class to the Mat-Tab-Content and other Mat-X tags which are generated runtime

Created on 8 Jan 2018  ·  20Comments  ·  Source: angular/components

Bug, feature request, or proposal:

Not able to add customize css class or apply css styling to any Mat-X element that are generated during runtime.

What is the expected behavior?

Customize style and add user defined CSS Class to override the behaviour of element (if required)

What is the current behavior?

Not applied

What are the steps to reproduce?

This is my html body
```




This is the test


This is the test




Below is the Generated Html when it runs in the browser(Chrome).


    <div aria-hidden="true" class="mat-tab-header-pagination mat-tab-header-pagination-before mat-elevation-z4 mat-ripple mat-tab-header-pagination-disabled" mat-ripple="" ng-reflect-disabled="true"><div class="mat-tab-header-pagination-chevron"></div></div>
    <div class="mat-tab-label-container">
        <div class="mat-tab-list" role="tablist" style="transform: translate3d(0px, 0px, 0px);">
            <div class="mat-tab-labels">
                    <!--bindings={"ng-reflect-ng-for-of": "[object Object],[object Object"}-->

                    <div class="mat-tab-label mat-ripple mat-tab-label-active ng-star-inserted" mat-ripple="" mattablabelwrapper="" role="tab" ng-reflect-disabled="false" id="mat-tab-label-0-0" tabindex="0" aria-controls="mat-tab-content-0-0" aria-selected="true">

                        <!--bindings={}--><!--bindings={"ng-reflect-ng-if": "true"}-->
                        General
                    </div> 
            </div>
            <mat-ink-bar class="mat-ink-bar" style="visibility: visible; left: 0px; width: 160px;"></mat-ink-bar>
        </div>
    </div>

    <div aria-hidden="true" class="mat-tab-header-pagination mat-tab-header-pagination-after mat-elevation-z4 mat-ripple mat-tab-header-pagination-disabled" mat-ripple="" ng-reflect-disabled="true"><div class="mat-tab-header-pagination-chevron"></div></div>
</mat-tab-header>

```

<div class="mat-tab-body-wrapper">
    <!--bindings={"ng-reflect-ng-for-of": "[object Object],[object Object"}-->
    <mat-tab-body class="mat-tab-body ng-tns-c23-28 mat-tab-body-active ng-star-inserted" role="tabpanel" ng-reflect-_content="[object Object]" ng-reflect-position="0" id="mat-tab-content-0-0" aria-labelledby="mat-tab-label-0-0" ng-reflect-origin="0">

        <div class="mat-tab-body-content ng-trigger ng-trigger-translateTab" style="transform: none;"><!---->
            <div _ngcontent-c12="" class="container ng-star-inserted" style="">
                <div _ngcontent-c12="" class="row">
                    <div _ngcontent-c12="" class="col-sm-2 col-md-4 col-lg-6">
                        This is the test
                    </div>
                    <div _ngcontent-c12="" class="col-sm-2 col-md-4 col-lg-6">
                        This is the test
                    </div>
                </div>
            </div>
    <!----></div>
    </mat-tab-body> 
</div>

.

REQUEST.
Want to add "MyTabClass" to the "div.mat-tab-body-content". I tried adding css style using !important, but still fails to apply custom styling or custom css class to the tags which are generated at runtime.

Please anybody aware about how to implement this guide me.
I am new to the Material Design with Angular 2

What is the use-case or motivation for changing an existing behavior?

To have a upperhand in the styling, when required. Usually we are using the default behaviour of material controls.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Latest version of all.
OS- windows 10

Is there anything else we should know?

Yes, this is not specifically related to the Mat-tabs. I was searching the way to apply custom css to any of the mat-X controls sub-elements which are auto-generated during rendering in browser

Most helpful comment

@willshowell
If a class was applied to the mat-tab, I would expect the generated html to apply the class to both the label and the body. This would allow the dev to manage both with the addition of the appropriate selector. (.mat-tab-label.first or .mat-tab-body.first)

<mat-tab-group>
   <mat-tab label="First" class="first">First</mat-tab>
   <mat-tab label="Second" class="second">Second</mat-tab>
</mat-tab-group>

Generated HTML is like this

<mat-tab-group>
   <mat-tab-header>
      ...
      <div class="mat-tab-label first">...</div>
      <div class="mat-tab-label second">...</div>
      ...
  </mat-tab-header>
   <div class="mat-tab-body-wrapper">
      <mat-tab-body class="mat-tab-body first">
        <div class="mat-tab-body-content">First</div>
      </div>
      <mat-tab-body class="mat-tab-body second">
        <div class="mat-tab-body-content">Second</div>
      </div>
   </div>
</mat-tab-group>

All 20 comments

You are likely just encapsulating your styles. Take a look at this guide and see if it helps:

https://material.angular.io/guide/customizing-component-styles

Why is this closed?

@ovoronin if you place the styles in a global stylesheet or remove view encapsulation from your component styles, they'll be applied.

@willshowell
For example I have

<mat-tab-group>
   <mat-tab label="First" class="first">First</mat-tab>
   <mat-tab label="Second" class="second">Second</mat-tab>
</mat-tab-group>

Generated HTML is like this

<mat-tab-group>
   <mat-tab-header>...</mat-tab-header>
   <div class="mat-tab-body-wrapper">
      <mat-tab-body class="mat-tab-body mat-tab-body-active">
        <div class="mat-tab-body-content">First</div>
      </div>
      <mat-tab-body class="mat-tab-body">
        <div class="mat-tab-body-content">Second</div>
      </div>
   </div>
</mat-tab-group>

As you can see there are no CSS classes 'first' and 'second' anywhere
It will be good to have them applied to corresponding mat-tab-body elements

I see. What DOM element would you expect to receive the class?

You could do this if you just wanted to style the body:

<mat-tab-group>
  <mat-tab label="First">
    <div class="first">First</div>
  </mat-tab>
  <mat-tab label="Second">
    <div class="second">Second</div>
  </mat-tab>
</mat-tab-group>

@willshowell
I was trying to style mat-tab-body elements to fix some scrolling stuff

@ovoronin I also wanted to style mat-tab elements, making them take all the available height.

I fixed them with flexbox using mat-tab-group { flex: 1; }in the component stylesheet and .mat-tab-body-wrapper { flex: 1; } in the global stylesheet.

Quick and dirty. It works but I'm quite sure it is not the best option :worried:

How to disable the animation that have been trigged when tab clicked ngtrigger translate-tab css

I have the same type of issue, where angular generates a wrapping <div> element inside the of the <mat-tab> tag in the generated code. In my case this <div> has display: flex set, where I want it to be display: block

My intuition tells me this is not the way we should be styling these elements. These generated components should never have to be touched if Angular is/was designed well. However if I change the display to block in DevTools as said above, I get the desired design and with flex I don't so, yeah... if it's possible, would like to know how :D

@willshowell What if placing them in the global styles is not possible? I have two types of tabs in my mat-tab-group and need to apply different styles to them. How would I accomplish this without applying classes to the specific mat-tabs?

@shootdaj I think you might be limited to a workaround like some manual class manipulation.

@andrewseguin what do you think? would it be possible to allow classes be applied to mat-tab?

@willshowell
If a class was applied to the mat-tab, I would expect the generated html to apply the class to both the label and the body. This would allow the dev to manage both with the addition of the appropriate selector. (.mat-tab-label.first or .mat-tab-body.first)

<mat-tab-group>
   <mat-tab label="First" class="first">First</mat-tab>
   <mat-tab label="Second" class="second">Second</mat-tab>
</mat-tab-group>

Generated HTML is like this

<mat-tab-group>
   <mat-tab-header>
      ...
      <div class="mat-tab-label first">...</div>
      <div class="mat-tab-label second">...</div>
      ...
  </mat-tab-header>
   <div class="mat-tab-body-wrapper">
      <mat-tab-body class="mat-tab-body first">
        <div class="mat-tab-body-content">First</div>
      </div>
      <mat-tab-body class="mat-tab-body second">
        <div class="mat-tab-body-content">Second</div>
      </div>
   </div>
</mat-tab-group>

@willshowell Any news on this? It would be great to have some flexibility over the control.

I tried to style a specific tab, but the class/style is thrown away when the tabs are generated in the browser.

You can use ng-template:

<mat-tab>
    <ng-template mat-tab-label>
        <span class="first">First Tab</span>
    </ng-template>
    ...

@shootdaj I found by accident once that you can add global styles with ::ng-deep

Just use ::ng-deep like this in ANY component - not nested under anything, and it will be propagated to root styles (assuming the defining component has been displayed) :

 // propagate to root styles
 ::ng-deep div { outline: 1px solid hotpink; }

You can do this to avoid having to put things in root styles - perhaps you don't have access to it, or you're writing a debugging control. Also this approach may not work forever, so you'll have to make your own judgement based on that.

I wish they would just officially support :root

As of today, the best approach I've found is just using inline styling:

<div style="display: block; color: blue;">
<div>content</div>
</div>
It was great for me. I hope it helps you all.

we can use CSS :nth-child() Selector. Thank you

A clean solution would be to:

  1. Apply a (custom) class to the <mat-tab-group> element.
<mat-tab-group class="custom-tabs"></mat-tab-group>
  1. Disable view encapsulation in the component which displays the tabs.
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  encapsulation: ViewEncapsulation.None
})

You can now style both .mat-tab-body and .mat-tab-body-wrapper.

.custom-tabs .mat-tab-body-wrapper {
  background: #eee;
}
.custom-tabs .mat-tab-body {
  padding: 20px;
}

In some cases you don't want to globally define all component styles, which happens when you disable view encapsulation. To prevent this, simply create a component that's dedicated to display (and style) tab groups.

I have to hack the css of mat-tab because when I use popover in mat-tab
the pop-over will hide by the overflow set in mat-tab-body-wrapper and .mat-tab-body.mat-tab-body-active
I use :host ::ng-deep to hack the mat-tab style

:host ::ng-deep .mat-tab-body-wrapper {
    overflow: visible;
    overflow-x: visible;
    overflow-y: visible;
    .mat-tab-body.mat-tab-body-active {
        overflow-x: visible;
        overflow-y: visible;
    }
}

2019-07-15 18-05-18 的屏幕截图

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

LoganDupont picture LoganDupont  ·  3Comments

3mp3ri0r picture 3mp3ri0r  ·  3Comments

alanpurple picture alanpurple  ·  3Comments

vitaly-t picture vitaly-t  ·  3Comments

savaryt picture savaryt  ·  3Comments