103

This question comes from the Material2 Github repo.

I still have problems to style a Material component that is wrapped in a custom component.

I have a <logo> component that contains <md-icon svgIcon="logo"></md-icon>

Adding:

:host { 
   .mat-icon {
    width: 100px;
    height: 100px;
    font-size: 56px;
  }
}

Will not apply to the Material component inside my custom component.

Vega
  • 27,856
  • 27
  • 95
  • 103
Mackelito
  • 4,213
  • 5
  • 39
  • 78
  • 1
    "Within" or "on"? The `:host` syntax is meant to apply to the component itself, and **not** to it's children. Sounds like you have a "child" of `md-icon`, and that means you just want to adjust the css with just the plain class and not using `:host` – Neil Lunn May 10 '17 at 09:28
  • The `width`/`height`/`font-size` overrides are better suited for the built-in material icons. Unfortunately, changing the font size won't work when you're using the `svgIcon` – Will Howell May 10 '17 at 13:06

12 Answers12

116

In my case, this works perfectly. I use newest material (6.2.0)

CSS:

.icon {
    font-size: 36px;
}

HTML:

  <div class="icon">
    <mat-icon [inline]="true">done</mat-icon>
  </div>

The main thing is to set: [inline]="true"

From the API:

@Input() inline: boolean - Whether the icon should be inlined, automatically sizing the icon to match the font size of the element the icon is contained in.

bob
  • 2,674
  • 1
  • 29
  • 46
Mariusz.v7
  • 2,322
  • 2
  • 16
  • 24
74

UPDATE: 2019-05-22

Newer versions of Material Design has the option to set [inline]="true" as a property on the HTML element.

I would recommend using that approach instead.

<mat-icon svgIcon="thumbs-up" inline="true"></mat-icon>

When using this, the icon will inherit from the parent container!

GLHF! :)


I have been getting some questions about this so I just wanted to make a clearer example of how to use it...

/* 1. Add this mixin to a "global" scss */

@mixin md-icon-size($size: 24px) {
  font-size: $size;
  height: $size;
  width: $size;
  line-height: $size;
}

/* 2. Then use it like this in you component scss */

mat-icon {
  @include md-icon-size(32px);
}

example usage

<mat-icon class="myIcon" svgIcon="search"></mat-icon>
:host {
  .myIcon {
    &mat-icon {
      @include md-icon-size(32px);
    }
  }
}
Mackelito
  • 4,213
  • 5
  • 39
  • 78
  • 5
    This solution uses SCSS, what would be the vanilla CSS solution? Furthermore, this only changes the bounding-box size of the wrapper `` element, not the `` element contained within. – Gerardo Figueroa Feb 16 '18 at 15:58
  • note that this will have unexpected behavior when using `em` unit, because em relates on the element's `font-size`. So `@include md-icon-size(3em);` will actually make it `9em` – Martin Schneider Apr 02 '18 at 19:25
  • I agree to @GerardoFigueroa 's point. It is not changing the size of the svg, its just changing the size of the bounding box. – monica Dec 14 '18 at 08:20
  • Adding !important will do the job, like this font-size: $size !important; – Divyanshu Rawat Jul 12 '19 at 22:24
37

I'm using

<mat-icon svgIcon="cellphone-link"></mat-icon>

with

.mat-icon {
    transform: scale(2);
}

for resizing the svg element. It was the only working solution for me, where 2 is 200% of the actual size (downsizing to e.g. 0.5 would be possible also).

Setting "height" and "width" was no option for me, because the rendered svg element of the mat-icon component has no viewBox attribute at the moment. But the viewBox attribute is mandatory to make it work with "height" and "width" styling. Maybe the Angular Material team will improve that in future.

As a side note: You can center the mat-icon with a parent wrapper and

display: flex;
align-items: center;
justify-content: center;
Pierre Chavaroche
  • 1,253
  • 16
  • 12
9

Edit: Please see the accepted answer!

Using it like this works just fine.

<md-icon svgIcon="arrow-down" class="size-16"></md-icon>

when having defined this in theme css (not in component :host)

md-icon.size-16 {
  width: 16px;
  height: 16px;
  line-height: 16px;
}
Mackelito
  • 4,213
  • 5
  • 39
  • 78
7

To make sure the icon remains centered within its in-build container (within <mat-icon> component) after it is resized, use this solution. Does not need a wrapper box nor the inline=true property.

HTML

<mat-icon class="big">error_outline</mat-icon>

CSS

.big {
  width: 2rem;
  height: 2rem;
  font-size: 2rem;
}

Note: You can also use other units, like px or em

Patronaut
  • 1,019
  • 10
  • 14
6

Try this.

@mixin md-icon-size($size: 24px) {
  font-size: $size;
  height: $size;
  width: $size;
}

