Defensives HTML und CSS | WDD

Wenn es darum geht, im DOM eines anderen zu rendern, können Sie nicht einfach HTML und CSS schreiben, wie Sie es für Ihre eigene eigenständige Webanwendung tun würden. Sie müssen sorgfältig darüber nachdenken, wie sich bereits vorhandener CSS- und JavaScript-Code auf Ihre Anwendung auswirken könnte.

Bevor Sie mit dem Schreiben von HTML oder CSS beginnen, müssen Sie eine wichtige Entscheidung hinsichtlich des Erscheinungsbilds Ihrer Anwendung treffen. Möchten Sie, dass Ihre Bewerbung überall gleich aussieht? Oder möchten Sie, dass die Anwendung das native Erscheinungsbild der Seite übernimmt, auf der sie gehostet wird? Ihre Antwort wird einen tiefgreifenden Einfluss auf Ihre Strategie zum Rendern Ihrer App haben.

Eines ist jedoch immer gleich: Ab einem bestimmten Level werden Sie das üben, was wir defensives Rendering nennen. Unter „defensiv“ verstehen wir das Ergreifen von Maßnahmen zur Ausgabe von HTML und CSS, die die Auswirkungen der übergeordneten Seite auf Ihre Anwendung minimieren. Je weniger Ihr Widget von der übergeordneten Seite beeinflusst werden soll, desto mehr Schritte müssen Sie unternehmen. Diese Schritte können so klein sein wie die Namensgebung Ihres HTML- und CSS-Codes, um Namenskonflikte zu reduzieren, oder die Überspezifikation Ihrer CSS-Regeln, sodass diese Vorrang vor den Regeln der übergeordneten Seite haben. Für Widgets, die eine vollständige Immunität gegenüber der übergeordneten Seite wünschen, könnte dies auch bedeuten, dass Sie Ihr Widget in einem völlig separaten DOM bereitstellen, eingebettet in einen Iframe.

Wir konzentrieren uns auf die Darstellung von HTML und CSS, die sich im selben DOM befinden wie die Seite des Herausgebers. Für Widgets, die ein gewisses Maß an Individualisierung bieten sollen, kann dies für Herausgeber die flexibelste Lösung sein, da der Herausgeber Ihre Elemente problemlos gezielt auswählen und nach seinen Wünschen gestalten kann.

Das ist leider auch der Nachteil. Der Herausgeber könnte unwissentlich über CSS-Regeln und/oder JavaScript-Code verfügen, die unbeabsichtigt auf Ihr Widget abzielen und Chaos anrichten.

Wir werden verschiedene Möglichkeiten untersuchen, wie Sie den HTML- und CSS-Code Ihrer Anwendung vor dem Code des Herausgebers schützen können. Zunächst erfahren Sie etwas über HTML- und CSS-Namespaces. Anschließend erfahren Sie mehr über die CSS-Spezifität und wie die Stile der übergeordneten Seite Ihre eigenen überschreiben können.

Abschließend lernen Sie Techniken kennen, um die übergeordneten Stile der Seite außer Kraft zu setzen, indem Sie Ihr CSS zu stark spezifizieren und das Schlüsselwort !important missbrauchen. Zunächst einmal Namespaces.

Namensräume

Allen DOM-IDs, Klassen, data-*-Attributen und passenden CSS-Selektoren wurde stork- vorangestellt. Der Zweck? Um die Wahrscheinlichkeit zu verringern, dass diese Attribute mit der übergeordneten Seite in Konflikt geraten.

Betrachten Sie die folgende Situation. Ihr Widget verfügt über ein

-Element der obersten Ebene, das als Container fungiert. Dazu wird eine explizite Breite und Höhe festgelegt, wodurch der von Ihrem Widget eingenommene Bereich effektiv begrenzt wird. Sie haben diesem

einen einfachen Klassennamen, Container, gegeben, der einer Stilregel in Ihrem begleitenden CSS entspricht:


.container { width: 200px; Höhe: 200px; }

Das mag für eine normale Anwendung, die man zu Hause bleiben möchte, vollkommen angemessen sein, aber für eine Drittanbieter-App ist das ein absolutes No-Go. Der Grund? Ein solcher generischer Klassenname hat eine gute Chance, dass er bereits von der übergeordneten Seite verwendet wird. Wenn Sie diese Stilregel einführen, überschreiben Sie möglicherweise eine bestehende, vom Herausgeber eingerichtete Stilregel und ruinieren das Layout der Website. Oder es könnte umgekehrt sein, dass ihre Regel die Ihre außer Kraft setzt und die Größe Ihres Widgets unbeabsichtigt ändert.

Die Lösung? Stellen Sie allen Ihren Klassennamen (und anderen Attributen) einen für Ihre Anwendung eindeutigen Bezeichner voran – einen Namespace. Im Fall des Stork-Widgets sollte das bisherige Markup so geändert werden, dass es wie folgt aussieht:


.stork-container { width: 200px; Höhe: 200px }

Die Idee besteht darin, Ihrem JavaScript-Code einen Namensraum zu geben, damit Sie keine globalen Objekte deklarieren, die mit Code in Konflikt geraten, der auf der übergeordneten Seite ausgeführt wird. Es erstreckt sich auf jeden HTML-Teil, den Sie in die Seite einfügen: IDs, Klassen, data-*-Attribute, Formularnamen und so weiter.

Lesen:  Skalierung des Solarbetriebs: Softwarelösungen zur Bewältigung von Wachstum und Komplexität

Die Verwendung von HTML- und CSS-Namespaces ist ein Muss für jede Drittanbieteranwendung, die direkt auf der Seite des Herausgebers rendert. Dies ist nicht nur notwendig, um widersprüchliche CSS-Regeln zu verhindern; Es ist auch denkbar, dass die übergeordnete Seite über JavaScript verfügt, das das DOM nach Elementen abfragt, deren identifizierende Eigenschaften möglicherweise mit Ihren eigenen übereinstimmen. Seien Sie beim Namensraum für alles, was Sie in das DOM einfügen, streng.

CSS-Spezifität

Es ist wichtig zu beachten, dass die Festlegung von Namensräumen in Ihrem HTML und CSS zwar hilfreich ist, aber nur Fälle verhindert, in denen der Herausgeber Stile oder Abfragen verwendet, die auf Attribute mit demselben Namen wie Ihrem verweisen. Leider kann es immer noch zu Konflikten zwischen Ihrem Widget und den von der übergeordneten Seite definierten Stilen kommen, auch wenn deren CSS IDs, Klassennamen und Attribute verwendet, die nicht direkt auf Ihre Elemente verweisen. Dies liegt daran, dass einige CSS-Regeln vom Browser stärker gewichtet werden und Vorrang vor scheinbar nicht zusammenhängenden Regeln haben können, die Sie möglicherweise definieren. Dieses Phänomen wird als CSS-Spezifität bezeichnet und Sie müssen es verstehen, bevor Sie Elemente auf der Seite des Herausgebers sicher rendern können.

Kehren wir zum Containerbeispiel aus dem vorherigen Abschnitt über Namespaces zurück. Angenommen, der HTML-Code des Herausgebers verfügt über einen DIV der obersten Ebene, der den gesamten Inhalt umschließt, mit der ID Seite:

Nehmen wir außerdem an, die Seite verfügt über das folgende CSS, wobei die erste Regel vom Herausgeber definiert wird und die zweite Regel, die auf Stork-Container abzielt, von Ihrem Drittanbieter-Skript hinzugefügt wird:

/* Herausgeber */
#page div {
Hintergrundfarbe: grün;
}
/* Kamerastorch */
.stork-container {
Hintergrundfarbe: blau;
}

