Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot customize style of md-tabs #1276

Closed
albanx opened this issue Sep 19, 2016 · 27 comments
Closed

Cannot customize style of md-tabs #1276

albanx opened this issue Sep 19, 2016 · 27 comments
Assignees

Comments

@albanx
Copy link

albanx commented Sep 19, 2016

Bug, feature request, or proposal:

Adding custom style to the tabs header

What is the expected behavior?

affect css style of header (font size, color, display....)

What is the current behavior?

Style is beeing totally ignored due to attribute selectors generated by the own element ignoring the styleUrls ones

What are the steps to reproduce?

Create a simple element (html):

<md-tab-group>
    <md-tab>
        <template md-tab-label>Personal info</template>
        <template md-tab-content>
            <h4>Name, address</h4>
            <div class="">
                Some data here
            </div>
        </template>
    </md-tab>

    <md-tab>
        <template md-tab-label>Payment</template>
        <template md-tab-content>

            <div class="">
                Payment setup
            </div>
        </template>
    </md-tab>
</md-tab-group>

Add this style in the .scss:

md-tab-group {
    .md-tab-header {
        font-size: 12px !important;
        display: flex;
        flex-flow: row wrap;
        align-items: center;
        .md-tab-label {
            flex: 1;
            min-width: 1px;
        }
    }
}

Plunk demo http://plnkr.co/edit/K1iVNV

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

Need to customize md tabs style/colors/responsive

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

Angular 2.0, Material alpha 8-2

Is there anything else we should know?

@RoxKilly
Copy link

RoxKilly commented Sep 20, 2016

I see two problems with your Plunk

  1. Your styles are not valid CSS:
/*CSS styles should not be nested*/
md-tab-group {
   .md-tab-header{
    ...
   }
}
  1. Styles in components are isolated, so the Material component (md-tab-group) cannot see your App component styles. Put the styles you want to override in a main CSS file that you link to from your index.html.

On this Plunk, I have implemented some of the styles you were going for by putting them in index.css

@albanx
Copy link
Author

albanx commented Sep 20, 2016

I just copy pasted it, I am using scss in my code. But I am able to customize style of md-card for example. I edit the plunk example http://plnkr.co/edit/K1iVNV?p=preview.

I notice that my component is generating this css for my style:

md-tab-group[_ngcontent-yed-6]   .md-tab-header[_ngcontent-yed-6] {
  font-size: 12px !important;
  display: flex;
  flex-flow: row wrap;
  align-items: center; }
  md-tab-group[_ngcontent-yed-6]   .md-tab-header[_ngcontent-yed-6]   .md-tab-label[_ngcontent-yed-6] {
    flex: 1;
    min-width: 1px; }

But this is being override by this css, where the attribute selector _nghost-yed-7 get priority since it is present in the tag of the tab header:

