CSS-Isolationsproblem in Blazor

CSS-Isolationsproblem in Blazor

1. Umwelt

VS 2019 16.9.0 Vorschau 1.0

.NET SDK 5.0.100

2. Einleitung

Sobald CSS wirksam wird, wird es global angewendet, sodass wahrscheinlich Konflikte auftreten. Um dieses Problem zu lösen, wurde die CSS-Isolation entwickelt. Blazor wurde 2018 geboren, also vor mehr als 2 Jahren. CSS-Isolation wurde jedoch erst ab .NET 5 unterstützt.

3. Isolation zwischen Razor-Komponenten

Die CSS-Isolierung zwischen Razor-Komponenten sollte die einfachste und bequemste Möglichkeit sein, CSS-Isolierung zu verwenden. Es ist sehr einfach, CSS-Isolierung zwischen Razor-Komponenten zu erreichen. Sie müssen nur eine gleichnamige Datei „.razor.css“ im Verzeichnis erstellen, in dem sich die Komponente befindet. Wenn sich in Ordner A eine Komponente mit dem Namen „Component.razor“ befindet, müssen Sie nur „Component.razor.css“ in Ordner A erstellen, um einen separaten Stil für die Komponente „Component.razor“ festzulegen, ohne andere Komponenten zu beeinträchtigen.

Erstellen Sie am Beispiel der Standardvorlage eine neue „Index.razor.css“ mit folgendem Inhalt:

h1 {
    Schriftgröße: 48px;
    Schriftstärke: fett;
}

Erstellen Sie eine neue „Counter.razor.css“ mit folgendem Inhalt:

h1 {
    Schriftgröße: 16px;
    Schriftstärke: 400;
}

Die Wirkung ist wie folgt:

Die oben genannten Komponenten-CSS-Dateien werden als „Projektname.styles.css“-Dateien generiert, die in .NET 5 standardmäßig zu „index.html“ hinzugefügt werden. Die beiden oben genannten CSS-Dateien werden zu den folgenden Ergebnissen kompiliert:

/* /Seiten/Zähler.razor.rz.scp.css */
h1[b-g5zg69lne1] {
    Schriftgröße: 16px;
    Schriftstärke: 400;
}
/* /Seiten/Index.razor.rz.scp.css */
h1[b-f3rb2cn7la] {
    Schriftgröße: 48px;
    Schriftstärke: fett;
}

Beim Betrachten des DOM-Elements im Browser sieht das Ergebnis wie folgt aus:

<h1 b-f3rb2cn7la>Hallo Welt!</h1>

<h1 b-g5zg69lne1>Zähler</h1>

Das heißt, dem DOM dieser beiden Komponenten wird ein Attribut hinzugefügt, das mit „b-“ plus 10 zufälligen Zeichen beginnt, was Angular zu ähneln scheint (ich habe es nicht verwendet, aber ich habe ähnliche Dinge in Browsern gesehen). Die CSS-Isolierung in Blazor scheint durch zufällige Eigenschaftsnamen erreicht zu werden. Wie sieht es also aus, wenn styles.css über ID und Klasse generiert wird? Dies wird auch durch zufällige Attributnamen erreicht. Beispielsweise die folgende Komponenten-CSS-Datei:

#zxyao-a {
    Schriftgröße: 48px;
    Schriftstärke: fett;
}

#zxyao-b {
    Schriftgröße: 24px;
    Schriftstärke: fett;
    Hintergrundfarbe: #ff0000;
    Polsterung: 16px;
}

.zxyao-cls {
    Schriftgröße: 24px;
    Schriftstärke: fett;
    Hintergrundfarbe: #000;
    Farbe: #fff;
    Polsterung: 16px;
}

Es wird in das folgende Ergebnis kompiliert:

/* /Seiten/Index.razor.rz.scp.css */
#zxyao-a[b-f3rb2cn7la] {
    Schriftgröße: 48px;
    Schriftstärke: fett;
}