Welche Farbe wird nun der .stork-Container haben? Die Antwort könnte Sie schockieren und entsetzen: grün. In diesem einfachen Beispiel hat die Herausgeberregel (#page div) Vorrang vor der Klassenregel Ihrer Drittanbieteranwendung (.stork-container). Dies liegt daran, dass der Browser Regeln, die IDs enthalten, höher gewichtet als Regeln, die auf Klassen oder Attribute abzielen.

CSS-Regelprioritäten

Die W3C-CSS-Spezifikation beschreibt, wie Browser verschiedene Regeltypen priorisieren sollen. Hier ist eine Liste dieser Regeltypen, geordnet von der höchsten zur niedrigsten Priorität:

  1. Inline-Stile (style=”…”)
  2. Ausweise
  3. Klassen, Attribute und Pseudoklassen (:focus, :hover)
  4. Elemente (div, span usw.) und Pseudoelemente (:before, :after)

Gemäß dieser Tabelle werden Inline-Stile vor allen nachfolgenden Regeltypen gewichtet: IDs, Klassen und Elemente. Dies setzt sich logischerweise in der Liste fort, wobei IDs höher priorisiert werden als Klassen und Elemente usw. Es gibt eine Ausnahme von dieser Liste: Eigenschaften, die mit dem Schlüsselwort !important gekennzeichnet sind, haben höchste Priorität. Beachten Sie jedoch, dass sich das Schlüsselwort !important auf eine einzelne Eigenschaft innerhalb einer Regel auswirkt, nicht auf die gesamte Regel.

Was passiert, wenn Sie mehrere CSS-Regeln mit derselben Gewichtung haben, von denen jede möglicherweise dasselbe Element beeinflussen könnte? Schauen wir uns ein Beispiel an:

Iss dein Gemüse!


.stork-container { Hintergrundfarbe: blau; }
.stork-container span { Hintergrundfarbe: rot; }
.stork-container .stork-msg { Hintergrundfarbe: gelb; }

Welche Farbe hat die Spanne Ihrer Meinung nach? Auch hier könnte die Antwort überraschend sein: Gelb. Auch wenn diese Regeln alle in erster Linie klassenbasiert sind, gilt die zweite Regel (.storkcontainer span) als spezifischer als die erste Regel und die dritte Regel (.stork-container .stork-msg) als spezifischer als die zweite. Wie funktioniert das?

Inline-Stile sind König

Das heißt, was die CSS-Spezifität betrifft. Wenn Sie sich an früher in diesem Kapitel erinnern, haben wir erwähnt, dass Inline-Stile den Vorteil haben, dass sie selten mit der übergeordneten Seite in Konflikt geraten. Jetzt ist klar, warum: Sie haben Vorrang vor allen anderen Arten regulärer CSS-Regeln (mit Ausnahme derjenigen mit dem Schlüsselwort !important). Wenn Sie ein besonders einfaches Widget schreiben, ist es möglicherweise keine schlechte Idee, Inline-Stile zu verwenden; Sie vermeiden die meisten CSS-Spezifitätskonflikte.

Der Browser verwendet ein einfaches Bewertungssystem, um zu bestimmen, welche Regel Priorität hat. Für eine bestimmte Regel ist jeder Selektor, aus dem diese Regel besteht, einen bestimmten Wert wert. Diese Werte werden summiert, um einen Spezifitätswert zu erstellen. Wenn sich mehrere Regeln auf dasselbe Element auswirken, vergleicht der Browser die Spezifitätsbewertung jeder Regel und die Regel mit der höchsten Bewertung hat Priorität. Bei Gleichstand gewinnt die zuletzt festgelegte Regel. Inline-Stilattribute: 1000; IDs: 100; Klassen, Pseudoklassen und Attribute: 10, Elemente und Pseudoelemente: 1.

Lesen:  Wie man Agenturprozesse für Wachstum und Erfolg aufbaut

Wenn wir also auf unser vorheriges Beispiel zurückblicken, wären diesen CSS-Regeln die folgenden Bewertungen zugewiesen worden, wobei die Regel mit der höchsten Bewertung vom Browser priorisiert wurde: Sie werden schnell feststellen, dass es sich hierbei nicht um gewöhnliche Zahlen handelt. Ein Spezifitätswert ist eigentlich ein Tupel der Form (a, b, c, d), wobei a wertvoller als b, b wertvoller als c usw. ist. Das bedeutet, dass ein Stil, der durch ein einzelnes Inline-Stilattribut (1, 0, 0, 0) verursacht wird, eine höhere Spezifität aufweist als eine Regel mit hundert ID-Selektoren (0, 100, 0, 0).

  • .stork-container (0,0,1,0 – ein Klassenselektor)
  • .stork-container span (0,0,1,1 – ein Klassenselektor, ein Elementselektor)
  • .stork-container .stork-msg (0,0,2,0 – zwei Klassenselektoren)

An diesem Punkt sollten Sie einen guten Überblick darüber haben, wie die CSS-Spezifität funktioniert und warum der Browser einigen Regeln Vorrang vor anderen einräumt. Als Nächstes werden Sie dieses Wissen nutzen, indem wir einige Ansätze zum Schreiben von CSS untersuchen, das den widersprüchlichen Stilen von Verlagen standhält.

Überspezifizierung von CSS

Der erste und einfachste Ansatz zum Schreiben von CSS, das nicht in Konflikt mit der Seite des Herausgebers steht, besteht darin, Ihre Regeln zu spezifizieren. Das bedeutet, dass Sie zusätzliche Selektoren deklarieren müssen, um die Spezifität Ihrer Regeln zu erhöhen, sodass diese beim Vergleich Ihrer Regeln mit denen der übergeordneten Seite wahrscheinlich eine höhere Punktzahl erzielen und priorisiert werden.

Schauen wir uns das in der Praxis an. Betrachten Sie dieses überarbeitete Beispiel des Stork-Widget-Containers, der jetzt über zwei Containerelemente mit jeweils einer eindeutigen ID verfügt:

Mikon E90 Digitale Spiegelreflexkamera

http://camerastork.com/img/products/1337-small.png“/>

599 $

4,3/5,0 • 176 Bewertungen

Das zugehörige CSS für diesen HTML-Code könnte dann so aussehen:

#stork-main #stork-container { … }
#stork-main #stork-container .stork-product { … }
#stork-main #stork-container .stork-price { … }

Indem Sie beide Container-IDs redundant als übergeordnete Selektoren aller Ihrer CSS-Regeln angeben, geben Sie jeder Ihrer CSS-Regeln effektiv einen Mindestspezifitätswert von (0,2,0,0). Danach wird die generische #page-Regel des Herausgebers von früher nicht mehr mit Ihrem Widget in Konflikt geraten, da sie nur eine einzige ID verwendet. Auch rein klassen- oder elementbasierte Regeln stehen nicht im Widerspruch, da es sich hierbei um eine ganze CSS-Gewichtungsklasse unterhalb von IDs handelt. Auch wenn es für Auswahlzwecke völlig unnötig ist, eine zweite ID für Ihre Regeln anzugeben, dient sie hier als wirksames Mittel zur Steigerung der Spezifität.

Bewahren Sie Ihren Verstand mit einem CSS-Präprozessor

Das Schreiben von überspezifiziertem CSS kann eine echte Belastung sein: Sie müssen für jede Ihrer CSS-Regeln ständig dieselben IDs neu schreiben. Sie können Abhilfe schaffen, indem Sie einen CSS-Präprozessor verwenden, der die CSS-Sprache um zusätzliche Funktionen erweitert, beispielsweise die Möglichkeit, verschachtelte Regelhierarchien zu deklarieren. Mit dem LESS-CSS-Präprozessor könnten Sie beispielsweise das vorherige Beispiel wie folgt schreiben:

#stork-main {
#storch-container {
.stork-product { … }
.stork-price { … }
}
}

