När det gäller att göra på någon annans DOM, kan du inte naivt skriva HTML och CSS som du kan för din egen fristående webbapplikation. Du måste tänka noggrant om hur existerande CSS och JavaScript-kod kan påverka din ansökan.

Innan du börjar skriva HTML eller CSS måste du göra ett viktigt beslut angående utseende och känsla för din ansökan. Vill du att din ansökan ska se ut överallt? Eller vill du att programmet ska få det inhemska utseendet på den sida där den är värd? Ditt svar kommer att få en djupgående effekt på din strategi för att göra din app.

En sak är konstant: På något sätt övar du vad vi kallar defensiv återgivning. Med defensiv menar vi att vidta åtgärder för att mata ut HTML och CSS som minimerar effekten av föräldersidan på din ansökan. Ju mindre du vill att din widget påverkas av föräldrasidan, desto steg du måste ta. Dessa steg kan vara så små som namespacing din HTML och CSS för att minska namnkonflikter, eller överspecifiera dina CSS-regler så att de prioriterar över regler från föräldersidan. För widgets som vill ha fullständig immunitet från modersidan kan det också innebära att din widget används på en helt separat DOM, inbäddad i en iframe.

Vi kommer att fokusera på att göra HTML och CSS som lever på samma DOM som utgivarens sida. För widgets som syftar till att erbjuda en viss anpassningsnivå kan detta vara den mest flexibla lösningen för utgivare, eftersom utgivaren enkelt kan rikta in sig på dina element och anpassa dem till sina önskemål.

Tyvärr är detta också nackdelen. Utgivaren kunde utan tvekan ha CSS-regler och / eller JavaScript-kod som oavsiktligt inriktar på din widget och orsakar kaos.

Vi tittar på ett antal sätt att skydda programmets HTML och CSS från utgivarens kod. Först lär du dig om HTML och CSS namnområden. Därefter kommer du att lära dig om CSS-specificitet, och hur föräldrars sidans stilar kan överdriva din egen.

Slutligen lär du dig tekniker för att överdriva sidans överordnade stilar, genom att överspecificera din CSS och missbruka det viktiga sökordet. Först upp namnområden.

namnrymder

Alla DOM-ID, klasser, data- * attribut och matchande CSS-selektorer har prefixats med stork-. Syftet? För att minska sannolikheten för att dessa attribut strider mot föräldersidan.

Tänk på följande situation. Din widget har en toppnivå

element som fungerar som en behållare Det gör det genom att ange en explicit bredd och höjd, vilket effektivt begränsar det område som tas upp av din widget. Du har gett detta
ett enkelt klassnamn, behållare, som matchar en stilregel i din medföljande CSS:

...

Det här kan vara perfekt för en vanlig vistelse-hemma-applikation, men för en tredje part är det ett komplett nej-nr. Anledningen? Ett sådant generiskt klassnamn har en bra chans att redan används av föräldersidan. Om du introducerar denna stilregel kan du åsidosätta en befintlig stilregel som utgivits av förlaget och förstöra deras webbplatslayout. Eller, på sidan, kan deras regel åsidosätta dina och ändra storlek på din widget oavsiktligt.

Lösningen? Förkodning av alla dina klassnamn (och andra attribut) med en identifierare som är unik för din ansökan - en namnrymd. När det gäller Stork-widgeten, måste den tidigare markeringen ändras så att den ser ut så här:

...

Tanken är att du namespace din JavaScript-kod så att du inte deklarerar globala objekt som stämmer överens med kod som körs på modersidan. Den sträcker sig till varje bit av HTML som du lägger in på sidan: ID, klasser, data- * attribut, formulärnamn och så vidare.

Namnrymd HTML och CSS är ett måste för alla program från tredje part som gör direkt till utgivarens sida. Detta är inte bara nödvändigt för att förhindra motstridiga CSS-regler. det är också tänkbart att föräldersidan har JavaScript som frågar DOM för element vars identifierande egenskaper kan matcha din egen. Var noggrann i namespacing allt du lägger på DOM.

