Shadow DOM - Why?

I migrated my app from Ionic 3 to 4 and for the most part I see slightly better performance and it seems like it’s pretty stable. The only real issue I have is why did Ionic switch to use shadow DOM? I know it’s being used in other libraries but still it seems like this added a huge restriction on customization. I’ve been struggling to customize any Ionic component and it seems like there is very little gained by this

Issues I’ve been struggling with

  1. Expand ion-select and ion-select-option to display all text and not have an ellipses at the end

  2. I have a list of ion-item-sliding items that for some of them I want to hide the sliding arrow. Is this feasible? I put disabled=true but it still displays the icon, which is a little misleading

  3. is there a way to change the color of the arrow icon? Right now it’s a grayish color and I would rather change it to black so that users don’t think it’s disabled

1 Like

If there is a property that you think needs to exposed for customization, file an issue at: https://github.com/ionic-team/ionic/issues/17166

As for the ion-item-sliding, you are going to have to do some magic with *ngIf on the options container to make that work (I think)

Which arrow are referring to? On the ion-item, the color of the arrow is defined by --detail-icon-color

On the point of why/what is the benefit of Shadow DOM, I think the key benefit is that it protects the “integrity” of the component. With Shadow DOM, the component can be isolated from outside interference and only modified in expected ways through CSS variables (in effect, this is basically like an interface/API provided by the creator of the component for customising the component).

This means that if Ionic decide to update one of their components, they can do so without its behaviour breaking for people who may have modified the component with CSS styles in any number of ways. With a consistent “API” for implementing style changes, the components become much more stable and maintainable in the long term.

In short, it trades flexibility for stability/maintainability.

1 Like

Thanks for the reply, it helped point me in the right direction

For the first item I added this to global.scss.

.alert-tappable.sc-ion-alert-ios, .alert-tappable.sc-ion-alert-md{
    display: contents;
  }
  
  .alert-wrapper.sc-ion-alert-ios, .alert-wrapper.sc-ion-alert-md{
    max-width: 75vw;
  }
  .sc-ion-alert-ios .alert-radio-label, .alert-checkbox-label.sc-ion-alert-ios, .alert-checkbox-label.sc-ion-alert-md,.sc-ion-alert-md .alert-radio-label{ 
      white-space: pre-line !important;  
  }

For item 2 all I had to do was add/remove the “detail” attribute based on a flag, from ion-item. Not sure why this worked…

Item 3 added this to the component.scss:

ion-item {
    --detail-icon-opacity: 1.2;
}

Thanks for replying and also thanks for your blogs, they are really detailed and helpful.

I understand what’s gained by shadow DOM, not sure if it’s worth the headache. Especially since it seems like there are a lot of suggestions to put style changes into global.scss, doesn’t that defeat the purpose?

Shadow DOM doesn’t impact where you can put your CSS (unless you are talking about injecting CSS into the Shadow DOM which is technically possible but not recommended). If you want to affect the entire application you can put styles in global.scss, but Shadow DOM doesn’t affect the ability to implement component level styles.

Not all of Ionic use Shadow DOM, so it is still possible to modify some components, and even for the components that are protected by Shadow DOM you can still use CSS styles on the component itself and any projected content (just not on the internal structure of the component itself).

Shadow DOM is a new DOM feature that helps you build components. You can think of shadow DOM as a scoped subtree inside your element. Read more on Web Fundamentals. This document gives an overview of shadow DOM as it relates to Polymer walgreenslistens.com