Best way to pass styling to a component
I would just use a styles
input property on InputEdit, and pass in an object with the desired styles:
<InputEdit [styles]="stylesObj"> // in host component's template
stylesObj = {font-size: '1.1em', color: 'red'}; // in host component class
<input [ngStyle]="stylesObj" ...> // in InputEdit component's template
If you have multiple DOM elements you want to style, pass in a more complex object:
<InputEdit [styles]="stylesObj">
stylesObj = {
input: {font-size: '1.1em', color: 'red'}
label: { ... }
};
<label [ngStyle]="styles.label" ...>
<input [ngStyle]="styles.input" ...>
Mark Rajcok's answer is good for a group of styles, but if you're only going to allow the font-size and color to be changed, you may want to use a more direct approach like you started with (in this example, also enforcing only pixels instead of a more flexible string for demonstration purposes):
For Individual Style Properties:
Component:<InputEdit [color]="'red'" [fontSize]="16">
component.ts:Input() color: string = 'black';
Input() fontSize: number = 18;
component.template:<input type="text" [style.color]="color" [style.fontSize.px]="fontSize">
If Allowing a Group of Styles:
Component:<InputEdit [styles]="{backgroundColor: 'blue', 'font-size': '16px'}">
NOTE:
Make sure the CSS properties are camelCased or in a string if there is more than one word.
component.ts:@Input() styles: any = {};
component.template:<input type="text" [ngStyle]="styles">
update
::slotted
is now supported by all new browsers and can be used with `ViewEncapsulation.ShadowDom
https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted
original
/deep/
, ::shadow
and >>>
are deprecated.
::ng-deep
is the best option until all browsers properly support style encapsulation and ViewEncapsulation.Emulated
can be removed.
The deprecation is only for the native implementation in Chrome (other browsers never implemented it) but Angular has its own emulation of these CSS combinators in ViewEncapsulation.Emulated
(default)
/deep/
, ::shadow
and >>>
::ng-deep
can therefore be used just fine in Angular2.
For more than simple classes or style property settings use ngStyle
Angular 2.0 and ng-style
If you want to leave it up to the component to define the actual css you can try one of the following:
Add a property on your component for each 'logical' style setting, for instance headerSize
.
@Input('headerSize') headerSize: ('small' | 'large');
Then your component can check its value in one of a few ways to style itself:
Modify the HTML itself by showing or hiding child elements
<h1 *ngIf="headerSize == 'large'">{{ title }}</h1> <h2 *ngIf="headerSize == 'small'">{{ title }}</h2>
Set a custom class dynamically inside the component somewhere, and style it:
<div [ngClass]="'header-' + headerSize"> .header-small { h1 { font-size: 20px; } } .header-large { h1 { font-size: 30px; } }
Set a custom class dynamically at the class level. This is the same as #2 and doesn't require a wrapper element. However it's less than trivial to actually enable and disable these classes.
@HostBinding('class.header-small') _header_small; @HostBinding('class.header-large') _header_large;
Also note that if you're using ng-content
that the styles applied are the styles defined in the containing component and not the component that actually does the content replacement.