English
Français

Blog of Denis VOITURON

for a better .NET world

Blazor CSS Isolation

Posted on 2025-10-17

Vue d’ensemble

Le CSS Isolation (ou CSS isolé) est une fonctionnalité de Blazor qui permet d’associer des styles CSS spécifiquement à un composant, évitant ainsi les conflits de styles avec d’autres composants ou bibliothèques. Cette approche améliore la maintenabilité et la modularité des applications Blazor.

Comment activer le CSS Isolation?

Pour définir des styles spécifiques à un composant, il suffit de créer un fichier .razor.css qui porte le même nom que le fichier .razor du composant, dans le même dossier.

Par exemple, pour un composant MonComposant dans un fichier MonComposant.razor, créez un fichier MonComposant.razor.css à côté :

MonComposant.razor :

<div class="container">
    <h1>Mon Titre</h1>
    <p class="description">Description de mon composant</p>
</div>

MonComposant.razor.css :

.container {
    background-color: #f0f0f0;
    padding: 20px;
    border-radius: 8px;
}

h1 {
    color: #333;
    font-size: 2rem;
    margin-bottom: 1rem;
}

.description {
    color: #666;
    font-style: italic;
}

Comment cela fonctionne en interne

Lors de la compilation, Blazor réécrit automatiquement les sélecteurs CSS pour qu’ils correspondent au balisage rendu par le composant. Le framework génère un identifiant de portée unique au format b-{STRING} (où {STRING} est une chaîne de 10 caractères générée automatiquement) et l’ajoute comme attribut HTML aux éléments du composant.

HTML généré :

<div class="container" b-3xxtam6d07>
    <h1 b-3xxtam6d07>Mon Titre</h1>
    <p class="description" b-3xxtam6d07>...</p>
</div>

CSS généré :

.container[b-3xxtam6d07] {
    background-color: #f0f0f0;
    padding: 20px;
    border-radius: 8px;
}

h1[b-3xxtam6d07] {
    color: #333;
    font-size: 2rem;
    margin-bottom: 1rem;
}

.description[b-3xxtam6d07] {
    color: #666;
    font-style: italic;
}

Avantages du CSS Isolation

✅ Encapsulation des styles

✅ Maintenabilité améliorée

✅ Performance optimisée

✅ Simplicité d’utilisation

Inconvénients et limitations

❌ Complexité avec les composants enfants

❌ Limitation sur les composants Razor

❌ Structure HTML contrainte

❌ Debugging plus complexe

Styliser les composants enfants avec ::deep

L’un des défis majeurs du CSS Isolation est le styling des composants enfants. Par défaut, les styles isolés ne s’appliquent qu’au composant parent.

Le problème

Parent.razor :

@page "/parent"

<h1>Composant Parent</h1>
<MyChildComponent />

Parent.razor.css :

/* This style will NOT apply to the child component. */
h1 {
    color: blue;
}

MyChildComponent.razor :

<h1>MyChildComponent</h1>

La solution avec ::deep

Pour appliquer des styles aux composants enfants, utilisez le pseudo-élément ::deep :

Parent.razor.css :

/* This style will apply to the h1 of the parent AND the children. */
::deep h1 {
    color: blue;
}

Point crucial : Nécessité d’un élément HTML conteneur

Problème : L’identifiant généré n’est pas appliqué aux composants Razor eux-mêmes, mais seulement aux éléments HTML qu’ils contiennent. Pour utiliser ::deep correctement, il est souvent nécessaire d’ajouter un élément HTML conteneur.

Exemple incorrect (ne fonctionnera pas) :

<!-- Parent.razor -->
<h1>Parent</h1>
<MyChildComponent />

Exemple correct (fonctionnera) :

<!-- Parent.razor -->
<div>
    <h1>Parent</h1>
    <MyChildComponent />
</div>

Parent.razor.css :

/* Maintenant ::deep peut fonctionner correctement */
::deep h1 {
    color: red;
}

Le div conteneur reçoit l’identifiant de portée, permettant à ::deep de fonctionner sur les éléments descendants.

Exemples pratiques

Composant Card avec isolation CSS

Card.razor :

<div class="card">
    <div class="card-header">
        <h3>@Title</h3>
    </div>
    <div class="card-content">
        @ChildContent
    </div>
</div>

@code {
    [Parameter] public string Title { get; set; } = "";
    [Parameter] public RenderFragment? ChildContent { get; set; }
}

Card.razor.css :

.card {
    background: white;
    border: 1px solid #ddd;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
    margin-bottom: 1rem;
}

.card-header {
    background: #f8f9fa;
    padding: 1rem;
    border-bottom: 1px solid #ddd;
    border-radius: 8px 8px 0 0;
}

.card-header h3 {
    margin: 0;
    color: #333;
}

.card-content {
    padding: 1rem;
}

Page utilisant le composant Card

MaPage.razor :

@page "/ma-page"

<div class="page-container">
    <Card Title="Première carte">
        <p>Contenu de la première carte</p>
    </Card>
    
    <Card Title="Seconde carte">
        <p>Contenu de la seconde carte</p>
    </Card>
</div>

MaPage.razor.css :

.page-container {
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem;
}

/* Styliser les cartes depuis le parent */
::deep .card {
    transition: transform 0.2s ease;
}

::deep .card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}

Configuration avancée

Personnaliser l’identifiant de portée

Vous pouvez personnaliser le format de l’identifiant de portée dans le fichier projet :

<ItemGroup>
  <None Update="Components/MonComposant.razor.css" CssScope="mon-identifiant-custom" />
</ItemGroup>

Désactiver le CSS Isolation

Pour désactiver complètement le CSS Isolation dans un projet :

<PropertyGroup>
  <ScopedCssEnabled>false</ScopedCssEnabled>
</PropertyGroup>

Bonnes pratiques

  1. Organisez vos styles : Gardez les fichiers .razor.css à côté de leurs composants respectifs
  2. Utilisez des noms de classes explicites : Même si les styles sont isolés, des noms clairs améliorent la lisibilité
  3. Minimisez l’usage de ::deep : Préférez la composition de composants plutôt que la modification de styles enfants
  4. Ajoutez des conteneurs HTML : Quand vous devez utiliser ::deep, assurez-vous d’avoir un élément HTML conteneur approprié
  5. Testez la compatibilité : Vérifiez que vos styles fonctionnent correctement avec les différents navigateurs

Conclusion

Le CSS Isolation de Blazor est un outil puissant pour maintenir des styles organisés et éviter les conflits. Bien qu’il présente quelques limitations, notamment avec les composants enfants et la nécessité d’ajouter parfois des éléments HTML conteneurs, ses avantages en termes de maintenabilité et d’encapsulation en font un choix judicieux pour la plupart des applications Blazor.

La compréhension du fonctionnement interne, notamment le fait que l’identifiant généré ne s’applique qu’aux éléments HTML et non aux composants Razor eux-mêmes, est essentielle pour utiliser efficacement cette fonctionnalité.

Ressources

Langues

EnglishEnglish
FrenchFrançais

Suivez-moi

Articles récents