Как и где использовать :: 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 следует предпочесть для более широкой совместимости с инструментами.
Вы можете найти его здесь