I know how to use ::ng-deep
to apply styles to specific component's internal parts, but I'm looking for a more correct solution that does not require the parent to know about the components parts, and specifically to set dimensions of the component (width and hight).
Here's the full scenario:
@Component({
selector: 'app-root',
template: '<h1>Hello World!<h1><app-green-box></app-green-box>',
styles: [ 'app-green-box { width: 50%; }' ],
})
export class AppComponent {
}
@Component({
selector: 'app-green-box',
template: '<div class="green-box">Bye</div>',
styles: [ '.green-box { border: solid black 1px; background: green; }' ],
})
export class GreenBoxComponent {
}
As you can see, AppComponent
would like a green box that is 50% wide. GreenBoxComponent
does not have a way to know that (another parent might want it at 70% or at 10%).
Unfortunately, the above code doesn't work (I'm not exactly sure why - the custom element doesn't actually take up space as it has no visual presentation by itself, and so it can't be a bounding box for the content?).
Using ::ng-deep
requires the parent component to know that GreenBoxComponent
uses a <div>
for its internal box implementation, but is there a way to have the component just "copy" the styles from the host to whatever internal part it needs to apply these to?
Actually, after trying to explain to myself the reason that the custom element isn't a bounding box (in the question), I figured out the problem: the default display
for the custome element is inline
so it doesn't obey the size restrictions of the parent.
The solution is for GreenBoxComponent
to understand that it represents a box and not an inline element and that parents would like to treat it as a box - so it should force its host element to have display: block
, like so:
@Component({
selector: 'app-green-box',
template: '<div class="green-box">Bye</div>',
styles: [
':host { display: block; }',
'.green-box { border: solid black 1px; background: green; }',
],
})
export class GreenBoxComponent {
}