Skip to content

Commit

Permalink
feat(compiler): add support ::ng-deep
Browse files Browse the repository at this point in the history
- /deep/ is deprecated and being removed from Chrome
- >>> is semantically invalid in a stylesheet
- sass will no longer support either in any version of sass

-> use ::ng-deep in emulated shadow DOM mode

Because the deep combinator is deprecated in the CSS spec,
`/deep/`, `>>>` and `::ng-deep` are also deprecated in emulated shadow DOM mode
and will be removed in the future.

see https://www.chromestatus.com/features/6750456638341120
  • Loading branch information
vicb authored and matsko committed Jun 23, 2017
1 parent 81734cf commit b754e60
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
20 changes: 14 additions & 6 deletions aio/content/guide/component-styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,13 @@ if some ancestor element has the CSS class `theme-light`.



### /deep/
### (deprecated) `/deep/`, `>>>`, and `::ng-deep`

Component styles normally apply only to the HTML in the component's own template.

Use the `/deep/` selector to force a style down through the child component tree into all the child component views.
The `/deep/` selector works to any depth of nested components, and it applies to both the view
Use the `/deep/` shadow-piercing descendant combinator to force a style down through the child
component tree into all the child component views.
The `/deep/` combinator works to any depth of nested components, and it applies to both the view
children and content children of the component.

The following example targets all `<h3>` elements, from the host element down
Expand All @@ -134,17 +135,24 @@ through this component to all of its child elements in the DOM.

</code-example>

The `/deep/` selector also has the alias `>>>`. You can use either interchangeably.

The `/deep/` combinator also has the aliases `>>>`, and `::ng-deep`.

<div class="alert is-important">

Use the `/deep/` and `>>>` selectors only with *emulated* view encapsulation.
Use `/deep/`, `>>>` and `::ng-deep` only with *emulated* view encapsulation.
Emulated is the default and most commonly used view encapsulation. For more information, see the
[Controlling view encapsulation](guide/component-styles#view-encapsulation) section.

</div>

<div class="alert is-important">

The shadow-piercing descendant combinator is deprecated and [support is being removed from major browsers](https://www.chromestatus.com/features/6750456638341120) and tools.
As such we plan to drop support in Angular (for all 3 of `/deep/`, `>>>` and `::ng-deep`).
Until then `::ng-deep` should be preferred for a broader compatibility with the tools.

</div>

{@a loading-styles}

## Loading component styles
Expand Down
6 changes: 5 additions & 1 deletion packages/compiler/src/shadow_css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,11 @@ const _shadowDOMSelectorsRe = [
/\/shadow-deep\//g,
/\/shadow\//g,
];
const _shadowDeepSelectors = /(?:>>>)|(?:\/deep\/)/g;

// The deep combinator is deprecated in the CSS spec
// Support for `>>>`, `deep`, `::ng-deep` is then also deprecated and will be removed in the future.
// see https://github.com/angular/angular/pull/17677
const _shadowDeepSelectors = /(?:>>>)|(?:\/deep\/)|(?:::ng-deep)/g;
const _selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$';
const _polyfillHostRe = /-shadowcsshost/gim;
const _colonHostRe = /:host/gim;
Expand Down
13 changes: 13 additions & 0 deletions packages/compiler/test/shadow_css_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,19 @@ export function main() {
expect(css).toEqual('x[a] y {}');
});

it('should handle ::ng-deep', () => {
let css = '::ng-deep y {}';
expect(s(css, 'a')).toEqual('y {}');
css = 'x ::ng-deep y {}';
expect(s(css, 'a')).toEqual('x[a] y {}');
css = ':host > ::ng-deep .x {}';
expect(s(css, 'a', 'h')).toEqual('[h] > .x {}');
css = ':host ::ng-deep > .x {}';
expect(s(css, 'a', 'h')).toEqual('[h] > .x {}');
css = ':host > ::ng-deep > .x {}';
expect(s(css, 'a', 'h')).toEqual('[h] > > .x {}');
});

it('should pass through @import directives', () => {
const styleStr = '@import url("https://fonts.googleapis.com/css?family=Roboto");';
const css = s(styleStr, 'a');
Expand Down

2 comments on commit b754e60

@brianmtreese
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Victor, just curious if you guys have anything in the works on how this sort of thing will be handled down the road when Angular support is officially dropped. We're just trying to plan ahead and we have some things that rely on both view encapsulation and shadow piercing that may be difficult for us to change.

@simeyla
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brianmtreese I guess not? This is very frustrating. Using Angular Material effectively is almost impossible without needing to tweak a few things here and there - due to bugs or customization. Anybody know what we're expected to do in future?

Please sign in to comment.