Angular 2 替 Component 加上 CSS 的所有招數
- 2017-01-01
- Liu, An-Chi 劉安齊
題外話
看到一段我很認同的話:
應該由「新手」來教「超級新手」,為什麼?因為那些新手可能一個禮拜前跟你一樣卡在迴圈,不知道迴圈到底可以做什麼,但是這禮拜他就領悟了。我覺得這時候是最適合教學的時機,因為他們還記得「當初卡住的那種心情」,他們是最懂你心情的人。
By 一個資淺工程師年末的自我省視
剛進公司時,我也是完全沒接觸過 Angular 2,那種徬徨不安的日子依稀猶存,一段日子過去透過不斷查文獻和實作,也終於算是有點懂了,我一直認為程式最困難的地方就是剛入門的門檻,之後儘管也不會就都很簡單,但至少可以暢行無阻。
前言
Angular 2 是一個由組件構成的架構,意思就是所有 UI 都是建立在組件裡面。因此由組件建立風格 (style) 會讓我們使用 Angular 更快樂。我們接著就要談談不同的建立風格技巧,但首先我們要知道 Shadow DOM 和 View Encapsulation。
解釋
Shadow DOM 是 W3C 定義的網頁組件標準之一。它可以讓一群 DOM 實體被藏在單一元素 ( element ) 上 ( 也就是組件的概念 ),而且可以將元素封裝 ( encapsulate ) 風格。意味著被封裝的風格只會被這一群 DOM 使用而已。
但是 Shadow DOM 並不是所有瀏覽器都支援,決定要不要使用以及如何使用 Shadow DOM 的方法就稱為 View Encapsulation,分別有三種狀態:
- None:無 Shadow DOM 存在。
- 仿真 (Emulated):試圖模仿出 Shadow DOM,雖然不是真的,至少讓瀏覽器能使用我們的程式碼。
- 自然 (Native):瀏覽器能完全使用 Shadow DOM。
詳細解釋這三種差在哪裡,可以參考這一篇
設置 encapsulation
大概就長這樣,他會在 @Component
裡面
@Component({
templateUrl: 'card.html',
styles: [`
.card {
height: 70px;
width: 100px;
}
`],
encapsulation: ViewEncapsulation.Native
// encapsulation: ViewEncapsulation.None
// encapsulation: ViewEncapsulation.Emulated is default
})
正題開始
接著就來看看有那些技巧可以幫組件加上 CSS
寫在 Component 裡面
這是最常見的方法,也是最推薦的,常常會看到文件都是這樣用。
在我們的 @Component
中實體化:
@Component({
templateUrl: 'card.html',
styles: [`
.card {
height: 70px;
width: 100px;
}
`],
})
如果使用 view encapsulation 技術的預期結果:
- None: style 直接被包裝到
<head>
的<style>
裡面 - Emulated: style 被包裝到
<head>
的<style>
裡面,但可以辨識要對應的 Component - Native: 如同預期一般為網頁組件。
.CSS
@Component
的 styleUrls
可以引入對應的 CSS 檔
@Component({
styleUrls: ['css/style.css'],
templateUrl: 'card.html',
})
如果使用 view encapsulation 技術的預期結果:
- None: style 直接被包裝到
<head>
的<style>
裡面。他會被產生於執行完「寫在 Component 裡面」的方式之後。 - Emulated: style 被包裝到
<head>
的<style>
裡面,但可以辨識要對應的 Component。反而不是引入link
喔! - Native: 如同預期一般為網頁組件。
模板
也可以寫在模板裡面,可以是放在 <style>
標籤或是放在 HTML tag 裡面
//方法一
template: `
<style>
h1 {
color: purple;
}
</style>
<h1>Styling Angular Components</h1>
`
})
//方法二
@Component({
template: '<h1 style="color:pink">Styling Angular Components</h1>'
})
如果使用 view encapsulation 技術的預期結果:
- None:
- 方法一:style 直接被包裝到
<head>
的<style>
裡面。他會被產生於執行完「寫在 Component 裡面」的方式之後。 - 方法二:直接寫在 tag 裡面了。
- 方法一:style 直接被包裝到
- Emulated:
- 方法一: style 被包裝到
<head>
的<style>
裡面,但可以辨識要對應的 Component。 - 方法二:一樣是直接寫在 tag 裡面了。
- 方法一: style 被包裝到
- Native: 如同預期一般為網頁組件。
優先順序
有了這三種加入 CSS 的方法,那麼一次都用上去會怎樣呢?
@Component({
selector: 'my-app',
//Component style
styles: [`
h1 {
color: red;
}
`],
//External style
styleUrls['style.css'],
// Template inline style
template: `
<style>
h1 {
color: purple;
}
</style>
<h1 style="color:green">Styling Angular Components</h1>
`
})
分別是:
- Component style: 字變紅
- External style: 字變藍
- Template inline style: 字變紫
點開 Plunker看看答案吧! XD