Når det kommer til gjengivelse på andres DOM, kan du ikke naivt skrive HTML og CSS som du kanskje for ditt eget selvstendig webapplikasjon. Du må tenke nøye på hvordan eksisterende eksisterende CSS og JavaScript-kode kan påvirke søknaden din.

Før du begynner å skrive noen HTML eller CSS, må du ta en viktig beslutning om utseendet på applikasjonen din. Vil du at søknaden din skal se lik overalt? Eller vil du at programmet skal arve det innfødte utseendet på siden som den er vert for? Svaret ditt vil ha en dyp innvirkning på strategien din for å gjengi appen din.

En ting er konstant: På noe nivå vil du øve det vi kaller defensiv gjengivelse. Ved defensiv, mener vi å ta skritt for å utdata HTML og CSS som minimerer virkningen av overordnet siden på søknaden din. Jo mindre du vil at din widget påvirkes av foreldresiden, desto flere trinn må du ta. Disse trinnene kan være så små som namespacing HTML og CSS for å redusere navnekonflikter, eller overspecifying CSS-reglene dine slik at de prioriterer over regler fra foreldresiden. For widgets som ønsker fullstendig immunitet fra foreldresiden, kan det også bety at serveren din serveres på et helt eget DOM, innebygd i en iframe.

Vi vil fokusere på gjengivelse av HTML og CSS som lever på samme DOM som utgiverens side. For widgets som har som mål å tilby noen grad av tilpasning, kan dette være den mest fleksible løsningen for utgivere, siden utgiveren enkelt kan målrette elementene dine og tilpasse dem til deres preferanser.

Dessverre er dette også ulemper. Utgiveren kunne uvitende ha CSS-regler og / eller JavaScript-kode som utilsiktet målretter din widget og utfordrer ødeleggelse.

Vi ser på en rekke måter å skjerme programmets HTML og CSS fra utgiverens kode. Først vil du lære om HTML og CSS navneområder. Deretter lærer du om CSS-spesifisitet, og hvordan overordnede sidestiler kan overstyre din egen.

Til slutt lærer du teknikker for å overstyre sidens foreldreformater, ved å overspecify CSS og misbruke det viktige søkeordet. Først opp, navneområder.

navnerom

Alle DOM ID-er, klasser, data- * attributter, og tilhørende CSS-selektorer er prefixed med stork-. Formålet? For å redusere sannsynligheten for at disse attributene er i konflikt med foreldresiden.

Vurder følgende situasjon. Din widget har et toppnivå

element som fungerer som en beholder Det gjør dette ved å sette en eksplisitt bredde og høyde, som effektivt begrenser området tatt opp av widgeten din. Du har gitt dette
et enkelt klassenavn, container, som samsvarer med en stilregel i din medfølgende CSS:

...

Dette kan være perfekt egnet for et vanlig opphold-hjemme-program, men for en tredjepartsprogram er det et komplett ikke-no. Grunnen? Et slikt generisk klassenavn har en god sjanse til å bli brukt av foreldresiden. Hvis du introduserer denne stilregelen, kan du overstyre en eksisterende stilregel som er lagt ut av utgiveren, og ødelegge nettstedoppsettet. Eller på regelen kan regelen deres overstyre din og endre størrelsen på widgeten din utilsiktet.

Løsningen? Forkaster alle klassenavnene dine (og andre attributter) med en identifikator som er unik for søknaden din - et navneområde. I tilfelle av Stork-widgeten, må den forrige markeringen endres slik at den ser slik ut:

...

Tanken er at du namepace JavaScript-koden din, slik at du ikke erklærer globale objekter som er i konflikt med kode som kjører på foreldresiden. Den strekker seg til alle deler av HTML du legger inn på siden: IDer, klasser, data- * attributter, skjema navn, og så videre.

Namespacing HTML og CSS er et must for alle tredjepartsprogrammer som gjøres direkte til utgiverens side. Dette er ikke bare nødvendig for å hindre motstridende CSS-regler; Det er også tenkelig at foreldresiden har JavaScript som spør etter DOM for elementer hvis identifiserende egenskaper kan matche din egen. Vær streng i navngivning alt du legger på DOM.

