Reputation: 3182
I'm working on a component that renders other components into an iframe
. It renders successfully however I noticed the styles aren't being passed into it. I tried using the styles
array in the @Component
instead of linking to an external stylesheet which failed. I also added them to the template inside of a <style>
tag which also failed. I see how we can access the contentDocument
and or contentWindow
to pass data into the DOM of the iframe
which I planned on using a service
to do instead of having to dig around at things I can't even touch once they're inside the iframe
. Is there a way to pass the styles into it without having to make a data object then a couple functions inside the nested component to create and apply them? So far this is what my code looks like.
Component
import { PropertyDisplayComponent } from './components/property-display/property-display.component';
@Component({
selector: 'responsive-shell',
templateUrl: './responsive-shell.component.html',
styleUrls: ['./responsive-shell.component.css']
})
export class ResponsiveShellComponent implements OnInit, AfterViewInit {
@ViewChild('compFrame', {static: false}) CompFrame: ElementRef | undefined;
doc: any;
compRef: ComponentRef<PropertyDisplayComponent> | undefined;
constructor(private VcRef: ViewContainerRef, private resolver: ComponentFactoryResolver) { }
public onLoad(){
this.doc = this.CompFrame?.nativeElement.contentDocument || this.CompFrame?.nativeElement.CompFrame.contentWindow;
this.createComponent();
}
private createComponent():void{
const compFactory = this.resolver.resolveComponentFactory(PropertyDisplayComponent);
this.compRef = this.VcRef.createComponent(compFactory);
this.compRef.location.nativeElement.id = 'propertyDisplay';
this.doc.body.appendChild(this.compRef.location.nativeElement);
}
ngOnInit(): void {
}
ngAfterViewInit():void{
this.onLoad();
}
}
Template
<section class="shell">
<iframe class="iframeShell" #compFrame></iframe>
</section>
Is there something I should be doing differently or does anyone see where I can add in the stylesheet?
UPDATE I discovered the styling works if we do it inline, but would prefer a different solution if we can just pass the stylesheet some type of way.
Upvotes: 1
Views: 2395
Reputation: 1516
Try changing the component decoration from this...
@Component({
selector: 'responsive-shell',
templateUrl: './responsive-shell.component.html',
styleUrls: ['./responsive-shell.component.css']
})
to this...
@Component({
selector: 'responsive-shell',
templateUrl: './responsive-shell.component.html',
styleUrls: ['./responsive-shell.component.css'],
encapsulation: ViewEncapsulation.ShadowDom
})
More on the topic of ViewEncapsulation.
Note: this only works for modern browsers because it relies on the browser's support for the Shadow DOM API. I've experienced wonky behavior if you are loading several SCSS files from your component's SCSS but local styles work well.
Upvotes: 2