CSS-specificitet

Det är viktigt att notera att, men användbart, namespacing din HTML och CSS förhindrar endast fall där utgivaren använder stilar eller frågor som referensattribut med samma namn som din. Tyvärr kan din widget fortfarande störa mot stilar som definieras av föräldrasidan, även om deras CSS använder ID, klassnamn och attribut som inte direkt hänvisar till dina element. Detta beror på att vissa CSS-regler vägs tyngre av webbläsaren och kan ha företräde framför till synes obeslända regler som du kan definiera. Detta fenomen kallas CSS-specificitet, och du måste förstå det innan du säkert kan göra element på utgivarens sida.

Låt oss gå tillbaka till behållarens exempel från föregående avsnitt om namnområden. Antag att utgivarens HTML har en toppnivå DIV som bryter in hela sitt innehåll, med ett ID-nummer:

...
...

Låt oss dessutom säga att sidan har följande CSS, där den första regeln är definierad av utgivaren, och den andra regeln, som riktar sig mot storkonservat, läggs till av ditt tredjepartsskript:

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

Nu, vilken färg kommer .Stork-Container? Svaret kan chocka och skämma dig: grön. I det här enkla exemplet prioriterar utgivarregeln (#page div) över din tredjepartsprograms klassregel (.stork-container). Detta händer eftersom webbläsaren väger regler som innehåller ID-nummer högre än de som är inriktade på klasser eller attribut.

CSS-regelprioriteringar

W3C CSS-specifikationen beskriver hur webbläsare är avsedda att prioritera olika regeltyper. Här är en lista över dessa regeltyper, beställda från högsta prioritet till lägsta:

  1. Inline-stilar (style = "...")
  2. ID
  3. Klasser, attribut och pseudoklasser (: fokus,: svävar)
  4. Element (div, span, och så vidare) och pseudo-element (: före, efter)

Enligt detta diagram vägs inlinestilar över alla efterföljande regeltyper: ID, klasser och element. Detta fortsätter logiskt ner i listan, med ID-nummer prioriterat högre än klasser och element, och så vidare. Det finns ett undantag till den här listan: Egenskaper märkta med det viktiga sökordet har högsta prioritet. Men notera att det viktiga sökordet påverkar en enda egenskap inom en regel, inte hela regeln.

Vad händer när du har flera CSS-regler av samma vikt, vilka var och en skulle kunna påverka samma element? Låt oss ta en titt på ett exempel:

Eat your vegetables!

Vad antar du att färgen på spänningen är? Svaret igen kan vara överraskande: gul. Trots att dessa regler alla är primärklassbaserade anses den andra regeln (.container span) mer specifik än den första regeln, och den tredje regeln (.stork-container .stork-msg) är mer specifik än den andra. Hur fungerar detta?

Inline-stilar är kung

När det gäller CSS-specificitet, så är det. Om du kommer ihåg från tidigare i det här kapitlet nämnde vi att inline-stilar har fördelen att de sällan står i konflikt med föräldrasidan. Nu är det klart varför: De prioriteras över alla andra typer av regelbundna CSS-regler (exklusive de med det viktiga sökordet). Om du skriver en särskilt enkel widget, kanske det inte är en dålig idé att använda inline-stilar. du kommer att undvika de flesta CSS-specificitetskonflikter.

Webbläsaren använder ett enkelt poängsystem för att bestämma vilken regel som prioriteras. För en given regel är varje väljare som komponerar den här regelvärdet värt ett visst värde. Dessa värden summeras för att skapa en specificitetspoäng. När flera regler påverkar samma element, jämför webbläsaren varje regels specificitetspoäng, och regeln med högsta poäng prioriterar. I händelse av ett slips vinner den regel som definierades senast. Inline stil attribut: 1000; ID: 100; klasser, pseudoklasser och attribut: 10, element och pseudo-element: 1.

Så, titta tillbaka på vårt tidigare exempel, skulle dessa CSS-regler ha fått följande poäng, med högsta poängregeln prioriterad av webbläsaren: Du kommer snabbt märka att dessa inte är vanliga nummer. En specificitetspoäng är egentligen en tupel av formen (a, b, c, d), med en vara värdefullare än b, b är mer värdefull än c och så vidare. Det betyder att en stil som orsakas av en enkel inline-stilattribut (1, 0, 0, 0) har högre specificitet än en regel med hundra ID-selektorer (0, 100, 0, 0).

  • .Tork-container (0,0,1,0-en klassväljare)
  • .Tork-container spännvidd (0,0,1,1-en klassväljare, en elementväljare)
  • .Stork-container. Stork-msg (0,0,2,0-två klassväljare)

Vid denna tidpunkt borde du ha ett bra hand om hur CSS-specificitet fungerar, och varför webbläsaren prioriterar vissa regler över andra. Du kommer sedan att lägga den här kunskapen i bruk, eftersom vi utforskar några metoder för att skriva CSS som står högt i motsats till motstridiga förlagsstilar.

Överspecifiering av CSS

Det första och enklaste sättet att skriva CSS som inte strider mot utgivarens sida är att överspecifiera dina regler. Det innebär att deklarera ytterligare selektörer för att öka specifika regler för din regler, så att när webbläsaren jämför dina regler mot dem från föräldrasidan kommer de sannolikt att bli högre och prioriteras.

Låt oss titta på detta i praktiken. Tänk på detta reviderade exempel på Stork-widgetbehållaren, som nu sportar två behållarelement, var och en med ett unikt ID:

Mikon E90 Digital SLR

"/>

$ 599

4,3 / 5,0 • 176 recensioner

Den medföljande CSS för denna HTML kan då se ut så här:

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

Genom att redundant ange båda container-ID-erna som överordnade väljare av alla dina CSS-regler ger du en effektivitetspoäng på 0,2,0,0 till varje CSS-regler. Därefter kommer utgivarens generiska #page-regel från tidigare inte längre att vara i konflikt med din widget, eftersom den bara använder ett enda ID. Inte heller kommer några rent klass- eller elementbaserade regler att komma i konflikt eftersom de är en hel CSS-viktklass under ID s. Även om det är helt onödigt att ange ett andra ID för dina regler, så fungerar det som en effektiv enhet för att öka specificiteten.

Behåll din sanity med en CSS preprocessor

Skriva överspecificerade CSS kan vara ett verkligt drag: du måste ständigt skriva om samma ID-filer om och om igen för var och en av dina CSS-regler. Du kan åtgärda detta med hjälp av en CSS preprocessor, som utökar CSS-språket med ytterligare funktioner som förmågan att deklarera kapslade hierarkier av regler. Till exempel, med hjälp av LESS CSS preprocessorn, kan du skriva det tidigare exemplet så här:

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

Ett antal populära CSS preprocessorer finns idag, som alla har olika funktionssatser. Bland de mest populära är MINDRE,Sass, och Nål.

På sidan, kräver det här exemplet att din widget använder överordnade behållare med ID, vilket inte kommer att vara praktisk för widgets som kan göras flera gånger på samma sida. Dessutom är det fortfarande inte bulletbeständigt: en utgivare kan följa din ledning och överspecifiera sina egna CSS-regler, vilket resulterar i samma problem som du tidigare haft.

Men det här är ett osannolikt scenario, särskilt eftersom du redundant har angett två ID-nummer i varje regel. Du kan alternativt använda en, men det kommer givetvis att vara mer sårbar. Verkligheten är att de flesta utgivare använder sanna CSS-regler, och att överspecifiera dina regler som detta kommer att vara kompatibla med de flesta av dem.

Överspecificerande CSS blandas inte med kodkvalitetsverktyg

Om du tar för att överskatta din CSS så här kan du hitta en osannolik fiende: verktyg som utvärderar kvaliteten på din CSS-kod, till exempel CSS Lint, Google Page Speed ​​och Yahoos YSlow. Dessa verktyg kommer att indikera att du gör redundanta CSS-väljare, och de kommer att råda dig att ta bort sådana väljare för att minska filstorleken och förbättra webbläsarens CSS-prestanda. Tyvärr är dessa verktyg inte programmerade med skript från tredje part i åtanke, och utvärderar inte riktigt användbarheten av överskådliggörande CSS. Fördelarna med överspecifikation för program från tredje part kommer att uppväga den extra filstorleken och minuscule prestationsfrekvensen.

Missbrukande! Viktigt

Om du känner att överskriften av din CSS med extra ID eller klassväljare inte går tillräckligt långt, kan du bryta ut kärnvapentalternativet: det viktiga sökordet. Egenskaper inom en CSS-regel som sportar det viktiga sökordet prioriteras högst av allt, även över inline-stilar. Detta beror på att det viktiga sökordet var utformat för att ge webbläsare ett säkert sätt att överväga "författare" (publisher) -stilar, när det gäller webbläsarpluggar eller webbplatsspecifika stilar. Du kan missbruka! Viktigt genom att använda det på alla dina CSS-egenskaper, och prioritera dem effektivt över alla andra regler.

Så här kan du använda det viktiga sökordet på en enda CSS-regel:

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

Eftersom det är per egendom måste det viktiga sökordet upprepas så här, vilket kan bli ett drag över ett långt och komplext stilark. Men i utbyte får du en rockfast uppsättning stilark som är mycket osannolikt att återställas av förläggarens sida.

Det är fortfarande tänkbart att utgivaren i sin tur kunde använda! Viktigt att rikta in dina element och ställa in egna stilar, då är det sannolikt att de riktigt riktar in dina delar för anpassning. Å ena sidan kan det vara frustrerande om du försöker hålla en konsekvent utseende. Men om du har bestämt dig för att tillåta utgivare att anpassa din widget, är detta förmodligen önskat beteende.

En sak borde vara tydlig: att dela DOM med utgivaren kan göra det särskilt svårt att göra en konsekvent utformad widget. Även om du kan vidta åtgärder för att överspecifiera dina CSS-regler för att minska sannolikheten för konflikter, är det alltid möjligt för utgivaren att rikta in sina delar med sina regler, antingen av misstag eller med avsikt.

Men om du delar delningen med utgivaren är det som orsakar så mycket sorg, är det möjligt att göra din widget avstängd från DOM? Varför, ja-ja du kan.

Sammanfattning

För en tredjeparts JavaScript-applikation kräver insprutning av HTML och CSS på utgivarens sida mer omsorg än om du lägger till markering i en "säker" miljö. Du måste se till att du inte saktar ner sidan med en blockering när du lägger ut HTML på sidan. Du måste också överväga att ditt skript kanske kommer att inkluderas flera gånger på samma sida, och det ska göra flera instanser elegant. Dessutom bör du välja en optimal metod för att injicera CSS på utgivarens sida, antingen genom att inlätta alla dina stilar, lägga till länkelement eller infoga CSS-regler i JavaScript.

Men att bara hämta HTML och CSS på sidan är inte tillräckligt. Du måste erkänna att de element du presenterar för DOM kan stämma överens med föräldrasidan. Du måste också överväga hur dina stilar kan störa varandra med befintliga stilar som definierats av utgivaren. Du kan använda ett antal tekniker för att minska effekterna av överordnade stilar på din widget: genom att överspecifiera dina CSS-regler eller presentera ditt innehåll bakom en iframe, oavsett om det är en src-less iframe eller en som innehåller ett externt HTML-dokument.

Vilka tekniker använder du när du producerar CSS och HTML för tredje part? Faller du någonsin tillbaka! Viktigt? Låt oss veta i kommentarerna.

Utvalda bild / miniatyrbild, försvarsbild via Shutterstock.