Isolamento CSS di ASP.NET Core Blazor

Nota

Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Importante

Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.

Per la versione corrente, vedere la versione .NET 8 di questo articolo.

Di Dave Brock

Questo articolo illustra in che modo l'isolamento CSS definisce l'ambito CSS ai Razor componenti, che può semplificare CSS ed evitare conflitti con altri componenti o librerie.

Isolare gli stili CSS in singole pagine, visualizzazioni e componenti per ridurre o evitare:

  • Dipendenze da stili globali che possono risultare difficili da gestire.
  • Conflitti di stile nel contenuto annidato.

Abilitare l'isolamento CSS

Per definire stili specifici del componente, creare un .razor.css file corrispondente al nome del .razor file per il componente nella stessa cartella. Il .razor.css file è un file CSS con ambito.

Per un Example componente in un Example.razor file, creare un file insieme al componente denominato Example.razor.css. Il Example.razor.css file deve trovarsi nella stessa cartella del Example componente (Example.razor). Il nome di base "Example" del file non fa distinzione tra maiuscole e minuscole.

Example.razor:

@page "/example"

<h1>Scoped CSS Example</h1>

Example.razor.css:

h1 { 
    color: brown;
    font-family: Tahoma, Geneva, Verdana, sans-serif;
}

Gli stili definiti in Example.razor.css vengono applicati solo all'output sottoposto a rendering del Example componente. L'isolamento CSS viene applicato agli elementi HTML nel file corrispondente Razor . Tutte le h1 dichiarazioni CSS definite altrove nell'app non sono in conflitto con gli Example stili del componente.

Nota

Per garantire l'isolamento dello stile quando si verifica la creazione di bundle, l'importazione di CSS nei Razor blocchi di codice non è supportata.

Creazione di bundle di isolamento CSS

L'isolamento CSS si verifica in fase di compilazione. Blazor riscrive i selettori CSS in modo che corrispondano al markup sottoposto a rendering dal componente. Gli stili CSS riscritti vengono raggruppati e prodotti come asset statici. Viene fatto riferimento al foglio di stile all'interno del <head> tag (posizione del <head> contenuto). L'elemento seguente <link> viene aggiunto per impostazione predefinita a un'app creata dai modelli di Blazor progetto, dove il segnaposto {ASSEMBLY NAME} è il nome dell'assembly del progetto:

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

L'esempio seguente proviene da un'app ospitata Blazor WebAssemblyClient . Il nome dell'assembly dell'app è BlazorSample.Cliente viene <link> aggiunto dal Blazor WebAssembly modello di progetto quando il progetto viene creato con l'opzione Hosted (-ho|--hosted opzione che usa l'interfaccia della riga di comando di .NET o ASP.NET Core Hosted con Visual Studio):

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

All'interno del file in bundle, ogni componente è associato a un identificatore di ambito. Per ogni componente in stile, un attributo HTML viene aggiunto con il formato b-{STRING}, dove il {STRING} segnaposto è una stringa di dieci caratteri generata dal framework. L'identificatore è univoco per ogni app. Nel componente Blazor sottoposto Counter a rendering aggiunge un identificatore di ambito all'elemento h1 :

<h1 b-3xxtam6d07>

Il {ASSEMBLY NAME}.styles.css file usa l'identificatore di ambito per raggruppare una dichiarazione di stile con il relativo componente. Nell'esempio seguente viene fornito lo stile per l'elemento precedente <h1> :

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

In fase di compilazione viene creato un bundle di progetto con la convenzione obj/{CONFIGURATION}/{TARGET FRAMEWORK}/scopedcss/projectbundle/{ASSEMBLY NAME}.bundle.scp.css, dove i segnaposto sono:

  • {CONFIGURATION}: la configurazione di compilazione dell'app , ad esempio Debug, Release.
  • {TARGET FRAMEWORK}: framework di destinazione (ad esempio, net6.0).
  • {ASSEMBLY NAME}: nome dell'assembly dell'app (ad esempio, BlazorSample).

Supporto dei componenti figlio