[_nghost-yed-7] { display: flex; flex-direction: column; font-family: Roboto, "Helvetica Neue", sans-serif; }  .md-tab-header[_ngcontent-yed-7] { overflow: hidden; position: relative; display: flex; flex-direction: row; border-bottom: 1px solid #e0e0e0; flex-shrink: 0; }  .md-tab-label[_ngcontent-yed-7] { line-height: 48px; height: 48px; padding: 0 12px; font-size: 14px; font-family: Roboto, "Helvetica Neue", sans-serif; font-weight: 500; cursor: pointer; box-sizing: border-box; color: currentColor; opacity: 0.6; min-width: 160px; text-align: center; } .md-tab-label[_ngcontent-yed-7]:focus { outline: none; opacity: 1; background-color: rgba(178, 223, 219, 0.3); } .md-tab-disabled[_ngcontent-yed-7] { cursor: default; pointer-events: none; }  .md-tab-body-wrapper[_ngcontent-yed-7] { position: relative; overflow: hidden; flex-grow: 1; display: flex; }  .md-tab-body[_ngcontent-yed-7] { display: none; overflow: auto; box-sizing: border-box; flex-grow: 1; flex-shrink: 1; } .md-tab-body.md-tab-active[_ngcontent-yed-7] { display: block; }  md-ink-bar[_ngcontent-yed-7] { position: absolute; bottom: 0; height: 2px; background-color: #009688; transition: 350ms ease-out; }/*# sourceMappingURL=tab-group.css.map */

I really cannot understand this behavior, it seems that md-tabs are a sort of subcomponent...?!

@anderflash
Copy link

You need to use /deep/:

/deep/ md-tab-group {
...

@vinagreti
Copy link
Contributor

Even using /deep/ the styles are not applied. You must use !important to ensure the style will be applied.
So, the question is, what is the correct way of doing style modification in md components? I my case, I could not change md-checkbox margins when placing it inside a table <td>. So I ended up with this code to be possible to change the checkbox style

/deep/ .md-checkbox-inner-container{
    margin: 4px 0px 0px 0px !important;
}

The problem is that I do not want to use !important, so, how can I do this without !important?

@anderflash
Copy link

Sometimes I need to put a more specific selector, for example:

body <selector> {... 

instead of

<selector> {...

If you use SCSS you can use the hierarchy feature to get a better specification of the selectors, and they will win this "competition".

@vinagreti
Copy link
Contributor

vinagreti commented Oct 17, 2016

What do you mean by "the hierarchy feature"?

Let's say I have a component that is a table and then I place a md-checkbox at the first column of the tbody rows, so, how can I use the hierarchy feature to change the md-checkbox positioning without using !important and /deep/?

@anderflash
Copy link

Let's say we have:

<div class="articles">
  <article>
    <md-checkbox></md-checkbox>
  </article>
</div>

So you would style in SCSS in this way:

.articles{
  color: blue; /*style for entire articles section */
  article{
    color: red; /* style for each article*/
    /deep/ md-checkbox .md-checkbox-inner-container{
      margin: 4px 0px 0px 0px;
    }
  }
}

It will be translated to:

.articles{
  color: blue;
}
.articles article{
  color: red;
}
.articles article /deep/ md-checkbox .md-checkbox-inner-container{
  margin: 4px 0px 0px 0px;
}

So .articles article /deep/ md-checkbox .md-checkbox-inner-container may be specific enough to style the proper component without !important. As md-checkbox is a component, I think we need to edit the component style itself to change it without /deep/.

@vinagreti
Copy link
Contributor

Thanks @anderflash. Using /deep/ md-checkbox .md-checkbox-inner-container worked for me.

So we can assume that it is the right behavior because Angular 2 styles (except those that are loaded by index.html) are scoped to the component so one component should not be able to change nested components unless you use /deep/?

@anderflash
Copy link

That's also my view about this issue. I'm also learning it and the tools are evolving rapidly. It still seems like a hack to put /deep/ wherever we want back default css behavior (changing nested components without context). So I think it will change in the future.

@andrewseguin andrewseguin self-assigned this Nov 3, 2016
@andrewseguin
Copy link
Contributor

There are three ways to resolve this right now.
(1) Set view encapsulation to NONE on the component that hosts your tabs and use your component style sheet
(2) Load a separate style sheet apart from Angular (e.g. through index.html) that affects the tabs
(3) Use /deep/, which has so far been deprecated from the spec but still supported by Angular for the time being. Not recommended.

@albanx
Copy link
Author

albanx commented Nov 11, 2016

@andrewseguin None of that 3 methods help to customize some styles right now the style of a md-tab header. The only way for now, is to use the !important keyword on the style (and this is not recommended really).
I can set the encapsulation to NONE of my component, but this will affect only my component, not Tabs component. => this seems to be wrong
You're closing an issue that is an issue, style should be customized.

@andrewseguin
Copy link
Contributor

andrewseguin commented Nov 11, 2016

Perhaps I'm misunderstanding your issue. I am able to change the styling on this tab header by removing view encapsulation and applying styles that have a higher specificity than those defined in the default md CSS.

http://plnkr.co/edit/J6Wnn0?p=preview

@albanx
Copy link
Author

albanx commented Nov 11, 2016

No you've not misunderstood it. In your case, as you can see, the encapsulation was not enough, you've added also .my-tabs class. Any case this seems to be a better solution, I would have preferred to have a way just to customize the style without breaking the "rules"

@andrewseguin
Copy link
Contributor

Yes, it is necessary to use higher specificity in CSS selectors in order to override the default style of the tab header. Does this solution not fit your needs?

@albanx
Copy link
Author

albanx commented Nov 12, 2016

Let says yes but in general I would like to preserve encapsulation of my component and be able to customize the style of my app at the same time.

@andrewseguin
Copy link
Contributor

I would like to be able to do that as well, but unfortunately this is beyond the bounds of what can be done in material (or any UI toolkit) due to how angular 2 is implemented. Feel free to file an issue with angular to suggest this.

@FilipeQ
Copy link

FilipeQ commented Dec 27, 2016

encapsulation to NONE is the better way to customize tabs component?

@AbdallahBedir
Copy link

@andrewseguin why you didn't set "md-tab-group" component encapsulated to none ?

@ivanntis
Copy link

ivanntis commented Apr 20, 2017

I resolve my problem

/deep/ .mat-tab-label{
line-height: 28px !important;
height: 28px !important;

}
/deep/ .mat-tab-header {
background-color: #0288D1;
color: white;
border-radius: 5px 5px 0px 0px;
}
/deep/ .mat-ink-bar {
background-color: #d14b02 !important;
min-width: 120px;
}

result
captura de pantalla 2017-04-20 a las 7 38 53 a m

Tankyou

@ArnoutPullen
Copy link

Maybe the same way you can style a toolbar like this:

<md-toolbar color="primary">Title</md-toolbar>

<md-tab-group color="primary"> <md-tab label="Title">Content</md-tab> </md-tab-group>

@mist3r3
Copy link

mist3r3 commented May 22, 2017

Hello, it works indeed as @ivanntis said. But even if I can change all of the tabs, how can I change only one tab style? I want to add a + at the end in order to add a tab.
Thank you.

@ksiabani
Copy link

ksiabani commented Jul 18, 2017

Already mentioned, but I see a few adopting the /deep/ solution. /deep/ is being deprecated, sooner or later your apps will break.

@mist3r3
Copy link

mist3r3 commented Jul 19, 2017

So what is the best solution?

@ksiabani
Copy link

@mist3r3 the choices you have are as reported by @andrewseguin earlier in this thread. Since /deep/ is being deprecated the solutions you are left with are (copied from @andrewseguin above):

(1) Set view encapsulation to NONE on the component that hosts your tabs and use your component style sheet
(2) Load a separate style sheet apart from Angular (e.g. through index.html) that affects the tabs

Personally I use option 1.

@jraadt
Copy link

jraadt commented Jul 30, 2017

The issue with (1) setting the view encapsulation to NONE is those styles bleed throughout the entire app. If my component's stylesheet I had h1 { color: blue } then when changing the component from Emulated to None it makes ALL h1 elements blue that don't have a color defined by a more specific rule.

I would like to say "make this component and all it's children" h1's blue. Setting encapsulation to none I would have to add an application-wide unique selector to my component and use that in the component's stylesheet. But that's what I'm trying to get away from doing and why I fell in love with component view encapsulation.

@AnthonyNahas
Copy link

@anderflash i did the same thing!
i wrapped it into a css class e.g --> class ="test"
--> test{
/deep/ md-checkbox .md-checkbox-inner-container{
margin:..;
}
}

and its works!

@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests