Wenn es um das DOM von jemand anderem geht, können Sie HTML und CSS nicht so naiv schreiben, wie Sie es für Ihre eigene in sich geschlossene Webanwendung tun. 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 Erscheinungsbildes Ihrer Anwendung treffen. Möchten Sie, dass Ihre Anwendung überall gleich aussieht? Oder möchten Sie, dass die Anwendung das native Erscheinungsbild der Seite erbt, auf der sie gehostet wird? Ihre Antwort wird sich stark auf Ihre Strategie zum Rendern Ihrer App auswirken.

Eines ist konstant: Auf einer bestimmten Ebene werden Sie das üben, was wir als defensives Rendering bezeichnen. Mit defensiv meinen wir Schritte zur Ausgabe von HTML und CSS, die die Auswirkungen der übergeordneten Seite auf Ihre Anwendung minimieren. Je weniger Sie möchten, dass Ihr Widget von der übergeordneten Seite beeinflusst wird, desto mehr Schritte müssen Sie unternehmen. Diese Schritte können so klein sein wie Namespacing von HTML und CSS, um Namenskonflikte zu vermeiden, oder die CSS-Regeln überspezifizieren, so dass sie Vorrang vor Regeln von der übergeordneten Seite haben. Für Widgets, die vollständige Immunität von der übergeordneten Seite wünschen, könnte es auch bedeuten, dass Sie Ihr Widget auf einem vollständig separaten DOM, eingebettet in einen Iframe, bereitstellen.

Wir konzentrieren uns auf das Rendern von HTML und CSS, die auf demselben DOM wie die Publisher-Seite gespeichert sind. Für Widgets, die ein gewisses Maß an Individualisierung bieten sollen, kann dies die flexibelste Lösung für Publisher sein, da der Publisher Ihre Elemente einfach anvisieren und nach ihren Vorlieben gestalten kann.

Leider ist dies auch der Nachteil. Der Publisher könnte unwissentlich CSS-Regeln und / oder JavaScript-Code haben, die unbeabsichtigt auf Ihr Widget abzielen und Chaos verursachen.

Wir sehen uns verschiedene Möglichkeiten an, um den HTML- und CSS-Code Ihrer Anwendung vor dem Code des Publishers zu schützen. Zunächst lernen Sie HTML- und CSS-Namespaces kennen. Anschließend lernen Sie die CSS-Spezifität kennen und wie die Stile der übergeordneten Seite Ihre eigenen überschreiben können.

Schließlich lernen Sie Techniken zum Überschreiben der übergeordneten Stile der Seite, indem Sie Ihr CSS überspezifizieren und das Schlüsselwort! Important missbrauchen. Zuerst, Namespaces.

Namespaces

Alle DOM-IDs, -Klassen, -Data- * -Attribute und übereinstimmenden CSS-Selektoren wurden mit Storch vorangestellt. Die Absicht? Um die Wahrscheinlichkeit zu reduzieren, dass diese Attribute in Konflikt mit der übergeordneten Seite stehen.

Betrachten Sie die folgende Situation. Ihr Widget hat eine Top-Level

Element, das als Container fungiert. Dies erfolgt durch Festlegen einer expliziten Breite und Höhe, wodurch der von Ihrem Widget eingenommene Bereich effektiv begrenzt wird. Du hast das gegeben
ein einfacher Klassenname, Container, der einer Stilregel in Ihrem begleitenden CSS entspricht:

...

Dies ist möglicherweise für eine normale Anwendung zu Hause angemessen, aber für eine App von Drittanbietern ist es ein komplettes No-No. Der Grund? Ein solcher generischer Klassenname hat eine gute Chance, bereits von der übergeordneten Seite verwendet zu werden. Wenn Sie diese Stilregel einführen, überschreiben Sie möglicherweise eine vorhandene Stilregel, die vom Publisher eingerichtet wurde, und ruinieren deren Website-Layout. Oder, auf der anderen Seite, könnte ihre Regel Ihre eigenen überschreiben und Ihr Widget versehentlich verändern.

Die Lösung? Voreinstellen aller Klassennamen (und anderer Attribute) mit einem für Ihre Anwendung eindeutigen Bezeichner - einem Namespace. Im Falle des Stork-Widgets sollte das vorherige Markup wie folgt aussehen:

...

Die Idee ist, dass Sie Ihren JavaScript-Code mit einem Namespace versehen, damit Sie keine globalen Objekte deklarieren, die mit dem auf der übergeordneten Seite ausgeführten Code in Konflikt stehen. Es erstreckt sich auf jedes HTML-Element, das Sie in die Seite einfügen: IDs, Klassen, Daten- * -Attribute, Formularnamen und so weiter.

