slides.com/gerardsans | @gerardsans
800
750
// index.html
<my-app ng-version="4.0.0-rc.4">
<div>
<h2>Hello Angular 4! 👋</h2>
</div>
</my-app>
X . Y . Z
  MAJOR    MINOR     PATCH Â
<div>
<person name="John"></person>
<employee name="Tom" id="45231"></employee>
</div>
@Component({
selector: 'person',
template: `<h4>Person: {{name}}</h4>`
})
export class Person {
@Input() name: string;
}
@Component({
selector: 'employee',
template: `<h4>Employee: {{name}}, id: {{id}}</h4>`
})
export class Employee extends Person {
@Input() id: string;
}
source: blog
<html>
<head>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Hello World!</h1>
<p>This is my first CSS example</p>
</body>
</html>
//style.css
h1 {
color: blue;
background-color: yellow;
border: 1px solid black;
}
p {
color: red;
}
Element style
Element id
class/attribute selectors
element selectors
last CSS rule wins
source: blog
@Component({
selector: 'song-track', // <song-track></song-track>
template: `
<div class="container">
<track-image image="http://..."></track-image>
<div class="track-information">
<track-title>{{track}}</track-title>
<track-artist>{{artist}}</track-artist>
</div>
</div>`
})
export class SongTrack { }
@Component({
selector: 'song-track',
encapsulation: ViewEncapsulation.Emulated
})
<head>
<style>
.container[_ngcontent-ikt-1] { ... }
</style>
</head>
<body>
<my-app>
<song-track _nghost-ikt-1>
<div _ngcontent-ikt-1 class="container"></div>
</song-track>
</my-app>
</body>
@Component({
selector: 'song-track',
encapsulation: ViewEncapsulation.Native
})
<body>
<my-app>
<song-track>
â–¾ #shadow-root (open)
<style>.container { ... }</style>
<div class="container"></div>
</song-track>
</my-app>
</body>
@Component({
selector: 'song-track',
encapsulation: ViewEncapsulation.None
})
<head>
<style>.container { ... }</style>
</head>
<body>
<my-app>
<song-track>
<div class="container"></div>
</song-track>
</my-app>
</body>
safari
safari
@Component({
selector: 'song-track',
encapsulation: ViewEncapsulation.Native,
template: `
<div class="container">
<track-image image="image"></track-image>
<div class="track-information">
<track-title>{{track}}</track-title>
<track-artist>{{artist}}</track-artist>
</div>
</div>`
})
export class SongTrack { }
@Component({
selector: 'song-track',
encapsulation: ViewEncapsulation.Native,
template: `
<div class="container">
<ng-content select="track-image"></ng-content>
<div class="track-information">
<ng-content select="track-title"></ng-content>
<ng-content select="track-artist"></ng-content>
</div>
</div>`
})
export class SongTrack { }
<!-- Component (Shadow DOM) -->
<song-track
track="No Lie"
artist="Sean Paul, Dua Lipa">
</song-track>
<!-- Component (Light DOM) -->
<song-track2>
<track-image image="..."></track-image>
<track-title>No Lie</track-title>
<track-artist>Sean Paul, Dua Lipa</track-artist>
</song-track2>
@Component({
styles: [`
:host { color: black; }
:host(.selected) { color: red; }
`]
})
export class SongTrack { }
<song-track></song-track>
<song-track class="selected"></song-track>
:host-context(.theme) { color: red; }
:host-context(#player1) { color: red; }
<div class="theme">
<song-track></song-track>
</div>
<div id="player1">
<song-track></song-track>
</div>
@Component({
styles: [`
:host /deep/ .h3 { color: red; }
:host >>> .h4 { color: purple; }
`],
template: `
<div class="container">
<track-image image="http://..."></track-image>
<div class="track-information">
<track-title>{{track}}</track-title> //<h3><ng-content></h3>
<track-artist>{{artist}}</track-artist> //<h4><ng-content></h4>
</div>
</div>`
})
export class SongTrack { }
@Component({
selector: 'song-track',
styles: [`.container { color: white; }`]
})
export class SongTrack { }
@Component({
template: `
<style>
.container { color: deepskyblue; }
</style>
<div class="container">...</div>
`
})
export class SongTrack { }
//song-track.component.ts
@Component({
styleUrls: ['src/shared.css'],
})
export class SongTrack { }
//shared.css
.container { ... }
<song-track ngClass="selected" class="disabled"></song-track>
<song-track [ngClass]="'selected'"></song-track>
<song-track [ngClass]="['selected']"></song-track>
<song-track [ngClass]="{'selected': true}"></song-track>
<song-track class="selected disabled"></song-track>
<song-track class="selected"></song-track>
<song-track ngClass="selected disabled">
<song-track [ngClass]="'selected disabled'">
<song-track [ngClass]="['selected', 'disabled']">
<song-track [ngClass]="{'selected': true, 'disabled': true}">
<song-track [ngClass]="{'selected disabled': true}">
<song-track class="selected disabled"></song-track>
<song-track [ngStyle]="{'color': 'white'}" style="font-size: 12px;">
<song-track [ngStyle]="{'font-size.px': '12'}">
<song-track [ngStyle]="{'font-size': '12px'}">
<song-track style="color: white; font-size: 12px;">
<song-track style="font-size: 12px;">
<song-track [ngStyle]="{'color': 'white', 'font-size': '12px'}">
<song-track style="color: white; font-size: 12px;">
@Component({
host: {
'value': 'default', //'DOM-prop': 'value'
'[value]': "'default'", //'[DOM-prop]': 'expr'
'class': 'selected', //'DOM-attr': 'value'
'[class]': "'selected'", //'[DOM-attr]': 'expr'
'(change)': 'onChange($event)', // (event) : ...
'(window:resize)': 'onResize($event)', // (target:event) : ...
}
})
@Component({
host: {
//setting multiple values
'class': 'selected disabled',
'style': 'color: purple; margin: 5px;',
//setting single values (using binding)
'[class.selected]': 'true',
'[class.selected]': '!!selected', //add class if selected = true
'[style.color]': '"purple"' //expression must be a string
}
})
export class SongTrack { }
@Component({
})
export class SongTrack {
//<host class="selected"></host>
@HostBinding('class.selected') selected = true;
//<host style="color: red;"></host>
@HostBinding('style.color') color = 'red';
}
import { ElementRef } from '@angular/core';
@Component(...)
export class SongTrack {
constructor(private element: ElementRef){
let elem = this.element.nativeElement;
elem.style.color = "blue";
elem.style.cssText = "color: blue; ..."; // multiple styles
elem.setAttribute("style", "color: blue;");
}
}
import { ElementRef, Renderer } from '@angular/core';
@Component(...)
export class SongTrack {
constructor(
private element: ElementRef,
private renderer: Renderer
){
let elem = this.element.nativeElement;
renderer.setElementStyle(elem, "color", "blue");
renderer.setElementClass(elem, "selected", true);
}
}
Encapsulation Modes
Inline, Template inline, External Styles
ngClass, ngStyle
Shadow DOM Selectors
Host bindings/listeners
// Angular 2
<div *ngIf="flightInfo">{{flightInfo.name}}</div>
<div *ngIf="!flightInfo">Loading...</div>
// Angular 4
<div *ngIf="flightInfo; else noInfo">{{flight.name}}</div>
<ng-template #noInfo>
<div>Loading...</div>
</ng-template>
// Angular 2
<div *ngIf="flightInfo$ | async">
{{(flightInfo$ | async)?.name}}
</div>
// Angular 4
<div *ngIf="flightInfo$ | async; let flight">
{{flight.name}}
</div>
<div *ngIf="flightInfo$ | async as flight">
{{flight.name}}
</div>