32

The two shadow-piercing combinators have been removed, as stated in https://www.chromestatus.com/features/6750456638341120

So, what's the substitute for achieving the same thing? Or has this shadow-piercing feature been completely abandoned?

mfluehr
  • 2,832
  • 2
  • 23
  • 31
Zhengquan Bai
  • 1,057
  • 3
  • 14
  • 31
  • 1
    For something to replace `::shadow` and `deep` that works now, use a `style` element inside your shadow root, with something like `@import url( '/common-style.css' )`. See http://stackoverflow.com/questions/34699350/shadow-piercing-descendant-combinator-deep-including-shadow-pseudo-el/34706299#34706299 and http://stackoverflow.com/questions/30829019/polymer-share-styles-across-elements/32941101#32941101 The longer-term solution is [CSS Custom Properties (aka “CSS variables”)](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables). – sideshowbarker Mar 02 '16 at 10:40

4 Answers4

20

::shadow and /deep/ were removed for breaking encapsulation.

The substitutes are:

Marcelo Glasberg
  • 29,013
  • 23
  • 109
  • 133
  • 6
    For cases when you cannot access the shadow dom before it is rendered, it's impossible to avoid `::shadow` – RenaissanceProgrammer Aug 23 '17 at 19:45
  • 6
    @MarcG If there's no mechanism to break encapsulation, how can I override framework styling? – adamdport Mar 08 '18 at 19:22
  • 10
    I don't agree with "The problem is that `::shadow` and `/deep/` break encapsulation. I am glad they are gone.". Although they break encapsulation, if you use 3rd party components and they don't have css variables to style the way you want, you are simple without options, except for asking them to create the variables you want (which could never be created), or having to fork the component and to maintain it yourself just because of some trivial css you could have applied if `/deep/` was supported. I would prefer never have to use `/deep/`, but I would want to be able to use it when needed. – Lucas Basquerotto Oct 29 '18 at 12:52
  • @LucasBasquerotto So you actually do agree they break encapsulation, but you think that's OK when you have no other option. Well, when you have no other option and you really need to do something, any option is good. But remember breaking encapsulation is bad for a reason, and your use of the component may break when the 3rd party changes the component's internal representation. Ideally, yes, the 3rd party should allow for you to style everything you need, otherwise their components are lacking. – Marcelo Glasberg Oct 29 '18 at 17:51
  • 9
    @MarcG Yes, they break encapsulation and whenever possible such a thing **should be avoided**. I see your point, and I agree to it partially, but **I don't agree that removing `/deep/` was something good**. In an ideal world, every library would provide every expected css variable so as to make the use of hacks such as `/deep/` unecessary. Unfortunately, they are people with limited resources and time, and it's expected that their components will have css properties that the consumers can't override through css because of the shadow DOM. Such problems would be greatly mitigated with `/deep/`. – Lucas Basquerotto Oct 29 '18 at 18:18
  • 6
    Just had a situation where a third pary autocomplete input was showing it's auto complete suggestions behind my elements. should be a simple fix, just a z-index. But no this was painful to fix. I finally stumbled upon /deep/ which works but i see it's been depreciated. I don't see how you would fix this problem when it is fully removed. I think we still need a feature like this but override need to be explicit instead of implicit. – Ryan B Mar 12 '19 at 02:11
  • 4
    The problem here isn't that encapsulation could be broken - the problem is the hubris of whomever decided nobody should code in manner X. Let good code break no encapsulation, let bad code be, don't try to enforce 'good' on everybody. You cause problems that way and engender hatred and fury. I think there will be a revolt. – smaudet Apr 16 '19 at 13:44
  • How does it make any sense that forced encapsulation on a shadow DOM is a best practice while mode: closed is a worst practice? It doesn't! This is an excellent example of blindly following "best practices" without understanding *why* they are best practices. The shadow DOM *is not a class*. A class is a logic container that's significantly easier to break. A custom component is most often used as a scoped template to increase productivity and follow DRY principles. Forcing me to write "part" on everything and disabling core styling principles actively fights productivity and DRY principles. – dallin Oct 02 '22 at 11:44
2

As of Polymer 2:

  • ::shadow (shadow-piercing selectors) - there is no direct substitute. Instead a custom CSS properties has to be used. Polymer 2: Custom CSS Properties

  • /deep/ - there is some sort of replacement by defining :host > * { ... } (applies a ruleset to all of the top-level children in the host's shadow tree, which doesn't conflict with the rule in the main document).

For more detailed information check Polymer 2 Upgrade Notes

magiccrafter
  • 5,175
  • 1
  • 56
  • 50
2

At the time of writing you can try ::part and ::theme with Chrome 73 and above:

https://www.chromestatus.com/feature/5763933658939392

<submit-form>
  #shadow-root
  <x-form exportparts="some-input, some-box">
    #shadow-root
    <x-bar exportparts="some-input, some-box">
      #shadow-root
      <x-foo part="some-input, some-box"></x-foo>
    </x-bar>
  </x-form>
</submit-form>

<x-form></x-form>
<x-bar></x-bar>

You can style all the inputs with:

:root::part(some-input) { ... }

There is the full documentation how it works:

https://github.com/fergald/docs/blob/master/explainers/css-shadow-parts-1.md

This somehow can solve your problem, but I still miss the days how I styled embedded tweets with ::shadow.

sparanoid
  • 1,438
  • 1
  • 12
  • 10
0

"::v-deep" is working for me. For example:

    .menu {
        // stuff
    }
    /deep/.sub-menu {     // override submenu
        .sub-menu__mini {
                //stuff
            }
            a, a:hover {
                //stuff
            }
        }
    }

becomes:

    .menu {
        // stuff
    }
    ::v-deep .sub-menu {     // override submenu
        .sub-menu__mini {
                //stuff
            }
            a, a:hover {
                //stuff
            }
        }
    }
KirstieBallance
  • 1,238
  • 12
  • 26