#zxyao-b[b-f3rb2cn7la] {
    Schriftgröße: 24px;
    Schriftstärke: fett;
    Hintergrundfarbe: #ff0000;
    Polsterung: 16px;
}

.zxyao-cls[b-f3rb2cn7la] {
    Schriftgröße: 24px;
    Schriftstärke: fett;
    Hintergrundfarbe: #000;
    Farbe: #fff;
    Polsterung: 16px;
}

Die Ergebnisse sind wie folgt:

Das heißt, unabhängig davon, wie die Zusammenfassung der CSS-Komponentendatei geschrieben ist, wird sie in die Form eines CSS-Selektors [zufälliges Attribut] konvertiert.

4. Unterstützung für isolierte CSS-Unterkomponenten

Standardmäßig wird Komponenten-CSS nur auf die aktuelle Komponente angewendet. Es gibt beispielsweise zwei Komponenten:

/* Index.razor */
<div Klasse="mein-Text">
    Willkommen bei Ihrer neuen App.
    <CssIsolation.Komponenten.Kind />
</div>

/* Komponenten/Kind.razor */
<h1>Kind</h1>
<div Klasse="mein-Text">
    Dies ist eine untergeordnete Komponente</div>

Wenn der Stil in „Index.razor.css“ wie folgt ist,

.mein-text {
    Rand: 2px durchgezogen #000;
    Polsterung: 16px;
}

Dann funktioniert es nur für „Index.razor“ – der Rahmen erscheint auf der äußersten Indexkomponente.

Wenn Sie möchten, dass es mit dieser Komponente und ihrem Unterkomponentenelement „.my-text“ funktioniert, können Sie es mit „::deep“ markieren:

::deep .mein-text {
    Rand: 2px durchgezogen #000;
    Polsterung: 16px;
} 

Haben Sie festgestellt, dass der Rand von „.my-text“ dieser Komponente verschwunden ist? Wie bereits erwähnt, wird hier ::deep durch zufällige Attribute ersetzt, d. h. das Kompilierungsergebnis ist wie folgt:

/* /Seiten/Index.razor.rz.scp.css */
[b-f3rb2cn7la] .mein-text {
    Rand: 2px durchgezogen #000;
    Polsterung: 16px;
}

Unter diesen bezieht sich b-f3rb2cn7la auf das Stammelement dieser Komponente, wie in der Abbildung gezeigt.

Wenn es innerhalb dieser Gruppe kein eindeutiges übergeordnetes Element-Tag gibt, hat jedes native HTML-Tag innerhalb dieser Gruppe dieselben zufälligen Attribute. In der folgenden Komponente haben beispielsweise sowohl „div“ als auch „h1“ dieselben zufälligen Attribute und das Flag „::deep“ wird durch dieses Attribut ersetzt. Elemente in der „Child“-Komponente haben keine zufälligen Attribute.

<div Klasse="mein-Text">
    Willkommen bei Ihrer neuen App.
</div>
<h1>
    Willkommen bei Ihrer neuen App.
</h1>
<CssIsolation.Komponenten.Kind />

Einige Komponentenbibliotheken bieten Komponenten wie „Vorlage“, z. B. Ant Design Blazor. Wenn Sie Komponenten verwenden, um alle Elemente zu umschließen, z. B.:

<AntDesign.Vorlage>
    <div Klasse="mein-Text">
        Willkommen bei Ihrer neuen App.
        <CssIsolation.Komponenten.Kind />
    </div>
</AntDesign.Vorlage>

Blazor ignoriert die äußeren Komponenten, bis es das erste native HTML-Element in dieser Gruppe findet, und fügt dann allen nativen HTML-Elementen in dieser Ebene zufällige Attribute hinzu.

