24

I am attempting to override the default max-width of the snackbar component in Angular Material.

The CSS applied by Angular Material is shown below:

.mat-snack-bar-container {
    border-radius: 2px;
    box-sizing: border-box;
    display: block;
    margin: 24px;
    max-width: 568px;
    min-width: 288px;
    padding: 14px 24px;
    transform: translateY(100%) translateY(24px);
}

I have tried overriding using the same style in my style.css file but this style is overridden by the default style.

 .mat-snack-bar-container {
   max-width: 800px;
 }

I have found an answer to a similar question but I know the answer to that question is now deprecated (/deep/ is deprecated).

Is there a best practices solution to this?

Tony Scialo
  • 5,457
  • 11
  • 35
  • 52
  • .mat-snack-bar-container { max-width: 800px!important; } – Mehdi Dec 12 '17 at 01:03
  • I've tried avoid !important tags as well as they could be considered bad practice as well – Tony Scialo Dec 12 '17 at 01:04
  • in this case you need add the component name where you use the snack your-component-tag .mat-snack-bar-container { max-width: 800px; } – Mehdi Dec 12 '17 at 01:35
  • Possible duplicate of [Override Angular Material style in Angular component](https://stackoverflow.com/questions/44089246/override-angular-material-style-in-angular-component) – cgatian Dec 12 '17 at 01:39
  • @TonyScialo use the `:ng-deep` syntax. This one will be around for awhile until css variables are supported by more browsers. – cgatian Dec 12 '17 at 01:40
  • @cgatian, would you suggest using :ng-deep or the answer below in which ViewEncapsulation is set to none? – Tony Scialo Dec 12 '17 at 15:23
  • 1
    Personally I would use ng-deep. Especially if someone is going to be consuming my components. The `ViewEncapsulation.None` is essentially updating your `styles.css` file with the style and actually would probably cause more confusion to where the style is coming from. My only use for considering `ViewEnapsulation.None` would be dynamically loading some styles across the entire page when a particular component is initialized. The examples Angular uses assumes you don't have a `styles.css` in your project and if youre using the CLI you do. – cgatian Dec 12 '17 at 18:08

11 Answers11

22

To do this properly, you need to set the View Encapsulation to None on your component:

@Component({
    templateUrl: './my.component.html' ,
    styleUrls: ['./my.component.css'], 
    encapsulation: ViewEncapsulation.None,
})

Then in your component css you can just do this:

.mat-snack-bar-container {
   max-width: 800px;
}

From the official docs:

View Encapsulation = None means that Angular does no view encapsulation. Angular adds the CSS to the global styles. The scoping rules, isolations, and protections discussed earlier don't apply. This is essentially the same as pasting the component's styles into the HTML.

Andrei Matracaru
  • 3,511
  • 1
  • 25
  • 29
13

Put css in your styles.scss or styles.css

.snackbar {
    max-width: 90% !important;
    margin-left: auto !important; // center align from left
    margin-right: auto !important; // center align from right
    margin-bottom: 1rem !important; 
    padding: 10px !important; // spacing between the text and boundary
    background-color: green;
    color: white;

    .mat-button-wrapper {
        color: black !important; // action text color
    }
}

Note: make sure you have set !important with every style, without it, style wouldn't work.

in component.ts

this.snackbar.open(this.resMsg.message, 'OK', {
    panelClass: 'snackbar'
})

enter image description here

WasiF
  • 26,101
  • 16
  • 120
  • 128
7

Verified for @angular/material v7.0.x:

CSS !important modifier does the trick.

Put this is src/styles.scss (the app's global css):

.mat-snack-bar-container {
  max-width: 100% !important;
}

Also we tweak its font:

/* Overrides SnackBar CSS in Material Design's .mat-simple-snackbar class */
/* Original sizes: font: 24px, height: 47.952px */ 
.mat-simple-snackbar {
  display: flex; 
  font-size: 28px !important; // 28px  is double, 42px for triple
  min-height: 70px !important; // 70px for double, 90px for triple
  align-items: center !important;
  justify-content: center !important;
}
Paul Lockwood
  • 4,283
  • 1
  • 24
  • 19
2

As of June 30, 2019, using Angular Material 8.0.1 with Angular 8.0.3, the following SCSS and typescript seems to work for overriding the color of the action button in an Angular Material snackbar *without using !important *:

styles.scss (not the extremely long duration, which allowed me to inspect the styling before it disappeared):

$snackBarTextColor: white;
$snackBarBackgroundNormal: #087a51;
$snackBarActionColor: lightgray;
.snackBarInfo {
    background-color: $snackBarBackgroundNormal;
    color: $snackBarTextColor;


}
.mat-simple-snackbar > span {
    font-weight: bold;
}
.mat-simple-snackbar-action {
    .mat-button {
        .mat-button-wrapper {
            color: $snackBarActionColor;
        }
    }
}

app.module.ts:

import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar';
providers: [
        {
            provide: MAT_SNACK_BAR_DEFAULT_OPTIONS,
            useValue: {
                duration: 41000,
                horizontalPosition: 'center',
                verticalPosition: 'bottom',
                panelClass: 'snackBarInfo'
            }
        }
    ]
user3785010
  • 1,029
  • 1
  • 10
  • 11
2

I remember working in a project with web-designers, and they had a money-jar, where devs had to put a coin in if they used the !important statement. ;)

The other solutions did not work for me, unless i set the .cdk-overlay-pane (using material 11):

.cdk-overlay-pane {
    width: 100%;
}

.mat-snack-bar-container {
    max-width: 100%;
    width: 100%;
}
Guntram
  • 961
  • 14
  • 19
1

Not sure when Material introduced this (must be a new thing judging by all the answers to this thread), but you can now override the mat-snack-bar-container's styles by passing a parameter in the _snackBar.open(), like this:

component.ts

openSnackBar(message: string, action: string) {
    this._snackBar.open(message, action {
        panelClass: 'my-custom-container-class',
    });
  }

component.scss

::ng-deep .my-custom-container-class{
    max-width: 100% !important;
    min-width: 0% !important;
    min-height: 0 !important;
    padding: 0 !important;
    margin: 32px !important;
    box-shadow: none;
}

I'm afraid you still have to use the ng-deep and the !importants; but at least you no longer need to do ViewEncapsulation None.

adab4
  • 11
  • 2
1

FYI Starting with Angular Material v15 with the migradtion to MDC, the class .mat-snack-bar-container has been renamed to .mat-mdc-snack-bar-container

I also had to use some of the new inner MDC snackbar classes to properly recolor the snackbar starting in v15:

SCSS:

// Classname used in the MatSnackBarConfig obj of MatSnackBar.open():
// panelClass: ['my-snackbar-class']

my-snackbar-class.mat-mdc-snack-bar-container {
  .mdc-snackbar__surface {
    // Background color of entire snackbar:
    background-color: red;

    .mdc-snackbar__label {
      // Color of snackbar text:
      color: white;
    }

    button {
      // Color of snackbar button text:
      color: white !important;
    }
  }
}
RcoderNY
  • 1,204
  • 2
  • 16
  • 23
1

Found this discussion https://github.com/angular/components/issues/26928

since Angular 15 MDC the snackbar styles can be overriden as follows (where success-snackbar is your panelClass):

.success-snackbar {
  --mdc-snackbar-container-color: green;
  --mat-mdc-snack-bar-button-color: white;
  --mdc-snackbar-supporting-text-color: white;
  --mat-snack-bar-button-color: white;
}
Daulet
  • 96
  • 5
0

The way to go.


encapsulation: ViewEncapsulation.None

Here is a stackblick to demonstrate

Deunz
  • 1,776
  • 19
  • 32
0

Angular 10 and without special tricks:

  1. use panelClass when opening the snackbar, for example:
this.snackBar.open("VeryLongTextWithoutThePossibilityOfBreakingAutomatically", "X", {
    duration: 0,
    panelClass: 'notif-error'
});

duration: 0 is only for debugging.

  1. write this into your style.css
.notif-error {
    background-color: red;
}
.mat-snack-bar-container.notif-error {
    max-width: 100%;
}

Now because of css-specificity, this will be the most specific rule.

  • Beware that there should not be space between .mat-snack-bar-container and .notif-error.
  • This rule will apply to elements which has both the .mat-snack-bar-container and .notif-error classes.
  • This also works when your .notif-error class is empty.
PeterB
  • 960
  • 6
  • 8
0

Using vw works for me,on both bigger and small screen size

    .mat-snack-bar-container {
    margin-right: auto !important;
    margin-left: auto !important;
    width: 80vw !important;
    max-width: 100vw !important;
}

enter image description here

Qin Chenfeng
  • 451
  • 6
  • 5