Heutzutage sind eine Reihe beliebter CSS-Präprozessoren verfügbar, die alle über unterschiedliche Funktionssätze verfügen. Zu den beliebtesten gehören WENIGER, Sass, Und Stift.

Auf der anderen Seite erfordert dieses Beispiel, dass Ihr Widget Container der obersten Ebene mit IDs verwendet, was für Widgets, die mehrmals auf derselben Seite gerendert werden können, nicht praktikabel ist. Darüber hinaus ist es immer noch nicht absolut sicher: Ein Herausgeber könnte Ihrem Beispiel folgen und seine eigenen CSS-Regeln zu stark spezifizieren, was zu demselben Problem führen würde, das Sie zuvor hatten.

Dies ist jedoch ein unwahrscheinliches Szenario, insbesondere da Sie in jeder Regel zwei IDs redundant angegeben haben. Alternativ können Sie auch eines verwenden, das ist dann aber natürlich anfälliger. Die Realität ist, dass die meisten Verlage vernünftige CSS-Regeln verwenden und eine solche Überspezifizierung Ihrer Regeln mit den meisten von ihnen kompatibel ist.

Eine übermäßige Spezifizierung von CSS lässt sich nicht mit Code-Qualitätstools vertragen

Wenn Sie dazu übergehen, Ihr CSS auf diese Weise zu spezifizieren, stoßen Sie möglicherweise auf einen unwahrscheinlichen Feind: Tools, die die Qualität Ihres CSS-Codes bewerten, wie CSS Lint, Google Page Speed ​​und YSlow von Yahoo. Diese Tools zeigen an, dass Sie überflüssige CSS-Selektoren erstellen, und raten Ihnen, solche Selektoren zu entfernen, um die Dateigröße zu reduzieren und die CSS-Leistung des Browsers zu verbessern. Leider sind diese Tools nicht für Skripte von Drittanbietern programmiert und bewerten den Nutzen einer übermäßigen Spezifikation von CSS nicht angemessen. Die Vorteile einer Überspezifikation für Anwendungen von Drittanbietern überwiegen die zusätzliche Dateigröße und die geringfügigen Leistungseinbußen.

Lesen:  Die 15 besten CSS-Frameworks: Professionelles Bootstrap und Foundation…

Missbrauch von !important