Wenn also das Stammelement dieser Komponente denselben CSS-Selektor hat wie das Element, dessen Unterkomponente den Stil festlegen muss, und Sie den Stil isolieren möchten, damit er sowohl auf diese Komponente als auch auf die Unterkomponente wirkt, gibt es zwei Möglichkeiten: Eine besteht darin, CSS-Stile für diese Gruppe und die Unterkomponente gleichzeitig zu schreiben, oder die andere darin, alle Komponenten und Elemente mit einem Element zu umschließen, d. h. das Stammelement zu ändern.

5. CSS-Präprozessor-Unterstützung

Häufig verwenden wir SCSS oder LESS, um Stildateien zu schreiben. Blazor unterstützt diese Präprozessoren nicht nativ. Wir können den Task Runner-Ressourcenmanager verwenden, um SCSS oder LESS zu kompilieren, bevor das Projekt generiert wird, oder einige Drittanbieterbibliotheken zur Unterstützung verwenden, wie z. B. das von Microsoft erwähnte Delegate.SassBuilder. Ich habe Delegate.SassBuilder ausprobiert. Vielleicht weil ich es falsch verwendet habe, schien die Generierung der CSS-Dateien später als die Projektgenerierung zu erfolgen, und die CSS-Dateien konnten bei der ersten Generierung des Programms nicht kompiliert werden. Als Nächstes werde ich eine andere Möglichkeit vorstellen, nämlich die Verwendung des „Task Runner Explorer“.

Hier habe ich einfach "node-sass" verwendet und es direkt über die Befehlszeile kompiliert, ohne erweiterte Tools wie Gulp oder Webpack zu verwenden. Die Lösungsschritte sind wie folgt (auf die Installation von node-sass wird hier nicht eingegangen):

Laden Sie die Erweiterung „Command Task Runner“ herunter und installieren Sie sie

Schreiben Sie das SCSS-Dateikompilierungs-Befehlszeilenprogramm „scss.bat“

Erstellen Sie eine neue scss.bat-Datei im Stammverzeichnis des Projekts:

Und schreiben Sie den folgenden Befehl.

node-sass -r ./ -o ./ --source-map true --source-map-contents sass --output-style komprimiert

Dieser Befehl kompiliert die SCSS-Datei und generiert eine komprimierte CSS-Datei und eine entsprechende Quellzuordnungsdatei.

Bat-Datei zum Task Runner hinzufügen

Klicken Sie mit der rechten Maustaste auf die Datei scss.bat und wählen Sie die Option „Zu Task Runner hinzufügen“.

Bind Run Task

Öffnen Sie Ansicht | Andere Fenster | Task Runner Explorer, suchen Sie den scss-Befehl, klicken Sie mit der rechten Maustaste und wählen Sie Bindung | Vor Generierung. Nach der Bindung können Sie den Befehl unter Vor Generierung im Bindungsfenster auf der rechten Seite sehen.

Nach dem Aktivieren des Task-Runners wird im Lösungsverzeichnis eine Datei „commands.json“ generiert. Der Inhalt meiner Datei ist wie folgt. Die Option „-vs-binding“ gibt den Speicherort der Laufzeit der Taskbindung an.

{
  "Befehle": {
    "scss": {
      "Dateiname": "cmd.exe",
      "Arbeitsverzeichnis": ".",
      "Argumente": "/c scss.bat"
    }
  },
  "-vs-binding": { "Vor dem Erstellen": [ "scss" ] }
}

Führen Sie das Programm anschließend einfach direkt aus, um die Wirkung zu sehen.

Natürlich können wir in SCSS auch das Tag "::deep" verwenden, das auch korrekt angezeigt werden kann, zum Beispiel:

/* Seiten/Index.razor.scss */
.mein-text {
    Rand: 2px durchgezogen #000;
    Polsterung: 16px;

    ::tief {
           .mein-text {
            Rand: 2px durchgezogen #ff0000;
            Hintergrundfarbe: #000;
            Farbe: #fff;
        }
    }
}