.material-icons.mat-icon {
  @include md-icon-size(32px);
}
eltonplima
  • 161
  • 1
  • 6
4

I think the problem is caused by inlining the svg without viewBox - preventing all resizing attempts.

Seems to me the alternative is using the iconfont directly:

<i class="material-icons" style="font-size: 40px">face</i>
Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Jorg Janke
  • 1,027
  • 7
  • 9
1

Worked for me

HTML

  <button mat-fab>
    <mat-icon class="md-36" inline aria-label="Home button">
      home
    </mat-icon>
  </button>
  <button mat-fab>
    <mat-icon class="md-48" inline aria-label="Up button">
      expand_less
    </mat-icon>
  </button>

CSS

.material-icons.md-18 {
  margin-top: -3px;
  font-size: 18px;
}
.material-icons.md-24 {
  margin-top: -3px;
  font-size: 24px;
}
.material-icons.md-36 {
  margin-top: -3px;
  font-size: 36px;
}
.material-icons.md-48 {
  margin-top: -4px;
  font-size: 48px;
}

The icons are properly centered and the wrapper div doesn't overflow the fab/button Not too elegant I guess

0

One other possible option, if you want to have the option to scale images to any font size up to a maximum (e.g. 300px), the following scss loop would work;

@for $i from 1 through 300{
  .iconsize-#{$i}{
    font-size: $i+unquote('px') !important;
    height: $i+unquote('px') !important;
    width: $i+unquote('px') !important;
  };
}

If you want to set a minimum size to generate in the compiled CSS, simply change 1 above to the minimum size you'd like and likewise, to change the maximum value, change 300 to whatever maximum value you'd like.

This is particularly handy for the icons as being SVG, they will scale to the size you set (though I've had some trouble getting third-party SVG icons scaling to fit the container, but that's a different issue). If you're like me, you often need to have the majority of icons at a specific size (e.g. menu icons) with some icons being larger (e.g. decorative elements). This loop allows you to easily test different sizes of font up to any size at 1px increments until you find a size that works for you.

What does this do?

When your SCSS is compiled to CSS, it will output a loop with the relevant classes from 1 to 300.

How do I use it?

To use, simply add the .iconsize-[x] class to your mat-icon;

<mat-icon class="iconsize-45">show_chart</mat-icon>

This example will set the icon to be 45px width and height.

Scott P
  • 1,462
  • 1
  • 19
  • 31
  • Hmm.. interesting idea but for me I see no case where I would want to limit to a max-size.. and also I would never use !important :P – Mackelito Jan 30 '18 at 08:04
  • @Mackelito The reason to set a max size is simply because you will end up with a huge CSS file (and the logic for a loop requires it). The other option is to use inline properties. – Scott P Jan 30 '18 at 12:16
0

Simplest way to do it (with no extra CSS), the following works fine

    <sup><mat-icon inline="true">info</mat-icon></sup>
<small><mat-icon inline="true">info</mat-icon></small>
<big><mat-icon inline="true">info</mat-icon></big>

Please note the inline="true" which makes it inherit styling of parent tag

Madis Männi
  • 168
  • 1
  • 5
0

An alternative solution using the [ngStyle] directive.

When you simply want to overwrite the size of a mat-icon only once without making a stylesheet you can also easily do that using the ngStyle directive on the mat-icon component as follows:

<mat-icon [ngStyle]="{ 'width.px': 64, 'width.px': 64 'font-size.px': 64 }">build</mat-icon>

Or when defining the size in your component:

this.size = 64;

and then:

<mat-icon [ngStyle]="{ 'width.px': size, 'width.px': size 'font-size.px': size }">build</mat-icon>

This solution works because you are adding inline styling on the mat-icon host component directly.

Wrapping the above solution into a custom directive.

The above mentioned solution can be easily wrapped into a directive if you want to reuse the sizing multiple times in your application:

import { Directive, HostBinding, Input, OnInit } from '@angular/core';

@Directive({
  selector: '[appIconSize]',
})
export class IconSizeDirective {

  @HostBinding('style.width') @HostBinding('style.height') @HostBinding('style.font-size') @Input('appIconSize') public size: string;
    
}

and then:

<mat-icon appIconSize="64px">build</mat-icon>

Checkout a working example of both solution in the following StackBlitz.

Wilt
  • 41,477
  • 12
  • 152
  • 203
0

I am using Angular Material version 13.3.9.

In my case, both the button and the icon needed css:

.add-button-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 30px;
  width: 30px;
}

.mat-icon {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 30px;
  width: 30px;
}
<button mat-mini-fab class="add-button-container" color="primary"
                                            aria-label="icon button with an add icon">
                                            <mat-icon>add</mat-icon>
                                        </button>
Thinking
  • 747
  • 5
  • 11