Namespacing HTML und CSS ist ein Muss für alle Anwendungen von Drittanbietern, die direkt auf der Publisher-Seite gerendert werden. Dies ist nicht nur notwendig, um widersprüchliche CSS-Regeln zu vermeiden. Es ist auch denkbar, dass die übergeordnete Seite über JavaScript verfügt, das das DOM nach Elementen abfragt, deren identifizierende Eigenschaften mit Ihren eigenen übereinstimmen. Seien Sie streng bei der Namespacering alles, was Sie auf das DOM setzen.

CSS-Spezifität

Beachten Sie, dass das Namespacing von HTML und CSS nur dann hilfreich ist, wenn der Publisher Stile oder Abfragen verwendet, die auf Attribute mit demselben Namen verweisen wie Sie. Leider kann Ihr Widget immer noch Konflikte mit Stilen verursachen, die auf der übergeordneten Seite definiert sind, selbst wenn das 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 verwandten Regeln haben, die Sie möglicherweise definieren. Dieses Phänomen wird als CSS-Spezifität bezeichnet. Sie müssen es verstehen, bevor Sie Elemente auf der Publisher-Seite sicher rendern können.

Gehen wir zurück zum Container-Beispiel aus dem vorherigen Abschnitt über Namespaces. Angenommen, der HTML-Code des Publishers enthält ein DIV auf oberster Ebene, das den gesamten Inhalt mit einer ID der Seite umschließt:

...
...

Angenommen, die Seite enthält das folgende CSS, wobei die erste Regel vom Publisher definiert wird und die zweite Regel, Targeting stork-container, von Ihrem Drittanbieterskript hinzugefügt wird:

/* Publisher */#page div {background-color: green;}/* Camera Stork */.stork-container {background-color: blue;}

