Isolamento de CSS do ASP.NET Core Blazor
Observação
Esta não é a versão mais recente deste artigo. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, confira .NET e a Política de Suporte do .NET Core. Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Importante
Essas informações relacionam-se ao produto de pré-lançamento, que poderá ser substancialmente modificado antes do lançamento comercial. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.
Para informações sobre a versão vigente, confira a Versão do .NET 8 deste artigo.
Por Dave Brock
Este artigo explica como o isolamento de CSS define o CSS para componentes Razor, o que pode simplificar o CSS e evitar colisões com outros componentes ou bibliotecas.
Isole estilos CSS em páginas, exibições e componentes individuais para reduzir ou evitar:
- Dependências de estilos globais que podem ser desafiadoras de manter.
- Conflitos de estilo em conteúdo aninhado.
Habilitar o isolamento de CSS
Para definir estilos específicos do componente, crie um arquivo .razor.css
que corresponda ao nome do arquivo .razor
para o componente na mesma pasta. O arquivo .razor.css
é umarquivo CSS com escopo.
Para um componente Example
em um arquivo Example.razor
, crie um arquivo junto com o componente chamado Example.razor.css
. O arquivo Example.razor.css
deve estar na mesma pasta que o componente Example
(Example.razor
). O nome base "Example
" do arquivo não diferencia maiúsculas de minúsculas.
Example.razor
:
@page "/example"
<h1>Scoped CSS Example</h1>
Example.razor.css
:
h1 {
color: brown;
font-family: Tahoma, Geneva, Verdana, sans-serif;
}
Os estilos definidos em Example.razor.css
são aplicados apenas à saída renderizada do componente Example
. O isolamento de CSS é aplicado a elementos HTML no arquivo Razor correspondente. Quaisquer declarações CSS h1
definidas em outro lugar no aplicativo não entram em conflito com os estilos do componente Example
.
Observação
Para garantir o isolamento do estilo quando ocorrer o agrupamento, não há suporte para a importação de CSS em blocos de código Razor.
Agrupamento de isolamento de CSS
O isolamento de CSS ocorre no momento do build. Blazor reescreve os seletores de CSS para fazer a correspondência da marcação renderizada pelo componente. Os estilos CSS reescritos são empacotados e produzidos como um ativo estático. A folha de estilos é referenciada dentro da <head>
marca (local do <head>
conteúdo). O seguinte elemento <link>
é adicionado a um aplicativo criado a partir dos modelos de projeto Blazor:
Blazor Web Apps:
<link href="@Assets["{ASSEMBLY NAME}.styles.css"]" rel="stylesheet">
Aplicativos Blazor WebAssembly autônomos:
<link href="{ASSEMBLY NAME}.styles.css" rel="stylesheet">
<link href="{ASSEMBLY NAME}.styles.css" rel="stylesheet">
O espaço reservado {ASSEMBLY NAME}
é o nome do assembly do projeto.
O exemplo a seguir é de um aplicativo Blazor WebAssemblyClienthospedado. O nome do assembly do aplicativo é BlazorSample.Client
e <link>
é adicionado pelo modelo de projeto Blazor WebAssembly quando o projeto é criado com a opção Hospedado (opção -ho|--hosted
usando a CLI do .NET ou a caixa de seleção ASP.NET Core Hospedada usando o Visual Studio):
<link href="BlazorSample.Client.styles.css" rel="stylesheet">
Dentro do arquivo agrupado, cada componente está associado a um identificador de escopo. Para cada componente com estilo, acrescenta-se um atributo HTML com o formato b-{STRING}
, em que o espaço reservado {STRING}
é uma cadeia de dez caracteres gerada pela estrutura. O identificador é exclusivo para cada aplicativo. No componente Counter
renderizado, Blazor acrescenta um identificador de escopo ao h1
elemento :
<h1 b-3xxtam6d07>
O arquivo {ASSEMBLY NAME}.styles.css
usa o identificador de escopo para agrupar uma declaração de estilo ao seu componente. O seguinte exemplo mostra o estilo do elemento <h1>
anterior:
/* /Components/Pages/Counter.razor.rz.scp.css */
h1[b-3xxtam6d07] {
color: brown;
}
No momento da compilação, é criado um pacote de projeto com a convenção obj/{CONFIGURATION}/{TARGET FRAMEWORK}/scopedcss/projectbundle/{ASSEMBLY NAME}.bundle.scp.css
, em que os espaços reservados são:
{CONFIGURATION}
: a configuração de compilação do aplicativo (por exemplo,Debug
,Release
).{TARGET FRAMEWORK}
: a estrutura de destino (por exemplo,net6.0
).{ASSEMBLY NAME}
: o nome do assembly do aplicativo (por exemplo,BlazorSample
).
Suporte a componente filho
O isolamento CSS se aplica apenas ao componente associado ao formato {COMPONENT NAME}.razor.css
, onde o espaço reservado {COMPONENT NAME}
geralmente é o nome do componente. Para aplicar alterações em um componente filho, use o ::deep
pseudo-elemento para quaisquer elementos descendentes no arquivo .razor.css
do componente pai. O pseudo-elemento ::deep
seleciona elementos que são descendentes do identificador de escopo gerado por um elemento.
O exemplo a seguir mostra um componente pai chamado Parent
com um componente filho chamado Child
.
Parent.razor
:
@page "/parent"
<div>
<h1>Parent component</h1>
<Child />
</div>
Child.razor
:
<h1>Child Component</h1>
Atualize a declaraçãoh1
em Parent.razor.css
com o pseudo-elemento ::deep
para simbolizar que a declaração de estilo h1
deve ser aplicada ao componente pai e filhos.
Parent.razor.css
:
::deep h1 {
color: red;
}
O estilo h1
agora se aplica aos componentes Parent
e Child
sem a necessidade de criar um arquivo CSS com escopo separado para o componente filho.
O pseudoelemento ::deep
funciona somente com elementos descendentes. A marcação a seguir aplica os estilos h1
aos componentes conforme o esperado. O identificador de escopo do componente pai é aplicado ao elemento div
, portanto, o navegador sabe herdar estilos do componente pai.
Parent.razor
:
<div>
<h1>Parent</h1>
<Child />
</div>
No entanto, excluir o elemento div
remove a relação descendente. No exemplo a seguir, o estilo não é aplicado ao componente filho.
Parent.razor
:
<h1>Parent</h1>
<Child />
O pseudoelemento ::deep
afeta onde o atributo de escopo é aplicado à regra. Quando você define uma regra CSS em um arquivo CSS com escopo, o escopo é aplicado ao elemento mais à direita. Por exemplo: div > a
é transformado em div > a[b-{STRING}]
, em que o espaço reservado {STRING}
é uma cadeia de dez caracteres gerada pela estrutura (por exemplo, b-3xxtam6d07
). Para que a regra seja aplicada a um seletor diferente, o pseudoelemento ::deep
permite essa aplicação. Por exemplo, div ::deep > a
é transformado em div[b-{STRING}] > a
(por exemplo, div[b-3xxtam6d07] > a
).
Poder anexar o pseudo-elemento ::deep
a qualquer elemento HTML permite que você crie estilos CSS com escopo que alteram os elementos renderizados por outros componentes quando você pode determinar a estrutura das marcas HTML renderizadas. Para um componente que renderiza uma marca de hiperlink (<a>
) dentro de outro componente, verifique se o componente está encapsulado em um div
(ou qualquer outro elemento) e use a regra ::deep > a
para criar um estilo que somente é aplicado a esse componente quando o componente pai é renderizado.
Importante
O CSS com escopo somente se aplica a elementos HTML e não a componentes Razor ou Auxiliares de Marca, incluindo elementos com um Auxiliar de Marca aplicado, como <input asp-for="..." />
.
Suporte para pré-processador de CSS
Pré-processadores de CSS são úteis para aprimorar o desenvolvimento de CSS utilizando recursos como variáveis, aninhamento, módulos, mixins e herança. Embora o isolamento de CSS não dê suporte nativo a pré-processadores CSS, como Sass ou Less, a integração de pré-processadores de CSS é contínua desde que a compilação do pré-processador ocorra antes que Blazor reescreva os seletores de CSS durante o processo de compilação. Usando o Visual Studio, por exemplo, configure a compilação de pré-processador existente como uma tarefa Before Build no Gerenciador do Executor de Tarefas do Visual Studio.
Muitos pacotes NuGet de terceiros, como AspNetCore.SassCompiler
, podem compilar arquivos SASS/SCSS no início do processo de compilação antes que ocorra o isolamento de CSS e não será necessária nenhuma configuração adicional.
Configuração do isolamento de CSS
O isolamento do CSS foi feito para funcionar “out-of-the-box”, mas tem configuração para alguns cenários avançados, por exemplo, quando há dependências em ferramentas ou fluxos de trabalho existentes.
Personalizar o formato de identificador de escopo
Os identificadores de escopo usam o formato b-{STRING}
, em que o espaço reservado {STRING}
é uma cadeia de caracteres de dez caracteres gerada pela estrutura. Para personalizar o formato do identificador de escopo, atualize o arquivo de projeto para um padrão desejado:
<ItemGroup>
<None Update="Components/Pages/Example.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>
No exemplo anterior, o CSS gerado para Example.razor.css
altera o identificador de escopo de b-{STRING}
para custom-scope-identifier
.
Use identificadores de escopo para obter a herança com arquivos CSS com escopo. No exemplo de arquivo de projeto a seguir, um arquivo BaseComponent.razor.css
contém estilos comuns entre componentes. Um arquivo DerivedComponent.razor.css
herda esses estilos.
<ItemGroup>
<None Update="Components/Pages/BaseComponent.razor.css" CssScope="custom-scope-identifier" />
<None Update="Components/Pages/DerivedComponent.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Use o operador curinga (*
) para compartilhar identificadores de escopo em vários arquivos:
<ItemGroup>
<None Update="Components/Pages/*.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Os identificadores de escopo usam o formato b-{STRING}
, em que o espaço reservado {STRING}
é uma cadeia de caracteres de dez caracteres gerada pela estrutura. Para personalizar o formato do identificador de escopo, atualize o arquivo de projeto para um padrão desejado:
<ItemGroup>
<None Update="Pages/Example.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>
No exemplo anterior, o CSS gerado para Example.razor.css
altera o identificador de escopo de b-{STRING}
para custom-scope-identifier
.
Use identificadores de escopo para obter a herança com arquivos CSS com escopo. No exemplo de arquivo de projeto a seguir, um arquivo BaseComponent.razor.css
contém estilos comuns entre componentes. Um arquivo DerivedComponent.razor.css
herda esses estilos.
<ItemGroup>
<None Update="Pages/BaseComponent.razor.css" CssScope="custom-scope-identifier" />
<None Update="Pages/DerivedComponent.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Use o operador curinga (*
) para compartilhar identificadores de escopo em vários arquivos:
<ItemGroup>
<None Update="Pages/*.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>
Alterar o caminho base para ativos da Web estáticos
O arquivo scoped.styles.css
é gerado na raiz do aplicativo. No arquivo de projeto, use a <StaticWebAssetBasePath>
propriedade para alterar o caminho padrão. O seguinte exemplo coloca o arquivo scoped.styles.css
e o rest dos ativos do aplicativo no caminho _content
:
<PropertyGroup>
<StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>
Desabilitar o agrupamento automático
Use a propriedade DisableScopedCssBundling
para recusar como Blazor publica e carrega os arquivos com escopo no runtime. Usando essa propriedade, outras ferramentas ou processos são responsáveis por tirar os arquivos CSS isolados do diretório obj
e publicá-los e carregá-los em runtime:
<PropertyGroup>
<DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>
Desabilitar o isolamento de CSS
Desabilite o isolamento de CSS para um projeto definindo a propriedade <ScopedCssEnabled>
como false
no arquivo de projeto do aplicativo:
<ScopedCssEnabled>false</ScopedCssEnabled>
Suporte à RCL (biblioteca de classes) Razor
Estilos isolados para componentes em um pacote NuGet ou biblioteca de classesRazor (RCL) são agrupados automaticamente:
O aplicativo usa importações CSS para fazer referência aos estilos agrupados da RCL. Para uma biblioteca de classes chamada
ClassLib
e um aplicativo Blazor com uma folha de estilosBlazorSample.styles.css
, a folha de estilos da RCL é importada na parte superior da folha de estilos do aplicativo:@import '_content/ClassLib/ClassLib.bundle.scp.css';
Os estilos agrupados da RCL não serão publicado como um ativo da Web estático do aplicativo que consome os estilos.
Para obter mais informações sobre RCLs, consulte os seguintes artigos:
- Consumir componentes do Razor de uma Razor biblioteca de classes (RCL)
- Interface do usuário do Razor reutilizável em bibliotecas de classes com o ASP.NET Core