☕
Angularのホスト要素を動的にスタイリングする方法
共通UIコンポーネントで頻出するホスト要素のスタイリング方法を、整理した。
ホスト要素の説明はこちら。
前提条件
以下の環境で動作確認済み。
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 20.0.4
Node: 22.14.0
Package Manager: pnpm 10.10.0
OS: darwin arm64
Angular: 20.0.5
... animations, common, compiler, compiler-cli, core, forms
... platform-browser
Package Version
------------------------------------------------------
@angular-devkit/architect 0.2000.4
@angular-devkit/core 20.0.4
@angular-devkit/schematics 20.0.4
@angular/build 20.0.4
@angular/cdk 20.0.4
@angular/cli 20.0.4
@angular/material 20.0.4
@schematics/angular 20.0.4
rxjs 7.8.2
typescript 5.8.3
zone.js 0.15.1
サンプルコードは読みやすさを優先して、import文を省略している。完全なコードはソースコードを確認してほしい。
boolean型のinputでclass名を制御するケース
状態に応じてクラスを付けたいときは、[class.xxx]
を使う。
main.ts
<app-text text="てすと" [active]="true" />
text.component.ts
@Component({
selector: 'app-text',
template: `{{text()}}`,
host: {
'[class.active]': 'active()',
'[class.disabled]': 'disabled()',
},
styleUrl: `text.component.css`,
})
export class TextComponent {
text = input.required<string>();
active = input.required<boolean>();
disabled = input<boolean>(false);
}
text.component.css
:host.active {
/* active時のスタイル */
}
:host.disabled {
/* disable時のスタイル */
}
string型のinputでstyleを制御するケース
input
で渡された値をそのまま[style.xxx]
にバインドする。
main.ts
<app-text text="てすと" color="blue" size="lg" />
text.component.ts
type Color = 'red' | 'blue';
type Size = 'sm' | 'md' | 'lg';
@Component({
selector: 'app-text',
template: `{{text()}}`,
host: {
'[style.color]': 'color()',
'[style.font-size.px]': 'fontSize()',
},
})
export class TextComponent {
text = input.required<string>();
color = input<Color>('red');
size = input<Size>('md');
fontSize = computed(() => {
const size = this.size();
switch (size) {
case 'sm':
return 10;
case 'md':
return 16;
case 'lg':
return 24;
}
});
}
string型のinputでclass名を制御するケース
複数のclass名を使いたいときは、joinして[class]
に渡す。
[class.color]
や[class.size]
のような書き方は使えない。
main.ts
<app-text text="てすと" color="blue" size="lg" />
text.component.ts
type Color = 'red' | 'blue';
type Size = 'sm' | 'md' | 'lg';
@Component({
selector: 'app-text',
template: `{{text()}}`,
host: {
// NG
// '[class.color]': 'color()',
// '[class.size]': 'size()',
// OK
'[class]': 'classes()',
},
styleUrl: `text.component.css`,
})
export class TextComponent {
text = input.required<string>();
color = input<Color>('red');
size = input<Size>('md');
classes = computed(() => {
const color = this.color();
const size = this.size();
return [color, size].join(' ');
});
}
text.component.css
:host.red {
color: red;
}
:host.blue {
color: blue;
}
:host.sm {
font-size: 10px;
}
:host.md {
font-size: 16px;
}
:host.lg {
font-size: 24px;
}
Discussion