Угловой материал, перекрывающий стиль по умолчанию компонента SnackBar

Я пытаюсь переопределить стандартную максимальную ширину компонента закусочной в Angular Material.

CSS, примененный Angular Material, показан ниже:

.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);
}

Я попытался переопределить, используя тот же стиль в моем файле style.css, но этот стиль переопределяется стилем по умолчанию.

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

Я нашел ответ на подобный вопрос, но я знаю, что ответ на этот вопрос в настоящее время не рекомендуется (/deep/ устарел).

Есть ли передовое решение для решения этой проблемы?

11 ответов

Чтобы сделать это правильно, вам необходимо установить для параметра "Вид инкапсуляции" значение "Нет" в компоненте:

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

Затем в вашем компоненте CSS вы можете просто сделать это:

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

Из официальных документов:

View Encapsulation = None означает, что Angular не выполняет инкапсуляцию вида. Angular добавляет CSS к глобальным стилям. Обсуждаемые ранее правила определения границ, изоляции и защиты не применяются. По сути, это то же самое, что и вставка стилей компонента в HTML.

Положить CSS в свой styles.scss или же 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: #0b8357;
    color: #f7f0cf;

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

Примечание: убедитесь, что вы установили !important с каждым стилем, без него стиль не будет работать.

в component.ts

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

Проверено на @ angular / material v7.0.x:

CSS ! Важный модификатор делает свое дело.

Поместите это как src/styles.scss (глобальный css приложения):

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

Также мы настраиваем его шрифт:

/* 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;
}

Я помню, как работал над проектом с веб-дизайнерами, и у них была копилка, куда разработчикам приходилось класть монету, если они использовали оператор !important. ;)

Другие решения у меня не сработали, если только я не установил .cdk-overlay-pane (используя материал 11):

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

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

Нашел это обсуждение https://github.com/angular/comComponents/issues/26928 .

начиная с Angular 15 MDC стили закусочной можно переопределить следующим образом (гдеsuccess-snackbarваш класс панели):

      .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;
}

По состоянию на 30 июня 2019 года, используя Angular Material 8.0.1 с Angular 8.0.3, следующие SCSS и машинописный текст работают для переопределения цвета кнопки действия в снэк-баре Angular Material * без использования! Важный *:

styles.scss (не очень длительный период, который позволил мне проверить стиль до его исчезновения):

$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'
            }
        }
    ]

К вашему сведению, начиная с Angular Material v15 с переходом на MDC, класс.mat-snack-bar-containerбыл переименован в.mat-mdc-snack-bar-container

Мне также пришлось использовать некоторые из новых внутренних классов закусочной MDC, чтобы правильно перекрасить закусочную, начиная с v15:

СКСС:

      // 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;
    }
  }
}

Не уверен, когда Material представил это (судя по всем ответам в этой теме, это должно быть что-то новое), но теперь вы можете переопределить стили mat-snack-bar-container, передав параметр в _snackBar.open() , например :

компонент.ts

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

компонент.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;
}

Боюсь, вам все равно придется использовать ng-deep и !importants; но, по крайней мере, вам больше не нужно делать ViewEncapsulation None.

С использованием vw работает для меня, как на большом, так и на маленьком экране

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

Angular 10 и без особых ухищрений:

  1. используйте panelClass при открытии закусочной, например:
this.snackBar.open("VeryLongTextWithoutThePossibilityOfBreakingAutomatically", "X", {
    duration: 0,
    panelClass: 'notif-error'
});

duration: 0 только для отладки.

  1. напишите это в свой style.css
.notif-error {
    background-color: red;
}
.mat-snack-bar-container.notif-error {
    max-width: 100%;
}

Теперь из-за специфики css это будет наиболее конкретное правило.

  • Помните, что между.mat-snake-bar-container и.notif-error не должно быть пробелов.
  • Это правило будет применяться к элементам, имеющим классы.mat-snake-bar-container и.notif-error.
  • Это также работает, когда ваш класс.notif-error пуст.

Путь к работе.


encapsulation: ViewEncapsulation.None

Вот стек, чтобы продемонстрировать

Другие вопросы по тегам