Diretivas de Atributo ngClass e ngStyle em Angular
Introdução
As diretivas definem um conjunto de instruções aplicadas ao renderizar o código HTML. Uma diretiva é representada por uma classe com metadados de diretiva. No TypeScript, o decorador @Directive
é usado para anexar metadados a uma classe.
No Angular, existem três tipos de diretivas:
Componentes
: Um componente também é essencialmente uma diretiva, e o decorador@Component
expande as funcionalidades do decorador@Directive
adicionando recursos para trabalhar com templates.De atributo
: Estas diretivas alteram o comportamento de um elemento já existente ao qual são aplicadas. Por exemplo, as diretivas embutidas no Angular, comongModel
,ngStyle
engClass
.Estruturais
: Elas alteram a estrutura do DOM adicionando, modificando ou removendo elementos HTML. Exemplos são as diretivasngFor
engIf
.
ngClass
A diretiva ngClass
permite definir um conjunto de classes que serão aplicadas a um elemento. Ela aceita um conjunto de classes no seguinte formato:
[ngClass]="{
'classe1': true/false,
'classe2': true/false,
...
}"
Para usar essa diretiva, é necessário importar a classe NgClass
do módulo @angular/common
.
Por exemplo, podemos definir o seguinte componente:
import { Component } from "@angular/core";
import { NgClass } from "@angular/common";
@Component({
selector: "my-app",
standalone: true,
imports: [NgClass],
template: `<div [ngClass]="{ verdanaFont: true }">
<h1>Hello Angular</h1>
<p [ngClass]="{ segoePrintFont: true }">A aplicação Angular é composta por componentes</p>
</div>`,
styles: [
`
.verdanaFont {
font-size: 13px;
font-family: Verdana;
}
`,
`
.segoePrintFont {
font-size: 14px;
font-family: "Segoe Print";
}
`,
],
})
export class AppComponent {}
Na seção de estilos do componente, foram definidos dois estilos que estabelecem diferentes propriedades de fonte: verdanaFont
e segoePrintFont
.
No template, a diretiva [ngClass]="{verdanaFont: true}"
é usada para vincular a classe a um elemento. Essa diretiva aceita um objeto JavaScript onde as chaves são os nomes das classes e os valores booleanos determinam se a classe deve ser aplicada (true
) ou não (false
). No exemplo acima, a classe verdanaFont
será aplicada ao elemento div
.
No entanto, dentro do bloco div
, há um parágrafo, e queremos aplicar um estilo diferente a ele. Por padrão, o parágrafo herda os estilos do bloco div
pai, mas podemos sobrescrever esses estilos aplicando a classe segoePrintFont
.
Em vez de valores fixos (true
/false
), podemos usar expressões vinculadas:
import { Component } from "@angular/core";
import { NgClass } from "@angular/common";
@Component({
selector: "my-app",
standalone: true,
imports: [NgClass],
template: `<div [ngClass]="{ verdanaFont: isVerdana }">
<h1>Hello Angular</h1>
<p [ngClass]="{ segoePrintFont: isSegoe }">A aplicação Angular é composta por componentes</p>
</div>`,
styles: [
`
.verdanaFont {
font-size: 13px;
font-family: Verdana;
}
`,
`
.segoePrintFont {
font-size: 14px;
font-family: "Segoe Print";
}
`,
],
})
export class AppComponent {
isVerdana = true;
isSegoe = true;
}
Alternativamente, podemos usar as seguintes expressões de vinculação:
<div [class.verdanaFont]="true">
<h1>Hello Angular</h1>
<p [class.verdanaFont]="false" [class.segoePrintFont]="true">A aplicação Angular é composta por componentes</p>
</div>
A expressão [class.verdanaFont]="true"
indica que a classe verdanaFont
será aplicada ao elemento.
No entanto, com ngClass
, podemos definir um conjunto de classes a serem aplicadas a um elemento:
import { Component } from "@angular/core";
import { NgClass } from "@angular/common";
@Component({
selector: "my-app",
standalone: true,
imports: [NgClass],
template: `<div [ngClass]="currentClasses">
<h1>Hello Angular</h1>
<p>A aplicação Angular é composta por componentes</p>
</div>`,
styles: [
`
.verdanaFont {
font-size: 13px;
font-family: Verdana;
}
`,
`
.navyColor {
color: navy;
}
`,
],
})
export class AppComponent {
isVerdana = true;
isNavy = true;
currentClasses = {
verdanaFont: this.isVerdana,
navyColor: this.isNavy,
};
}
Nesse caso, as classes verdanaFont
e navyColor
serão aplicadas ao elemento.
ngStyle
A diretiva ngStyle
permite definir um conjunto de estilos que serão aplicados a um elemento. A diretiva aceita um objeto JavaScript onde as chaves são os nomes das propriedades CSS:
import { Component } from "@angular/core";
import { NgStyle } from "@angular/common";
@Component({
selector: "my-app",
standalone: true,
imports: [NgStyle],
template: `<div [ngStyle]="{ 'font-size': '13px', 'font-family': 'Verdana' }">
<h1>Hello Angular</h1>
<p [ngStyle]="{ 'font-size': '14px', 'font-family': 'Segoe Print' }">A aplicação Angular é composta por componentes</p>
</div>`,
})
export class AppComponent {}
Para usar a diretiva ngStyle
, é necessário importar a classe NgStyle
do pacote @angular/common
.
De forma semelhante, também podemos aplicar estilos usando propriedades do objeto style
:
<div [style.fontSize]="'13px'" [style.fontFamily]="'Verdana'">
<h1>Hello Angular</h1>
<p [style.fontSize]="'14px'" [style.fontFamily]="'Segoe Print'">A aplicação Angular é composta por componentes</p>
</div>
Também podemos estabelecer uma vinculação dinâmica.
Alteração Dinâmica de Estilos
As diretivas ngClass
e ngStyle
permitem a vinculação a expressões, possibilitando a alteração dinâmica de estilos ou classes. Por exemplo:
import { Component } from "@angular/core";
import { NgClass } from "@angular/common";
@Component({
selector: "my-app",
standalone: true,
imports: [NgClass],
template: `<div [ngClass]="{ invisible: visibility }">
<h1>Hello Angular</h1>
<p>A aplicação Angular é composta por componentes</p>
</div>
<button (click)="toggle()">Toggle</button>`,
styles: [
`
.invisible {
display: none;
}
`,
],
})
export class AppComponent {
visibility: boolean = true;
toggle() {
this.visibility = !this.visibility;
}
}
A expressão [ngClass]="{invisible: visibility}"
vincula a classe invisible
ao valor da variável visibility
. Ao clicar no botão, podemos alternar esse valor, controlando assim a visibilidade do bloco.
Como alternativa, também poderíamos usar a seguinte expressão:
<div [class.invisible]="visibility"></div>
Ou ainda:
<div [style.display]="visibility ? 'block' : 'none'"></div>