CSS spesifisitet

Det er viktig å merke seg at, men nyttig, namespacing HTML og CSS bare hindrer tilfeller hvor utgiveren bruker stiler eller spørringer som referanseattributter med samme navn som ditt. Dessverre kan widgeten din fortsatt være i konflikt med stiler som er definert av foreldresiden, selv om deres CSS bruker IDer, klassenavn og attributter som ikke direkte refererer til elementene dine. Dette skyldes at noen CSS-regler veier tungere av nettleseren, og kan ha forrang over tilsynelatende ikke-relaterte regler du kan definere. Dette fenomenet kalles CSS-spesifisitet, og du må forstå det før du trygt kan gjøre elementer på utgiverens side.

La oss gå tilbake til containereksemplet fra forrige seksjon på navneområder. Anta at utgiverens HTML har et toppnivå DIV som bryter alt innholdet sitt, med en ID-side:

...
...

I tillegg la oss si at siden har følgende CSS, der den første regelen er definert av utgiveren, og den andre regelen som målretter mot stork-container, blir lagt til av tredjepartsskriptet ditt:

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

Nå, hvilken farge vil. Stork-container ha? Svaret kan sjokkere og skremme deg: grønn. I dette enkle eksemplet prioriterer utgiverregelen (#page div) over tredjepartsprogrammets klasseregel (.stork-container). Dette skjer fordi nettleseren veier regler som inneholder ID-er høyere enn de som retter seg mot klasser eller attributter.

CSS-regelprioriteter

W3C CSS-spesifikasjonen beskriver hvordan nettlesere er ment å prioritere ulike regeltyper. Her er en liste over disse regeltypene, bestilt fra høyeste prioritet til laveste:

  1. Inline-stiler (style = "...")
  2. IDer
  3. Klasser, attributter og pseudoklasser (: fokus, hover)
  4. Elementer (div, span, og så videre) og pseudo-elementer (: før, etter)

Ifølge dette diagrammet veies inline-stiler over alle etterfølgende regeltyper: IDer, klasser og elementer. Dette fortsetter logisk nedover listen, med ID-er prioriteres høyere enn klasser og elementer, og så videre. Det er ett unntak fra denne listen: egenskaper som er merket med det viktige søkeordet, har høyeste prioritet. Men merk at det viktige søkeordet påvirker en enkelt eiendom i en regel, ikke hele regelen.

Hva skjer når du har flere CSS-regler med samme vekt, som hver kan tenke på det samme elementet? La oss se på et eksempel:

Eat your vegetables!

Hva antar du at fargene på spekteret er? Svaret igjen kan være overraskende: gul. Selv om disse reglene alle er primært klassebaserte, anses den andre regelen (.container span) mer spesifikk enn den første regelen, og den tredje regelen (.stork-container. Stork-msg) mer spesifikk enn den andre. Hvordan virker dette?

Inline-stiler er konge

Når det gjelder CSS-spesifisitet, er det. Hvis du husker fra tidligere i dette kapitlet, nevnte vi at inline-stiler har fordelen av sjelden at de er i konflikt med foreldresiden. Nå er det klart hvorfor: de prioriteres over hver annen type vanlig CSS-regel (unntatt de med det viktige søkeordet). Hvis du skriver en spesielt enkel widget, kan det ikke være en dårlig idé å bruke inline-stiler; Du vil unngå de fleste CSS-spesifisitetskonflikter.

Nettleseren bruker et enkelt scoring system for å bestemme hvilken regel som prioriteres. For en gitt regel er hver selector som komponerer den regelen verdt en viss verdi. Disse verdiene summeres for å skape en spesifisitetspoengsum. Når flere regler påvirker det samme elementet, sammenligner nettleseren hver regels spesifisitetspoeng, og regelen med høyest poengsum prioriterer. I tilfelle av et slips vinner regelen som ble definert sist. Inline stil attributter: 1000; ID: 100; klasser, pseudoklasser og attributter: 10, elementer og pseudo-elementer: 1.

Så, ser tilbake på vårt forrige eksempel, ville disse CSS-reglene ha blitt tildelt følgende score, med høyest scoring-regelen som prioriteres av nettleseren: Du vil raskt se at disse ikke er vanlige tall. En spesifisitetspoengsum er faktisk en tuple av skjemaet (a, b, c, d), med et vesen mer verdifullt enn b, b er mer verdifullt enn c, og så videre. Det betyr at en stil som skyldes et enkelt inline-stilattributt (1, 0, 0, 0) har høyere spesifisitet enn en regel med hundre ID-selektorer (0, 100, 0, 0).

  • .Stork-container (0,0,1,0-en klassevelger)
  • .Tork-beholder spenning (0,0,1,1-ett-klasse velger, en elementvelger)
  • .Stork-container. Stork-msg (0,0,2,0-to klasse selektorer)

På dette tidspunktet bør du ha et godt håndtak på hvordan CSS-spesifisitet fungerer, og hvorfor nettleseren prioriterer noen regler over andre. Du vil neste sette denne kunnskapen til bruk, ettersom vi undersøker noen tilnærminger for å skrive CSS som står høyt i møte med motstridende utgiverstiler.

Overspecifying CSS

Den første og enkleste tilnærmingen til å skrive CSS som ikke er i konflikt med utgiverens side, er å overspecify dine regler. Dette betyr at deklarerer flere valggivere for å øke spesifisiteten til reglene dine, slik at når nettleseren sammenligner reglene dine mot de fra foreldresiden, vil de sannsynligvis score høyere og prioriteres.

La oss se på dette i praksis. Tenk på dette reviderte eksempelet på Stork-widgetbeholderen, som nå har to beholderelementer med hver en unik ID:

Mikon E90 Digital SLR

"/>

$ 599

4,3 / 5,0 • 176 Anmeldelser

Den medfølgende CSS for denne HTML kan da se slik ut:

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

Ved å redundant angi begge container-ID-er som overordnede selektorer av alle dine CSS-regler, gir du effektivt CSS-reglene en minimums spesifisitetspoengsum på (0,2,0,0). Etterpå vil utgiverens generiske #page-regel fra tidligere ikke lenger være i konflikt med widgeten din, fordi den bare bruker en enkelt ID. Ingen vil heller rent klasse- eller elementbaserte regler komme i konflikt, fordi de er en hel CSS vektklasse under ID s. Selv om det for utvelgelsesformål er helt unødvendig å spesifisere et andre ID for reglene, fungerer det som en effektiv enhet for å øke spesifisiteten.

Bevar din sunnhet med en CSS preprosessor

Skrive overspecified CSS kan være en virkelig dra: du må hele tiden omskrive de samme IDene igjen og igjen for hver enkelt av dine CSS-regler. Du kan rette opp dette ved hjelp av en CSS preprocessor, som utvider CSS-språket med tilleggsfunksjoner som evnen til å erklære nestede hierarkier av regler. For eksempel, ved hjelp av LESS CSS preprocessor, kan du skrive det forrige eksempelet slik:

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

En rekke populære CSS preprosessorer er tilgjengelige i dag, som alle har varierende funksjonssett. Blant de mest populære er MINDRE,sass, og Stylus.

På forsiden krever dette eksemplet at din widget bruker toppnivåbeholdere med ID, som ikke vil være praktisk for widgets som kan gjengis flere ganger på samme side. I tillegg er det fortsatt ikke bulletproof: en utgiver kan følge din ledelse og overspecify sine egne CSS-regler, noe som resulterer i det samme problemet du hadde før.

Men dette er et usannsynlig scenario, spesielt siden du redundant har oppgitt to ID-er i hvert av reglene. Du kan alternativt bruke en, men dette vil selvfølgelig være mer sårbar. Virkeligheten er at de fleste utgivere bruker sanne CSS-regler, og overspecifying dine regler som dette vil være kompatible med de fleste av dem.

Overspecifying CSS blandes ikke med kodekvalitetsverktøy

Hvis du tar for å overspecify CSS slik, kan du finne en usannsynlig fiende: verktøy som evaluerer kvaliteten på CSS-koden din, for eksempel CSS Lint, Google Page Speed ​​og Yahoo's YSlow. Disse verktøyene vil indikere at du gjør redundante CSS-valgere, og de vil råde deg til å fjerne slike valg for å redusere filstørrelsen og forbedre nettleserens CSS-ytelse. Dessverre er disse verktøyene ikke programmert med tredjepartsskript i tankene, og vurderer ikke brukbarheten av overspecifying CSS. Fordelene med overspecification for tredjepartsprogrammer vil oppveie den ekstra filstørrelsen og minuscule ytelsesspillet.

Misbruk! Viktig

Hvis du føler at overspecifying CSS med ekstra ID eller klassevalgere ikke går langt nok, kan du bryte ut nukleare alternativet: det viktige søkeordet. Egenskaper i en CSS-regel som har det viktige søkeordet, prioriteres høyest av alt, selv over inline-stiler. Dette skyldes at det viktige søkeordet var designet for å gi brukerne en sikker måte å overstyre "forfatter" (utgiver) stiler, når det gjelder nettleserplugger eller nettstedsspesifikke stiler. Du kan misbruke! Viktig ved å bruke den på alle dine CSS-egenskaper, og prioritere dem effektivt over alle andre regler.

Slik bruker du det viktige søkeordet på en enkelt CSS-regel:

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

Siden det er per eiendom, må det viktige søkeordet gjentas som dette, noe som kan bli en dra over et langt og komplekst stilark. Men i bytte får du et storslått sett med stilark som er svært lite sannsynlig å bli tilbakestilt av utgiverens side.

Det er fortsatt tenkelig at utgiveren i sin tur kunne bruke! Viktig for å målrette elementene dine og sette sine egne stiler, på hvilket tidspunkt er de sannsynligvis målrettet mot elementene dine for tilpasning. På den ene siden kan det være frustrerende hvis du prøver å opprettholde et konsekvent utseende. Men hvis du har bestemt deg for å tillate utgivere å tilpasse widgeten din, er dette trolig ønsket oppførsel.

En ting bør være klart: deling av DOM med utgiveren kan gjøre det spesielt vanskelig å lage en konsekvent stylet widget. Selv om du kan ta skritt for å overpecify CSS-reglene dine for å redusere risikoen for konflikter, er det alltid mulig for utgiveren å målrette elementene dine med deres regler, enten ved et uhell eller med vilje.

Men hvis du deler DOM med utgiveren, er det som forårsaker så mye sorg, er det mulig å gjengi din widget av DOM? Hvorfor, ja, ja det kan du.

Sammendrag

For en tredjeparts JavaScript-applikasjon krever injeksjon av HTML og CSS på utgiverens side mer omsorg enn om du legger til markering i et "trygt" miljø. Du må sørge for at når du legger ut HTML til siden, forsinker du ikke siden med en blokkering. Du må også vurdere at skriptet ditt kan bli inkludert flere ganger på samme side, og det bør gjengi flere forekomster grasiøst. I tillegg bør du velge en optimal metode for å injisere CSS i utgiverens side - enten ved å legge inn alle stilene dine, legge til linkelementer eller legge inn CSS-regler i JavaScript.

Men bare å få HTML og CSS på siden er ikke nok. Du må gjenkjenne at elementer du introduserer til DOM, kan være i konflikt med foreldresiden. Du må også vurdere hvordan stilene dine kan komme i konflikt med eksisterende stiler definert av utgiveren. Du kan bruke en rekke teknikker for å redusere effekten av foreldreformatene på widgeten din: ved å overspecify CSS-reglene dine eller presentere innholdet ditt bak en iframe, enten det er en src-less iframe eller en som inneholder et eksternt HTML-dokument.

Hvilke teknikker bruker du når du produserer CSS og HTML for tredjeparter? Finner du noen gang igjen? Viktig? Gi oss beskjed i kommentarene.

Utvalgt bilde / miniatyrbilde, forsvarsbilde via Shutterstock.