Angular Material button remove autofocus
Asked Answered
D

11

35

I have the following button

<td mat-cell *matCellDef="let element">
  <button mat-icon-button type="button" (click)="downloadStuff(element)">
    <mat-icon mat-icon matTooltip="{{element.someId}}">picture_as_pdf</mat-icon>
  </button>
</td>

All good but I noticed the little bugger gets outlined by default:

enter image description here

Ok.... CSS lets me remove the annoying outline withe the following:

button:focus {
    outline: none;
}

But then.. I still get this annoying default background focus:

enter image description here

I've tried a few overlay and background-related things in CSS and none of these seemed to address the issue. How do I remove this default background? And why does it behave like this by deafault???

See the selected item in dev tools. enter image description here

Doorstop answered 12/12, 2018 at 10:42 Comment(7)
This is normal behavior for Material design as you can see from this guide. Have you tried adding background-color: none; to your &:focus CSS ?Singles
Thanks Jake but background-color: none; was one of the first things I tried.Doorstop
If you use Chrome's DevTool and inspect the element and set it to focus, what CSS is applied ?Singles
Visual focus indication is an important part of usability. The solution to your problem is to remove focus, not to suppress the focus indicator because that would make for a bad user experience. It happens by default because of something you are doing or something you are using - we need to see how you are using the button to know why. Usually a simple button on a page does not get focus by default (e.g. xonklxyamje.angular.stackblitz.io code: stackblitz.com/angular/…).Rifleman
I added a copy of the selected button taken from dev tool in Chrome. The button is generated dynamical depending on the number of rows in the table. It is just added to one of the table's cells.Doorstop
You may be able set tabindex="-1" on the button if you want to remove it permanentlyByandby
This default behavior of material can be fixed if you can set the focus to any other button. Just add cdkFocusInitial on the button. It should make that button focused by defaultPlumbism
B
37

After clicking or touching on a Material Design button it stays focused ---> to resolve this, you need to add the following code: onclick="this.blur()"

<button mat-raised-button  onclick="this.blur()" (click)="onEdit()">Edit</button>

or in your case

<td mat-cell *matCellDef="let element">
    <button mat-icon-button type="button" onclick="this.blur()" (click)="downloadStuff(element)">
        <mat-icon mat-icon matTooltip="{{element.someId}}">picture_as_pdf</mat-icon>
    </button>
</td>
Beaut answered 26/9, 2019 at 11:21 Comment(4)
What's the difference between onclick and (click)?Accomplish
Here it was explained bought of with examples. w3schools.com/jsref/event_onclick.aspBeaut
It works, but the focus is shown for some miliseconds, then blur, making an ugly effect. I prefer the solution given by Rafique MohammedMoltke
This should be the accepted answer.Bandaranaike
M
31

In my case the real problem was the button structure. Angular Material builds various sub components and the last one is a 'div' with css class mat-button-focus-overlay:

My solution is simply. In style.css add or overwrite the mat-button-focus-overlay:

.mat-button-focus-overlay {
    background-color: transparent!important;
}
Mellar answered 4/3, 2019 at 14:42 Comment(0)
C
15

I was able to get rid of the default focused button by setting the attribute cdk-focus-start on other item. More info available here

Coly answered 7/8, 2019 at 14:14 Comment(1)
Thanks. Sent me in the right direction for my problem. FYI, cdk-focus-start deprecated, use cdkFocusRegionstart instead.Beveridge
M
7

In your styles css, just add this code. It will remove those annoying outline from all the buttons

button:focus {
    outline: none !important;
}
Mallissa answered 2/5, 2020 at 19:34 Comment(1)
I suppose there is a better solution to this, because the examples in material.angular.io/components/button/overview don't use this, but it works!Moltke
Y
6

Also try this.

<button mat-icon-button [autofocus]="false" (click)="closeDialog()">
  <mat-icon>clear</mat-icon>
</button>`

Just add [autofocus].

Yezd answered 7/8, 2019 at 2:24 Comment(1)
or you may put on the <button type="button"></button>.Yezd
B
6

Question is somewhat old. But I found a better solution for this.

Add tabindex="-1" to the button tag and problem solved!

<button tabindex="-1" mat-icon-button type="button" (click)="downloadStuff(element)">
    <mat-icon mat-icon matTooltip="{{element.someId}}">picture_as_pdf</mat-icon>
</button>
Barm answered 28/12, 2020 at 10:43 Comment(2)
This is not a better solution. You are removing keyboard navigation of tab.Mallissa
Thanks, a real solution among all these "why not fix the global styles to remove the initial focus, great idea"Obmutescence
D
3

Use this to remove both outline and auto focus in your .css:

button {
  outline: none;
}

::ng-deep .mat-button-focus-overlay {
  display: none;
}
Despatch answered 14/12, 2020 at 6:20 Comment(0)
A
1

If you don't want the focus to be on the close icon, one solution is that you make it focus on the 'Save' or 'Cancel' button initially. To do this, you need to add cdkFocusInitial in the button. For ex:

<div mat-dialog-actions>
   <button mat-flat-button>Cancel</button>
   <button mat-flat-button cdkFocusInitial>Submit</button>
</div>
Aloeswood answered 3/10, 2022 at 11:56 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Alkaline
C
0

for :focus, :cdk-keyboard-focus and so on, you can remove box-shadow

box-shadow: none;
Cythera answered 2/11, 2021 at 12:16 Comment(0)
N
0

Put the following css code in your outermost style file.

.mat-focus-indicator::before {
border-color: transparent !important; }
Nsf answered 23/6, 2022 at 14:40 Comment(0)
S
0

I solved this by following (sort of) the Accessibility section of Angular Material.

Here is my AppComponent:

export class AppComponent implements AfterViewInit {
    @ViewChild("appContainer") appContainer: ElementRef<HTMLElement>;

    appContainerOrigin = this._formatOrigin(null);

    constructor(
        private _focusMonitor: FocusMonitor,
        private _cdr: ChangeDetectorRef,
        private _ngZone: NgZone,
    ) {}

    ngAfterViewInit(): void {
        this._focusMonitor.monitor(this.appContainer, true).subscribe((origin) =>
            this._ngZone.run(() => {
                this.appContainerOrigin = this._formatOrigin(origin);
                this._cdr.markForCheck();
            }),
        );
    }

    private _formatOrigin(origin: FocusOrigin): string {
        return origin ? origin + " focused" : "blurred";
    }
}

Its template:

<div #appContainer class="app-container">
    <app-header></app-header>

    <div class="content-container">
        <router-outlet></router-outlet>
    </div>

    <app-footer></app-footer>
</div>

And the styles.scss file at the root of the project:

.cdk-mouse-focused *:focus {
    --mdc-list-list-item-focus-state-layer-color: none;
}

FocusMonitor adds a CSS class to the .app-container div which tells you how the focus was made. I then remove the color layer associated to the focus from the focused element if it was made by a mouse click. That way you get the same behavior as the Angular Material doc, as you can see in the Buttons doc. I don't think the Angular Material team implemented it like that, and I also don't think that's the ideal way to achieve it (a simple directive built in Angular Material by default would be nice) but it's the closest I could get from the expected behavior.

Schnorrer answered 18/9, 2023 at 18:0 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.