Nun, welche Farbe wird .stork-container haben? Die Antwort könnte dich schockieren und erschrecken: grün. In diesem einfachen Beispiel hat die Publisher-Regel (#page div) Vorrang vor der Klassenregel der Drittanbieteranwendung (.stork-container). Dies geschieht, weil der Browser Regeln abwägt, die höhere IDs enthalten als solche, 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, die von der höchsten Priorität bis zur niedrigsten Priorität angeordnet sind:

  1. Inline-Stile (Stil = "...")
  2. IDs
  3. Klassen, Attribute und Pseudoklassen (: focus,: hover)
  4. Elemente (div, span, usw.) und Pseudo-Elemente (: before,: after)

Gemäß diesem Diagramm werden Inline-Stile über alle folgenden Regeltypen abgewogen: IDs, Klassen und Elemente. Dies setzt die Liste logisch fort, wobei IDs höher priorisiert werden als Klassen und Elemente und so weiter. Es gibt eine Ausnahme zu dieser Liste: Eigenschaften, die mit dem Schlüsselwort! Important gekennzeichnet sind, haben die höchste Priorität. Beachten Sie jedoch, dass sich das Schlüsselwort! Wichtig auf eine einzelne Eigenschaft innerhalb einer Regel und nicht auf die gesamte Regel auswirkt.

Was passiert, wenn Sie mehrere CSS-Regeln mit demselben Gewicht haben, von denen jedes das gleiche Element betreffen könnte? Schauen wir uns ein Beispiel an:

Eat your vegetables!

Was denkst du, ist die Farbe der Spannweite? Die Antwort könnte wieder überraschend sein: Gelb. Obwohl diese Regeln alle primär klassenbasiert sind, wird die zweite Regel (.storkcontainer span) als spezifischer als die erste Regel und die dritte Regel (.stork-container .stork-msg) als spezifischer als die zweite betrachtet. Wie funktioniert das?

Inline-Stile sind König

Im Hinblick auf die CSS-Spezifität. Wenn Sie sich an früher in diesem Kapitel erinnern, haben wir erwähnt, dass Inline-Stile den Vorteil haben, selten in Konflikt mit der übergeordneten Seite zu kommen. Jetzt ist klar, warum: Sie haben Vorrang vor allen anderen regulären CSS-Regeln (ausgenommen solche mit dem Schlüsselwort! Wichtig). Wenn Sie ein besonders einfaches Widget schreiben, ist es möglicherweise keine schlechte Idee, eingebettete 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 erhalten. Wenn mehrere Regeln dasselbe Element betreffen, vergleicht der Browser die Spezifitätswerte jeder Regel, und die Regel mit der höchsten Punktzahl hat Priorität. Bei einem Gleichstand gewinnt die zuletzt definierte Regel. Inline-Stilattribute: 1000; IDs: 100; Klassen, Pseudoklassen und Attribute: 10, Elemente und Pseudoelemente: 1.

Wenn wir also auf unser vorheriges Beispiel zurückgehen, hätten diese CSS-Regeln die folgenden Punktzahlen erhalten, wobei die Regel mit der höchsten Punktzahl vom Browser priorisiert wurde: Sie werden schnell feststellen, dass es sich nicht um gewöhnliche Zahlen handelt. Ein Spezifitätswert ist eigentlich ein Tupel der Form (a, b, c, d), wobei ein Wert mehr wert ist als b, b wertvoller ist als c und so weiter. 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 einhundert 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 dieser Stelle sollten Sie einen guten Überblick darüber haben, wie CSS-Spezifität funktioniert und warum der Browser einige Regeln gegenüber anderen priorisiert. Sie werden dieses Wissen als nächstes nutzen, wenn wir einige Ansätze für das Schreiben von CSS erforschen, die sich gegen widersprüchliche Publisher-Stile behaupten.

Überspezifizieren von CSS

Der erste und einfachste Ansatz zum Schreiben von CSS, der nicht mit der Seite des Publishers in Konflikt steht, besteht darin, die Regeln zu überspezifizieren. Das bedeutet, dass Sie zusätzliche Selektoren deklarieren müssen, um die Spezifität Ihrer Regeln zu erhöhen. Wenn der Browser Ihre Regeln mit denen der übergeordneten Seite vergleicht, werden sie wahrscheinlich höher bewertet und priorisiert.

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

Mikon E90 Digital SLR

"/>

599 $

4.3 / 5.0 • 176 Bewertungen

Das zugehörige CSS für dieses HTML 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 als übergeordnete Selektoren aller Ihrer CSS-Regeln redundant angeben, geben Sie effektiv jeder Ihrer CSS-Regeln eine Mindestspezifität von (0,2,0,0). Danach steht die allgemeine #page-Regel des Publishers von früher nicht mehr in Konflikt mit Ihrem Widget, da nur eine einzige ID verwendet wird. Auch werden keine rein klassen- oder elementbasierten Regeln in Konflikt geraten, da es sich um eine gesamte CSS-Gewichtsklasse unterhalb von IDs handelt. Auch wenn es für Auswahlzwecke völlig unnötig ist, eine zweite ID für Ihre Regeln anzugeben, funktioniert es hier als effektives Mittel zur Erhöhung der Spezifität.

Bewahre deine Gesundheit mit einem CSS-Präprozessor

Das Schreiben überspezifizierter CSS kann ein echter Nachteil sein: Sie müssen die gleichen IDs für jede Ihrer CSS-Regeln immer wieder neu schreiben. Sie können dies beheben, indem Sie einen CSS-Präprozessor verwenden, der die CSS-Sprache um zusätzliche Funktionen wie die Möglichkeit, verschachtelte Hierarchien von Regeln zu deklarieren, erweitert. Wenn Sie zum Beispiel den CSS-Präprozessor LESS verwenden, können Sie das vorherige Beispiel wie folgt schreiben:

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

Eine Reihe von gängigen CSS-Präprozessoren ist heute verfügbar, die alle unterschiedliche Feature-Sets haben. 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 auf derselben Seite mehrfach gerendert werden können, nicht praktisch ist. Außerdem ist es immer noch nicht kugelsicher: Ein Publisher könnte Ihrem Beispiel folgen und seine eigenen CSS-Regeln überspezifizieren, was zu dem gleichen Problem führt, das Sie zuvor hatten.

Dies ist jedoch ein unwahrscheinliches Szenario, zumal Sie in jeder Regel zwei IDs redundant angegeben haben. Du könntest alternativ eins benutzen, aber das wird natürlich anfälliger sein. Die Realität ist, dass die meisten Publisher vernünftige CSS-Regeln verwenden, und eine Überspezifizierung Ihrer Regeln wird mit den meisten kompatibel sein.

Überspezifizierendes CSS wird nicht mit Codequalitätswerkzeugen kombiniert

Wenn Sie Ihr CSS so überspezifizieren, finden Sie vielleicht einen unwahrscheinlichen Gegner: Werkzeuge, die die Qualität Ihres CSS-Codes bewerten, wie CSS Lint, Google Page Speed ​​und Yahoo YSlow. Diese Tools zeigen an, dass Sie redundante CSS-Selektoren erstellen. Sie werden Ihnen raten, solche Selektoren zu entfernen, um die Dateigröße zu reduzieren und die CSS-Leistung der Browser zu verbessern. Leider sind diese Tools nicht mit Skripten von Drittanbietern programmiert und bewerten die Nützlichkeit der Überspezifizierung von CSS nicht angemessen. Die Vorteile der Überspezifizierung für Anwendungen von Drittanbietern werden die zusätzliche Dateigröße und den minimalen Leistungseinbruch überwiegen.

Missbrauch wichtig!

Wenn Sie der Meinung sind, dass die Überspezifizierung Ihres CSS mit zusätzlichen IDs oder Klassenselektoren nicht weit genug geht, können Sie die Kernoption ausbrechen: das Schlüsselwort! Eigenschaften innerhalb einer CSS-Regel, die das Schlüsselwort! Important aufweisen, werden am höchsten priorisiert, sogar über Inline-Stilen. Dies liegt daran, dass das! Keyword-Schlüsselwort dazu entwickelt wurde, Browserbenutzern eine sichere Möglichkeit zu geben, "Author" -Stile (Publisher-Stile) zu überschreiben, im Fall von Browser-Plugins oder standortspezifischen Stilen. Sie können sie missbrauchen, indem Sie sie für alle Ihre CSS-Eigenschaften verwenden und sie gegenüber allen anderen Regeln priorisieren.

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

.stork-price {font-size: 11px !important;color: #888 !important;text-decoration: none !important;display: block !important;}

Da es sich um eine Property handelt, muss das! Keyword-Schlüsselwort wie folgt wiederholt werden, was sich über ein langes und komplexes Stylesheet hinwegzieht. Im Gegenzug erhalten Sie jedoch eine Reihe von Stylesheets, die sehr wahrscheinlich nicht auf der Publisher-Seite zurückgesetzt werden.

Es ist immer noch vorstellbar, dass der Publisher im Gegenzug wichtige Elemente für die Ausrichtung Ihrer Elemente verwenden und eigene Stile festlegen kann. Ab diesem Zeitpunkt richten sie sich wahrscheinlich gezielt auf Ihre Elemente aus, um sie anzupassen. Auf der einen Seite kann das frustrierend sein, wenn Sie versuchen, ein einheitliches Erscheinungsbild zu erhalten. Wenn Sie jedoch festgelegt haben, dass Publisher Ihr Widget anpassen können, ist dies wahrscheinlich das gewünschte Verhalten.

Eines sollte klar sein: Wenn Sie das DOM mit dem Publisher teilen, kann es besonders schwierig sein, ein konsistent gestyltes Widget zu rendern. Obwohl Sie Ihre CSS-Regeln überspezifizieren können, um die Wahrscheinlichkeit von Konflikten zu verringern, ist es für den Publisher immer möglich, Ihre Elemente entweder versehentlich oder absichtlich mit ihren Regeln zu targeten.

Aber wenn das Teilen des DOM mit dem Publisher so viel Kummer verursacht, ist es möglich, das Widget vom DOM zu entfernen? Warum, ja - ja, du kannst.

Zusammenfassung

Für eine JavaScript-Anwendung von Drittanbietern ist das Einbetten von HTML- und CSS-Code auf die Publisher-Seite mit mehr Sorgfalt verbunden als das Hinzufügen von Markup zu einer "sicheren" Umgebung. Sie müssen sicherstellen, dass Sie bei der Ausgabe von HTML auf die Seite die Seite nicht mit einer blockierenden Operation verlangsamen. Sie müssen auch berücksichtigen, dass Ihr Skript möglicherweise mehrmals auf derselben Seite enthalten ist und mehrere Instanzen ordnungsgemäß gerendert werden sollten. Darüber hinaus sollten Sie eine optimale Methode zum Einbetten von CSS in die Publisher-Seite auswählen, indem Sie entweder alle Stile inline einfügen, Verknüpfungselemente anhängen oder CSS-Regeln in Ihr JavaScript einbetten.

Aber nur HTML und CSS auf der Seite zu bekommen ist nicht genug. Sie müssen erkennen, dass Elemente, die Sie in das DOM einführen, Konflikte mit der übergeordneten Seite verursachen können. Sie müssen auch berücksichtigen, wie Ihre Stile möglicherweise mit vorhandenen vom Publisher definierten Stilen in Konflikt stehen. Sie können eine Reihe von Techniken einsetzen, um die Auswirkungen von übergeordneten Stilen auf Ihr Widget zu reduzieren: indem Sie Ihre CSS-Regeln überspezifizieren oder Ihren Inhalt hinter einem iframe präsentieren, egal ob es sich um einen src-losen iframe oder einen externen HTML-Dokument handelt.

Welche Techniken verwenden Sie, wenn Sie CSS und HTML für Dritte erstellen? Fällt du jemals wieder darauf, wichtig? Lassen Sie es uns in den Kommentaren wissen.

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