Using Shadow Parts to Style Protected Shadow DOM Components

5 min read

Originally published January 12, 2021

Check out my advanced Ionic tutorials at eliteionic.com

I have a few articles and videos that help explain the purpose of Ionic's usage of Shadow DOM for some of their components, and how we can work with this approach to style components the way we want. If the concept of a Shadow DOM or using CSS Variables/Custom Properties to style Ionic component's is new to you, you might want to do a bit of additional reading before tackling this article:

Both of these tutorials were created before Ionic supported using Shadow Parts. With the added support for Shadow Parts, this will allow us to more easily pierce the veil of a Shadow DOM to inject our own custom styles, without having to resort to hacky methods like injecting CSS into components which mostly defeats the purpose of using Shadow DOM in the first place.

To help explain the role of Shadow Parts, I am publishing a free snippet from my Creating Ionic Applications with Angular book below. This is just one small part of the approximately 853 page book that contains a wealth of information about understanding and using Angular to build Ionic applications.


Shadow Parts are a newer way to help style elements that are within a Shadow DOM. Because this is a newer API, you might first want to check that Shadow Parts are supported by the browsers you intend to target: browser support (both Chrome for Android and iOS Safari support the API).

To reiterate, the basic idea of using a Shadow DOM in the context of styling is to ensure that the component won't be effected by styles outside of the component. It might be important that a particular component has a padding of 5px on a particular element, and we wouldn't want a global style that sets the padding to 20px to interfere with that.

Shadow Parts are basically a way for the designer of the component to mark particular elements within that component as being safe to target with CSS rules, and to expose them to styles coming from outside of the Shadow DOM.

Let's take the <ion-content> component as an example. If we look at the internal structure of the <ion-content> component (you can do this just by opening it's Shadow Root in the Chrome DevTools Element inspector) we would see something like this:

<ion-content>
  <!-- shadow-root -->
    <div id="background-content" part="background"></div>
    <main class="inner-scroll scroll-y overscroll" part="scroll">
    <div class="transition-effect"></div>
    <slot name="fixed"></slot>
  <!-- shadow-root -->
</ion-content>

All of these elements, except the <ion-content> itself, are within the Shadow DOM. That means we can't target them with standard CSS properties. If we were to try to set the background colour of background-content like this:

ion-content #background-content {
  background-color: #000;
}

...it wouldn't work. However, notice that a couple of these elements have a part attribute supplied? This is because they are using the Shadow Parts API. Anything that is exposed as a "part" can actually be styled directly, we just have to target it with a special selector syntax:

ion-content::part(background) {
  background-color: #000;
}

All we need to do is target the component itself, and then supply the part name to ::part(). Then we can just style using normal CSS properties. Just like with the CSS Variables, a list of available parts is also supplied in the documentation for each component.