/* Komponenten/Child.razor.scss */
h1 {
    Hintergrundfarbe: #efefef;
    Schriftstärke: 700;
}

Die entsprechenden Razor-Komponenten sind wie folgt:

/* Seiten/Index.razor */
@Seite "/"

<div Klasse="mein-Text">
    Willkommen bei Ihrer neuen App.
    <CssIsolation.Komponenten.Kind />
</div>

/* Komponenten/Kind.razor */
<h1>Kind</h1>
<div Klasse="mein-Text">
    Dies ist eine untergeordnete Komponente</div>

Der Operationseffekt ist wie folgt:

Ich persönlich finde jedoch, dass die Verwendung des Tags „::deep“ in SCSS etwas verwirrend sein kann. Es wird empfohlen, das Tag „::deep“ entweder nicht zu verwenden oder das Tag „::deep“ auf der äußersten Ebene zu platzieren, wie unten gezeigt.

// Etwas SCSS-Styling-Code …


::tief {
	// Einige SCSS-Stilcodes für Unterkomponenten ...
}


// Etwas SCSS-Styling-Code …

6. Ändern Sie die zufällige Attributidentifikation

Wie bereits erwähnt, beginnt die Standardform der von Blazor generierten zufälligen Attributnamen mit „b-“ plus 10 zufälligen Zeichen. Die offizielle Dokumentation von Microsoft zeigt, dass dies geändert werden kann. Dies ist benutzerfreundlicher für ihre eigenen Anwendungen. Xiaomi kann beispielsweise die zufällige Attributform so definieren, dass sie mit „mi“ beginnt, Taobao kann die zufällige Attributform so definieren, dass sie mit „tb“ beginnt, und so weiter. Allerdings scheint es bei dieser Funktion Probleme zu geben. Jemand hat auf Github ein Problem gemeldet: „Custom CSS Scope Identifier funktioniert nicht.“ Ich hoffe, Blazor kann immer perfekter werden.

Dies ist das Ende dieses Artikels über CSS-Isolierung in Blazor. Weitere Informationen zur CSS-Isolierung in Blazor finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

<<:  Beispiel für die Zuweisung von Werten zu ActiveX-Steuerelementeigenschaften anhand des Parameternamens in einer Webseite

>>:  So legen Sie eine horizontale Navigationsstruktur in HTML fest

Artikel empfehlen

So nutzen Sie die Multi-Core-CPU in node.js voll aus

Inhaltsverzeichnis Überblick So nutzen Sie die Mu...

Implementierung des Imports und Exports von Vue-Element-Admin-Projekten

vue-element-admin importiert Komponentenkapselung...

So generieren Sie ein kostenloses Zertifikat mit OpenSSL

1: Was ist OpenSSL? Welche Funktion hat es? Was i...

Zwei Beispiele für die Verwendung von Symbolen in Vue3

Inhaltsverzeichnis 1. Verwenden Sie SVG 2. Verwen...

So implementieren Sie ein responsives Layout in Vue-CLI

Wenn wir Frontend-Entwicklung betreiben, werden w...

Grafisches Tutorial zur Installation und Konfiguration von MySQL 5.7.19 (Win10)

Detailliertes Tutorial zum Herunterladen und Inst...

So erstellen Sie Benutzer und verwalten Berechtigungen in MySQL

1. So erstellen Sie einen Benutzer und ein Passwo...

Detaillierte Beispiele zur Ajax-Verwendung in js und jQuery

Inhaltsverzeichnis Natives JS So senden Sie eine ...

So vergessen Sie das Passwort von Jenkins in Linux

1. Jenkins-Installationsschritte: https://www.jb5...

Vue-Projekt @change mehrere Parameter, um mehrere Ereignisse zu übergeben

Erstens gibt es nur ein Änderungsereignis. change...

Mit CSS3 3D-Effekten einen Würfel erstellen

Wenn wir lernen, die 3D-Effekte von CSS3 zum Erst...