[ionic-v4] shadow-dom


#1

I migrate my app from v3 to v4 and I have many problems with CSS and shadow-dom.

How can I change the CSS for a child-element in shadow-root.

Example
I want to change css for class .button-inner in ion-button
here is my code for ionic v3
.long-text-button .button-inner {
font-size: 12px;
padding: 0px;
margin: 0px;
text-align: center;
white-space: normal;
}

I can’t use it in v4 because it wrap in shadow-root


Ionic 4 overwrite disabled input opacity
#2

I wrote an article about that here: https://www.joshmorony.com/shadow-dom-usage-in-ionic-web-components/

In short, the only way you can style elements inside of a Shadow DOM is if they are styled using CSS4 variables that you can override.


#3

Thank for your reply and your blog is very helpful.
I found my solution to this problem

I create a directive and write my custom CSS to shadowRoot.

import { Directive, ElementRef, Input, OnChanges } from '@angular/core';
@Directive({
  selector: '[appShadowCss]'
})
export class ShadowCssDirective implements OnChanges {
  @Input() shadowCustomCss: string;

  ngOnChanges(): void {
    const shadow = this.el.nativeElement.shadowRoot || this.el.nativeElement.attachShadow({ mode: 'open' });
    if (shadow) {
      let innerHTML = '';
      innerHTML += '<style>';
      innerHTML += this.shadowCustomCss;
      innerHTML += '</style>';
      shadow.innerHTML += innerHTML;
    }
  }
  constructor(private el: ElementRef) {

  }

}


<ion-button expand="block" fill="outline"  appShadowCss shadowCustomCss='.button-inner{white-space:normal;}'>
             Edit your phone number.
</ion-button>

I know It is a very bad idea to do this in every button.
Do you know how to disable shadow root in ionic?


Change style of ionic v4 components
#4

Well, this is a bit annoying. That is not the only way to style it. You can inject your own styles by traversing the tree using shadowRoot property but it’s ugly and requires a code change to just change a border or something simple like the width of a tab. I don’t think shadow DOM will stop people from injecting their own CSS, it’s just made it more difficult


#5

I agree that it won’t stop people, but I can see the benefits in terms of long term support for the components. Seems to me to pretty much be a trade off of flexibility for stability. I think a lot of people will inject their own CSS which would defeat the overall purpose/goal from Ionic’s view, but I think most people will probably end up conforming to the CSS variable approach - especially as they become better documented and more variables are added.


#6

I have a huge problem with a segment button that has a button inside a shadow root. I need the default value (6px) for this, but it is a first element and assumes the value applied as shown below. Can someone help me?


#7

I think in theory you should then have all CSS properties as a variable because each has its own application and use cases. For me it is really a problem if the variable is not there then.

For me there should be an option like ::ng-deep, /deep/ to overwrite such things anyway, but unfortunately there is not. Only via javascript which is really rubbish.


#8

@danielmm1997 I agree with you. In theory not using /deep/ should be good, but in practice I don’t think that’s good.

From a commentary I saw (that I agree):

Custom properties — These are not suited or intended for wholesale styling of shadow descendants, as CSS WG members have said. They are far too unwieldy when exposing lots of properties, and they put an onus on the component author to anticipate all possible use-cases in advance. If the component you’re using doesn’t expose a custom property to do what you want, you’re out of luck.

Source: https://medium.com/@jonrimmer/8c8043c015dc (it’s about angular css, but based on shadow dom / native encapsulation)

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/ .

I don’t consider shadow dom production ready while there isn’t a way to access inner components in shadow dom through css (unless I’m not using 3rd party components, which is not the case when using ionic components), because of the reasons above.

The intent of the ionic team for using it should be good, but I don’t think that the result is good, at least for now, and without a way to disable it (to use the ionic components without shadow dom).