Wenn Sie der Meinung sind, dass die Überspezifizierung Ihres CSS mit zusätzlichen IDs oder Klassenselektoren nicht weit genug geht, können Sie die nukleare Option herausbrechen: das Schlüsselwort !important. Eigenschaften innerhalb einer CSS-Regel, die das Schlüsselwort !important enthalten, haben die höchste Priorität, sogar vor Inline-Stilen. Dies liegt daran, dass das Schlüsselwort !important entwickelt wurde, um Browser-Benutzern eine todsichere Möglichkeit zu bieten, „Autoren“-Stile (Herausgeber-Stile) im Fall von Browser-Plugins oder standortspezifischen Stilen zu überschreiben. Sie können !important missbrauchen, indem Sie es für alle Ihre CSS-Eigenschaften verwenden und ihnen so effektiv Vorrang vor allen anderen Regeln geben.

So können Sie das Schlüsselwort !important für eine einzelne CSS-Regel verwenden:

.stork-price {
Schriftgröße: 11px !important;
Farbe: #888 !important;
Textdekoration: keine !important;
Anzeige: block !important;
}

Da es pro Eigenschaft gilt, muss das Schlüsselwort !important auf diese Weise wiederholt werden, was bei einem langen und komplexen Stylesheet zu einer Belastung werden kann. Aber im Gegenzug erhalten Sie einen grundsoliden Satz an Stylesheets, die von der Seite des Herausgebers höchstwahrscheinlich nicht zurückgesetzt werden.

Es ist immer noch vorstellbar, dass der Herausgeber wiederum !important verwendet, um Ihre Elemente gezielt anzusprechen und eigene Stile festzulegen. Zu diesem Zeitpunkt zielt er wahrscheinlich gezielt auf Ihre Elemente zur Anpassung ab. Einerseits kann das frustrierend sein, wenn Sie versuchen, ein einheitliches Erscheinungsbild beizubehalten. Wenn Sie sich jedoch dafür entschieden haben, Publishern die Anpassung Ihres Widgets zu erlauben, ist dies wahrscheinlich ein gewünschtes Verhalten.

Eines sollte klar sein: Die gemeinsame Nutzung des DOM mit dem Herausgeber kann es besonders schwierig machen, ein Widget mit einheitlichem Stil zu rendern. Obwohl Sie Maßnahmen ergreifen können, um Ihre CSS-Regeln zu stark zu spezifizieren, um die Wahrscheinlichkeit von Konflikten zu verringern, ist es immer möglich, dass der Herausgeber versehentlich oder absichtlich Ihre Elemente mit seinen Regeln ins Visier nimmt.

Aber wenn die gemeinsame Nutzung des DOM mit dem Herausgeber so viel Kummer verursacht, ist es dann möglich, Ihr Widget außerhalb des DOM zu rendern? Warum, ja – ja, das kannst du.

Zusammenfassung

Bei einer JavaScript-Anwendung eines Drittanbieters erfordert das Einfügen von HTML und CSS in die Seite des Herausgebers mehr Sorgfalt, als wenn Sie Markup in einer „sicheren“ Umgebung hinzufügen würden. Sie müssen sicherstellen, dass Sie bei der Ausgabe von HTML auf der Seite die Seite nicht durch einen Blockierungsvorgang verlangsamen. Sie müssen auch bedenken, dass Ihr Skript möglicherweise mehrmals auf derselben Seite eingefügt wird und mehrere Instanzen ordnungsgemäß rendern sollten. Darüber hinaus sollten Sie eine optimale Methode zum Einfügen von CSS in die Seite des Herausgebers wählen – entweder durch Inlining aller Ihrer Stile, Anhängen von Linkelementen oder Einbetten von CSS-Regeln in Ihr JavaScript.

Es reicht jedoch nicht aus, nur HTML und CSS auf die Seite zu bringen. Sie müssen erkennen, dass Elemente, die Sie in das DOM einführen, mit der übergeordneten Seite in Konflikt geraten können. Sie müssen auch berücksichtigen, dass Ihre Stile möglicherweise mit vorhandenen, vom Herausgeber definierten Stilen in Konflikt geraten. Sie können eine Reihe von Techniken verwenden, um die Auswirkungen übergeordneter Stile auf Ihr Widget zu reduzieren: indem Sie Ihre CSS-Regeln zu stark spezifizieren oder Ihren Inhalt hinter einem Iframe präsentieren, unabhängig davon, ob es sich um einen Iframe ohne SRC handelt oder um einen, der ein externes HTML-Dokument enthält.

Welche Techniken verwenden Sie bei der Erstellung von CSS und HTML für Dritte? Greifen Sie jemals auf !important zurück? Lass es uns in den Kommentaren wissen.

Ausgewähltes Bild/Miniaturansicht, Verteidigungsbild über Shutterstock.

Aktuelle Artikel:

Empfohlen