Per impostazione predefinita, l'isolamento CSS si applica solo al componente associato al formato {COMPONENT NAME}.razor.css, dove il segnaposto {COMPONENT NAME} è in genere il nome del componente. Per applicare le modifiche a un componente figlio, utilizzare lo ::deeppseudoelemento per qualsiasi elemento discendente nel file del .razor.css componente padre. Lo ::deep pseudoelemento seleziona gli elementi discendenti dell'identificatore di ambito generato da un elemento.

Nell'esempio seguente viene illustrato un componente padre denominato Parent con un componente figlio denominato Child.

Parent.razor:

@page "/parent"

<div>
    <h1>Parent component</h1>

    <Child />
</div>

Child.razor:

<h1>Child Component</h1>

Aggiornare la h1 dichiarazione in Parent.razor.css con lo ::deep pseudoelemento per indicare la h1 dichiarazione di stile deve essere applicata al componente padre e ai relativi elementi figlio.

Parent.razor.css:

::deep h1 { 
    color: red;
}

Lo h1 stile ora si applica ai Parent componenti e Child senza la necessità di creare un file CSS con ambito separato per il componente figlio.

Lo ::deep pseudoelemento funziona solo con gli elementi discendenti. Il markup seguente applica gli h1 stili ai componenti come previsto. L'identificatore di ambito del componente padre viene applicato all'elemento div , quindi il browser sa ereditare gli stili dal componente padre.

Parent.razor:

<div>
    <h1>Parent</h1>

    <Child />
</div>

Tuttavia, l'esclusione dell'elemento div rimuove la relazione discendente. Nell'esempio seguente lo stile non viene applicato al componente figlio.

Parent.razor:

<h1>Parent</h1>

<Child />

Lo ::deep pseudoelemento influisce sulla posizione in cui l'attributo scope viene applicato alla regola. Quando si definisce una regola CSS in un file CSS con ambito, l'ambito viene applicato all'elemento più a destra per impostazione predefinita. Ad esempio: div > a viene trasformato in div > a[b-{STRING}], dove il {STRING} segnaposto è una stringa di dieci caratteri generata dal framework , ad esempio b-3xxtam6d07. Se invece si desidera che la regola venga applicata a un selettore diverso, lo ::deep pseudoelemento consente di farlo. Ad esempio, div ::deep > a viene trasformato in div[b-{STRING}] > a (ad esempio, div[b-3xxtam6d07] > a).

La possibilità di associare lo ::deep pseudoelemento a qualsiasi elemento HTML consente di creare stili CSS con ambito che influiscono sugli elementi sottoposti a rendering da altri componenti quando è possibile determinare la struttura dei tag HTML sottoposti a rendering. Per un componente che esegue il rendering di un tag di collegamento ipertestuale (<a>) all'interno di un altro componente, verificare che il componente sia incluso in un div elemento (o qualsiasi altro elemento) e usare la regola ::deep > a per creare uno stile applicato solo a tale componente quando viene eseguito il rendering del componente padre.

Importante

Css con ambito si applica solo agli elementi HTML e non ai componenti o agli Razor helper tag, inclusi gli elementi con un helper tag applicato, ad esempio <input asp-for="..." />.

Supporto dei preprocessori CSS

I preprocessori CSS sono utili per migliorare lo sviluppo di CSS tramite l'utilizzo di funzionalità come variabili, annidamenti, moduli, mixin ed ereditarietà. Anche se l'isolamento CSS non supporta in modo nativo preprocessori CSS, ad esempio Sass o Less, l'integrazione dei preprocessori CSS è facile, purché la compilazione del preprocessore venga eseguita prima Blazor di riscrivere i selettori CSS durante il processo di compilazione. Usando Visual Studio, ad esempio, configurare la compilazione del preprocessore esistente come attività Prima di compilare in Esplora esecuzione attività.

Molti pacchetti NuGet di terze parti, ad esempio AspNetCore.SassCompiler, possono compilare file SASS/SCSS all'inizio del processo di compilazione prima che si verifichi l'isolamento CSS.

Configurazione dell'isolamento CSS

L'isolamento CSS è progettato per funzionare correttamente, ma fornisce la configurazione per alcuni scenari avanzati, ad esempio quando sono presenti dipendenze da strumenti o flussi di lavoro esistenti.

