Search code examples
angularangular-material

How to get the size of the Angular Material button? (AM version >7.2)


When using Angular Material (version > 7.2.2): The Angular Material team removed the (previously available) globally accessible CSS custom property "--mdc-icon-button-state-layer-size".

AFAIK, it's now not possible anymore to know the size of a button in Angular Material. Is there any other way to know the size of a Material button? (I feel a bit ashamed to use Angular Material, now that I have to ask such questions).

I asked this question already on GitHub (https://github.com/angular/components/issues/28738); but all I got was a off-topic answer by an Google employee and the issue was closed and it seems to have been erased, behind the sofa and gone into the Google void.

I was expecting to get the size of an Angular Material Button.


Solution

  • You can use getBoundingClientRect to get the size of the button.

    1. Add a template variable to the button you want to get the size of.
    2. Use viewChild or @ViewChild to get the button.
      • Make sure to add the { read: ElementRef } option.
    3. use getBoundingClientRect() on the nativeElement to get the size.

    Based on your Github question, here is a working example.

    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [MatButtonModule],
      template: `
        <button #btn mat-flat-button color="primary">My Button</button>
      `,
    })
    export class App {
      btn = viewChild('btn', { read: ElementRef });
    
      ngAfterViewInit() {
        const rect = this.btn()?.nativeElement.getBoundingClientRect();
        console.log(rect);
        // Output:
        // { x: 0, y: 0, width: 106, height: 36, top: 0, left: 0 }
      }
    }
    

    Here is the StackBlitz code, it calculates half the button size and sets a CSS variable called --half-height that can be used on other items in the CSS using var(--half-height).

    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [MatButtonModule],
      styles: `
        :host {
          .wrapper {
            display: flex;
            flex-direction: row;
            gap: 20px;
          }
    
          button {
            flex: 1;
          }
    
          .box {
            flex: 1;
            height: var(--half-height);
            background: red;
          }
        }
      `,
      template: `
      <div class="wrapper">
        <button #btn mat-flat-button color="primary">My Button</button>
    
        <div class="box"></div>
      </div>
      `,
    })
    export class App {
      btn = viewChild('btn', { read: ElementRef });
    
      set halfBinding(value: string) {
        document.documentElement.style.setProperty('--half-height', value);
      }
    
      ngAfterViewInit() {
        const rect = this.btn()?.nativeElement.getBoundingClientRect();
        this.halfBinding = rect.height / 2 + 'px';
      }
    }