Как и где использовать :: ng-deep?

Я новичок в Angular 4, поэтому кто-нибудь может объяснить, как и где использовать ::ng-deep в Angular 4?

На самом деле я хочу перезаписать некоторые свойства CSS дочерних компонентов из родительских компонентов. Кроме того, это поддерживается на IE11?

Ответ 1

Обычно /deep/"shadow-piercing" комбинатор может использоваться для приведения стиля к child components. У этого селектора был псевдоним >>> и теперь есть еще один, который называется :: ng-deep.

поскольку /deep/combinator устарел, рекомендуется использовать ::ng-deep

Например:

<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>

и css

.overview {
    ::ng-deep {
        p {
            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}

он будет применяться к дочерним компонентам

Ответ 2

ПРИМЕНЕНИЕ

::ng-deep, >>> и /deep/ отключают инкапсуляцию представления для определенных правил CSS, другими словами, это дает вам доступ к элементам DOM, которых нет в HTML вашего компонента. Например, если вы используете Angular Material (или любую другую стороннюю библиотеку, подобную этой), некоторые сгенерированные элементы находятся за пределами области компонентов (например, dialog), и вы не можете получить доступ к этим элементам. напрямую или используя обычный способ CSS. Если вы хотите изменить стили этих элементов, вы можете использовать одну из этих трех вещей, например:

::ng-deep .mat-dialog {
  /* styles here */
}

На данный момент команда Angular рекомендует выполнять "глубокие" манипуляции только с ЭМУЛИРОВАННОЙ инкапсуляцией вида.

Deprecation

"глубокие" манипуляции на самом деле также устарели, НО пока еще работает, потому что Angular поддерживает предварительную обработку (не спешите отказываться от ::ng-deep сегодня, посмотрите на практике амортизации первой).

В любом случае, прежде чем следовать этому пути, я рекомендую вам взглянуть на отключение подхода инкапсуляции представлений (который тоже не идеален, он позволяет вашим стилям проникать в другие компоненты), но в некоторых случаях это лучший способ. Если вы решили отключить инкапсуляцию вида, настоятельно рекомендуется использовать определенные классы, чтобы избежать пересечения правил CSS и, наконец, избежать путаницы в ваших таблицах стилей. Это действительно легко отключить прямо в файле компонента .ts:

@Component({
  selector: '',
  template: '',
  styles: [''],
  encapsulation: ViewEncapsulation.None  // Use to disable CSS Encapsulation for this component
})

Вы можете найти больше информации об инкапсуляции вида в этой статье.

Ответ 3

Убедитесь, что вы не пропустили объяснение :host-context который находится прямо над ::ng-deep в угловой инструкции: https://angular.io/guide/component-styles. Отказ от ответственности: я пропустил это до сих пор и жаль, что я видел это раньше.

::ng-deep часто необходим, когда вы не написали компонент и не имеете доступа к его источнику, но :host-context может быть очень полезной опцией, когда вы это делаете.

Например, у меня есть черный заголовок <h1> внутри компонента, который я разработал, и я хочу иметь возможность изменить его на белый, когда он отображается на темном тематическом фоне.

Если у меня не было доступа к источнику, мне, возможно, придется сделать это в css для родителя:

.theme-dark widget-box ::ng-deep h1 { color: white; }

Но вместо этого с помощью :host-context вы можете сделать это внутри компонента.

 h1 
 {
     color: black;       // default color

     :host-context(.theme-dark) &
     {
         color: white;   // color for dark-theme
     }

     // OR set an attribute 'outside' with [attr.theme]="'dark'"

     :host-context([theme='dark']) &
     {
         color: white;   // color for dark-theme
     }
 }

Это будет искать где-нибудь в цепочке компонентов для .theme-dark и применять CSS к h1, если найден. Это хорошая альтернатива тому, чтобы слишком полагаться на ::ng-deep что, хотя и часто необходимо, является своего рода анти-паттерном.

В этом случае символ & заменяется на h1 (то, как работает sass/scss), так что вы можете определить свой "нормальный" и тематический/альтернативный css рядом друг с другом, что очень удобно.

Будьте осторожны, чтобы получить правильное количество : Для ::ng-deep их два, а для :host-context только один.

Ответ 4

Я бы подчеркнул важность ограничения ::ng-deep только дочерними элементами компонента, требуя, чтобы родительский класс был инкапсулированным классом css.

Чтобы это работало, важно использовать ::ng-deep после родителя, а не раньше, иначе это будет применяться ко всем классам с одинаковыми именами в момент загрузки компонента.

Компонент CSS:

.my-component ::ng-deep .mat-checkbox-layout {
    background-color: aqua;
}

Компонент шаблона:

<h1 class="my-component">
    <mat-checkbox ....></mat-checkbox>
</h1>

Результирующий css:

.my-component[_ngcontent-c1] .mat-checkbox-layout {
    background-color: aqua;
}

Ответ 5

Просто обновление:

Вы должны использовать ::ng-deep вместо /deep/ который, кажется, устарел.

По документации:

Тени-пронизывающий комбинатор-потомок устарел, и поддержка удаляется из основных браузеров и инструментов. Таким образом, мы планируем отказаться от поддержки в Angular (для всех 3 of/deep/, >>> и :: ng-deep). До тех пор :: ng-deep следует предпочесть для более широкой совместимости с инструментами.

Вы можете найти его здесь