Personalizzare il formato dell'identificatore di ambito

Per impostazione predefinita, gli identificatori di ambito usano il formato b-{STRING}, dove il segnaposto {STRING} è una stringa di dieci caratteri generata dal framework. Per personalizzare il formato dell'identificatore di ambito, aggiornare il file di progetto a un modello desiderato:

<ItemGroup>
  <None Update="Components/Pages/Example.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Nell'esempio precedente il file CSS generato per Example.razor.css cambia il relativo identificatore di ambito da b-{STRING} a custom-scope-identifier.

Usare gli identificatori di ambito per ottenere l'ereditarietà con i file CSS con ambito. Nell'esempio di file di progetto seguente un BaseComponent.razor.css file contiene stili comuni tra i componenti. Un file DerivedComponent.razor.css eredita questi stili.

<ItemGroup>
  <None Update="Components/Pages/BaseComponent.razor.css" CssScope="custom-scope-identifier" />
  <None Update="Components/Pages/DerivedComponent.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Usare l'operatore carattere jolly (*) per condividere gli identificatori di ambito tra più file:

<ItemGroup>
  <None Update="Components/Pages/*.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Per impostazione predefinita, gli identificatori di ambito usano il formato b-{STRING}, dove il segnaposto {STRING} è una stringa di dieci caratteri generata dal framework. Per personalizzare il formato dell'identificatore di ambito, aggiornare il file di progetto a un modello desiderato:

<ItemGroup>
  <None Update="Pages/Example.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Nell'esempio precedente il file CSS generato per Example.razor.css cambia il relativo identificatore di ambito da b-{STRING} a custom-scope-identifier.

Usare gli identificatori di ambito per ottenere l'ereditarietà con i file CSS con ambito. Nell'esempio di file di progetto seguente un BaseComponent.razor.css file contiene stili comuni tra i componenti. Un file DerivedComponent.razor.css eredita questi stili.

<ItemGroup>
  <None Update="Pages/BaseComponent.razor.css" CssScope="custom-scope-identifier" />
  <None Update="Pages/DerivedComponent.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Usare l'operatore carattere jolly (*) per condividere gli identificatori di ambito tra più file:

<ItemGroup>
  <None Update="Pages/*.razor.css" CssScope="custom-scope-identifier" />
</ItemGroup>

Cambiare il percorso di base per gli asset Web statici

Il scoped.styles.css file viene generato nella radice dell'app. Nel file di progetto usare la <StaticWebAssetBasePath> proprietà per modificare il percorso predefinito. L'esempio seguente inserisce il scoped.styles.css file e il resto degli asset dell'app nel _content percorso:

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

Disabilitare il raggruppamento automatico in bundle

Per rifiutare esplicitamente come Blazor pubblica e carica i file con ambito in fase di esecuzione, usare la DisableScopedCssBundling proprietà . Quando si usa questa proprietà, significa che altri strumenti o processi sono responsabili dell'acquisizione dei file CSS isolati dalla directory e della obj pubblicazione e del caricamento in fase di esecuzione:

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

Disabilitare l'isolamento CSS

Disabilitare l'isolamento CSS per un progetto impostando la <ScopedCssEnabled> proprietà su false nel file di progetto dell'app:

<ScopedCssEnabled>false</ScopedCssEnabled>

Supporto della libreria di classi Razor (RCL)

Gli stili isolati per i componenti in un pacchetto NuGet o Razor in una libreria di classi (RCL) vengono raggruppati automaticamente:

  • L'app usa le importazioni CSS per fare riferimento agli stili in bundle di RCL. Per una libreria di classi denominata ClassLib e un'app Blazor con un BlazorSample.styles.css foglio di stile, il foglio di stile rcl viene importato nella parte superiore del foglio di stile dell'app:

    @import '_content/ClassLib/ClassLib.bundle.scp.css';
    
  • Gli stili in bundle di RCL non vengono pubblicati come asset Web statici dell'app che utilizza gli stili.

Per altre informazioni sulle librerie di classi Razor (RCL), vedere gli articoli seguenti: