Partilhar via


ASP.NET Core Blazor Isolamento CSS

Observação

Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.

Advertência

Esta versão do ASP.NET Core não é mais suportada. Para obter mais informações, consulte a Política de suporte do .NET e do .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.

Por Dave Brock

Este artigo explica como o isolamento CSS limita o CSS aos componentes Razor, o que pode simplificar o CSS e evitar colisões com outros componentes ou bibliotecas.

Isolar estilos CSS em páginas, exibições e componentes individuais para reduzir ou evitar:

  • Dependências de estilos globais que podem ser difíceis de manter.
  • Conflitos de estilo em conteúdo aninhado.

Ativar isolamento CSS

Para definir estilos específicos do componente, crie um .razor.css arquivo correspondente ao nome do .razor arquivo para o componente na mesma pasta. O .razor.css arquivo é um arquivo CSS com escopo.

Para uma Example componente num Example.razor arquivo, crie um arquivo junto ao componente chamado Example.razor.css. O Example.razor.css arquivo deve residir na mesma pasta que o Example componente (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 Example componente. O isolamento CSS é aplicado a elementos HTML no arquivo correspondente Razor . Quaisquer h1 declarações CSS definidas em outro lugar no aplicativo não entram em conflito com os estilos do Example componente.

Observação

Para garantir o isolamento de estilo quando ocorre agregação, não há suporte para a importação de CSS em Razor blocos de código.

Agrupamento de isolamento CSS

O isolamento CSS ocorre no momento da compilação. Blazor reescreve seletores CSS para corresponder à marcação renderizada pelo componente. Os estilos CSS reescritos são agrupados e produzidos como um ativo estático. A folha de estilo é referenciada dentro da <head> tag (local do <head> conteúdo). O seguinte elemento <link> é adicionado a uma aplicação criada a partir dos modelos de projeto Blazor.

Blazor Web Apps:

<link href="@Assets["{PACKAGE ID/ASSEMBLY NAME}.styles.css"]" rel="stylesheet">

Aplicações Blazor WebAssembly autónomas:

<link href="{PACKAGE ID/ASSEMBLY NAME}.styles.css" rel="stylesheet">
<link href="{PACKAGE ID/ASSEMBLY NAME}.styles.css" rel="stylesheet">

O {PACKAGE ID/ASSEMBLY NAME} espaço reservado é a ID do pacote do projeto (<PackageId> no arquivo de projeto) para um nome de biblioteca ou de assemblagem de uma aplicação.

O exemplo a seguir é de um aplicativo hospedado Blazor WebAssemblyClient . O nome do assembly da aplicação é BlazorSample.Client, e o <link> é adicionado pelo modelo de projeto Blazor WebAssembly quando o projeto é criado com a opção de Hospedagem (-ho|--hosted opção usando a CLI do .NET ou a caixa de seleção ASP.NET Core Hospedado usando o Visual Studio):

<link href="BlazorSample.Client.styles.css" rel="stylesheet">

Dentro do arquivo incluído, cada componente é associado a um identificador de escopo. Para cada componente com estilo, um atributo HTML é acrescentado com o formato b-{STRING}, onde o placeholder {STRING} é uma cadeia de dez caracteres gerada pelo framework. O identificador é exclusivo para cada aplicativo. No componente renderizado Counter , Blazor acrescenta um identificador de escopo ao h1 elemento:

<h1 b-3xxtam6d07>

O {PACKAGE ID/ASSEMBLY NAME}.styles.css arquivo usa o identificador de escopo para agrupar uma declaração de estilo com seu componente. O exemplo a seguir fornece o estilo para o elemento anterior <h1> :

/* /Components/Pages/Counter.razor.rz.scp.css */
h1[b-3xxtam6d07] {
    color: brown;
}

No momento da compilação, um pacote de projeto é criado com a convenção obj/{CONFIGURATION}/{TARGET FRAMEWORK}/scopedcss/projectbundle/{PACKAGE ID/ASSEMBLY NAME}.bundle.scp.css, onde os espaços reservados são:

  • {CONFIGURATION}: A configuração de compilação do aplicativo (por exemplo, DebugRelease, ).
  • {TARGET FRAMEWORK}: A estrutura de destino (por exemplo, net6.0).
  • {PACKAGE ID/ASSEMBLY NAME}: A ID do pacote do projeto (<PackageId> no arquivo do projeto) para uma biblioteca ou nome de assembly para um aplicativo (por exemplo, BlazorSample).

Apoio ao componente filho

O isolamento CSS só se aplica 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 a um componente filho, use o ::deeppseudoelemento em qualquer elemento descendente no ficheiro do .razor.css componente pai. O ::deep pseudoelemento seleciona elementos que são descendentes do identificador de escopo gerado de 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ção em h1 com o pseudo-elemento Parent.razor.css para significar que a declaração de estilo ::deep deve ser aplicada ao componente pai e aos seus filhos.

Parent.razor.css:

::deep h1 { 
    color: red;
}

O estilo h1 agora aplica-se aos componentes Parent e Child sem a necessidade de criar um ficheiro CSS específico para o componente filho.

O ::deep pseudoelemento só funciona com elementos descendentes. A marcação a seguir aplica os h1 estilos aos componentes conforme o esperado. O identificador de escopo do componente pai é aplicado ao div elemento , para que o navegador saiba herdar estilos do componente pai.

Parent.razor:

<div>
    <h1>Parent</h1>

    <Child />
</div>

No entanto, excluir o div elemento remove a relação descendente. No exemplo a seguir, o estilo não é aplicado ao componente filho.

Parent.razor:

<h1>Parent</h1>

<Child />

O ::deep pseudoelemento afeta onde o atributo scope é aplicado à regra. Quando se define uma regra CSS num ficheiro CSS com escopo, o escopo é aplicado ao elemento mais à direita. Por exemplo: div > a é transformado em div > a[b-{STRING}], onde o espaço reservado {STRING} é uma cadeia de dez caracteres gerada pela estrutura (por exemplo, b-3xxtam6d07). Se, em vez disso, você quiser que a regra se aplique a um seletor diferente, o ::deep pseudoelemento permite que você faça isso. Por exemplo, div ::deep > a é transformado em div[b-{STRING}] > a (por exemplo, div[b-3xxtam6d07] > a).

A capacidade de anexar o ::deep pseudoelemento a qualquer elemento HTML permite criar estilos CSS com escopo que afetam elementos renderizados por outros componentes quando você pode determinar a estrutura das tags 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 só seja aplicado a esse componente quando o componente pai for renderizado.

Importante

CSS com escopo só se aplica a elementos HTML e não a Razor componentes ou auxiliares de tag, incluindo elementos com um auxiliar de tag aplicado, como <input asp-for="..." />.

Suporte ao pré-processador CSS

Os pré-processadores CSS são úteis para melhorar o desenvolvimento CSS utilizando recursos como variáveis, aninhamento, módulos, mixins e herança. Embora o isolamento CSS não suporte nativamente pré-processadores CSS, como Sass ou Less, a integração de pré-processadores CSS é perfeita, desde que a compilação do pré-processador ocorra antes Blazor de reescrever os seletores CSS durante o processo de compilação. Usando o Visual Studio, por exemplo, configure a compilação de pré-processador existente como uma tarefa Antes da compilação no Visual Studio Task Runner Explorer.

Muitos pacotes NuGet de terceiros, como AspNetCore.SassCompiler, podem compilar ficheiros SASS/SCSS no início do processo de construção antes de ocorrer o isolamento CSS.

Configuração de isolamento CSS

O isolamento CSS é projetado para funcionar automaticamente, mas fornece opções de configuração para alguns cenários avançados, por exemplo, quando há dependências em ferramentas ou fluxos de trabalho existentes.

Personalizar o formato do identificador de escopo

Os identificadores de escopo usam o formato b-{STRING}, onde o espaço reservado {STRING} é uma cadeia 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 seu identificador de escopo de b-{STRING} para custom-scope-identifier.

Utilize identificadores de escopo para alcançar herança com ficheiros CSS delimitados. No exemplo de arquivo de projeto a seguir, um BaseComponent.razor.css arquivo contém estilos comuns entre componentes. Um DerivedComponent.razor.css arquivo 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}, onde o espaço reservado {STRING} é uma cadeia 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 seu identificador de escopo de b-{STRING} para custom-scope-identifier.

Utilize identificadores de escopo para alcançar herança com ficheiros CSS delimitados. No exemplo de arquivo de projeto a seguir, um BaseComponent.razor.css arquivo contém estilos comuns entre componentes. Um DerivedComponent.razor.css arquivo 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 recursos estáticos da web

O scoped.styles.css arquivo é gerado na raiz do aplicativo. No arquivo de projeto, use a <StaticWebAssetBasePath> propriedade para alterar o caminho padrão. O exemplo a seguir coloca o scoped.styles.css arquivo e o restante dos ativos do aplicativo no _content caminho:

<PropertyGroup>
  <StaticWebAssetBasePath>_content/$(PackageId)</StaticWebAssetBasePath>
</PropertyGroup>

Desativar agregação automática

Para desativar a forma como Blazor publica e carrega arquivos com escopo em tempo de execução, use a DisableScopedCssBundling propriedade. Ao usar essa propriedade, isso significa que outras ferramentas ou processos são responsáveis por retirar os arquivos CSS isolados do obj diretório e publicá-los e carregá-los em tempo de execução:

<PropertyGroup>
  <DisableScopedCssBundling>true</DisableScopedCssBundling>
</PropertyGroup>

Desativar isolamento CSS

Desative o isolamento CSS para um projeto definindo a <ScopedCssEnabled> propriedade como false no arquivo de projeto do aplicativo:

<ScopedCssEnabled>false</ScopedCssEnabled>

Razor suporte para biblioteca de classes (RCL)

Os estilos isolados para componentes em um pacote NuGet ou Razor biblioteca de classes (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 com nome ClassLib e uma Blazor aplicação com uma BlazorSample.styles.css folha de estilo, a folha de estilo da RCL é importada na parte superior da folha de estilo da aplicação:

    @import '_content/ClassLib/ClassLib.bundle.scp.css';
    
  • Os estilos agrupados da RCL não são publicados como um recurso web estático na aplicação que os utiliza.

Para obter mais informações sobre RCLs, consulte os seguintes artigos:

Recursos adicionais