Before you start to put in writing any HTML or CSS, you’ll need to make an vital choice relating to the feel and appear of your software. Do you need your software to look the identical in every single place? Or would you like the applying to inherit the native feel and appear of the web page on which it’s hosted? Your reply can have a profound impact in your technique for rendering your app.
One factor is fixed: at some stage, you’ll be working towards what we name defensive rendering. By defensive, we imply taking steps to output HTML and CSS that reduce the influence of the mum or dad web page in your utility. The much less you need your widget impacted by the dad or mum web page, the extra steps you’ll must take. These steps could be as small as namespacing your HTML and CSS to scale back title conflicts, or overspecifying your CSS guidelines in order that they take precedence over guidelines from the dad or mum web page. For widgets that need full immunity from the dad or mum web page, it might additionally imply serving your widget on a totally separate DOM, embedded in an iframe.
We’ll deal with rendering HTML and CSS that dwell on the identical DOM because the writer’s web page. For widgets that goal to supply some degree of customization, this may be essentially the most versatile answer for publishers, for the reason that writer can simply goal your parts and magnificence them to their preferences.
We’ll take a look at quite a lot of methods to protect your software’s HTML and CSS from the writer’s code. First, you’ll study HTML and CSS namespaces. Then, you’ll study CSS specificity, and the way the guardian web page’s types can override your individual.
Finally, you’ll be taught methods for overruling the web page’s mother or father kinds, by overspecifying your CSS and abusing the !essential key phrase. First up, namespaces.
All DOM IDs, lessons, knowledge-* attributes, and matching CSS selectors have been prefixed with stork-. The function? To cut back the probability of these attributes conflicting with the father or mother web page.
Consider the next state of affairs. Your widget has a prime-stage <div> aspect that acts as a container. It does this by setting an express width and top, successfully bounding the realm taken up by your widget. You’ve given this <div> a simple class identify, container, which matches a method rule in your accompanying CSS:
<div> ... </div> <type> .container width: 200px; top: 200px; </type>
This is perhaps completely applicable for a daily keep-at-dwelling software, however for a 3rd-social gathering app, it’s an entire no-no. The motive? Such a generic class identify has a superb probability of already being utilized by the mother or father web page. If you introduce this fashion rule, you would possibly override an present fashion rule put in place by the writer and damage their website structure. Or, on the flip aspect, their rule would possibly override yours and resize your widget inadvertently.
The resolution? Prefixing your entire class names (and different attributes) with an identifier distinctive to your software—a namespace. In the case of the Stork widget, the earlier markup ought to be amended to appear to be this:
<div> ... </div> <type> .stork-container width: 200px; top: 200px </type>
It’s vital to notice that, although useful, namespacing your HTML and CSS solely prevents instances the place the writer is utilizing kinds or queries that reference attributes with the identical title as yours. Unfortunately, your widget can nonetheless battle with types outlined by the guardian web page, even when their CSS makes use of IDs, class names, and attributes that don’t straight reference your components. This is as a result of some CSS guidelines are weighed extra closely by the browser, and may take priority over seemingly unrelated guidelines you may outline. This phenomenon is known as CSS specificity, and also you’ll want to grasp it earlier than you possibly can safely render parts on the writer’s web page.
Let’s return to the container instance from the earlier part on namespaces. Suppose the writer’s HTML has a prime-degree DIV that wraps all their content material, with an ID of web page:
<div id="web page"> ... <!-- Publisher content material --> <div> ... <!-- Stork content material --> </div> </div>
Additionally, let’s say the web page has the next CSS, the place the primary rule is outlined by the writer, and the second rule, concentrating on stork-container, is added by your third-occasion script:
/* Publisher */ #web page div background-shade: inexperienced; /* Camera Stork */ .stork-container background-shade: blue;
Now, what shade will .stork-container have? The reply would possibly shock and appall you: inexperienced. In this easy instance, the writer rule (#web page div) takes precedence over your third-occasion utility’s class rule (.stork-container). This occurs as a result of the browser weighs guidelines containing IDs increased than people who goal courses or attributes.
CSS RULE PRIORITIES
The W3C CSS specification outlines how browsers are supposed to prioritize completely different rule varieties. Here’s a listing of those rule sorts, ordered from highest precedence to lowest:
- Inline kinds (fashion=”…”)
- Classes, attributes, and pseudo-courses (:focus, :hover)
- Elements (div, span, and so forth) and pseudo-parts (:earlier than, :after)
According to this chart, inline kinds are weighed above all subsequent rule sorts: IDs, courses, and parts. This continues logically down the checklist, with IDs prioritized larger than lessons and parts, and so forth. There’s one exception to this checklist: properties tagged with the !vital key phrase take highest precedence. But observe that the !essential key phrase impacts a single property inside a rule, not all the rule.
What occurs when you could have a number of CSS guidelines of the identical weight, every of which might conceivably have an effect on the identical factor? Let’s check out an instance:
<div> <span class="stork-msg">Eat your greens!</span> </div> <model> .stork-container background-colour: blue; .stork-container span background-colour: pink; .stork-container .stork-msg background-coloration: yellow; </type>
What do you suppose the colour of the span is? The reply once more may be stunning: yellow. Even although these guidelines are all primarily class-primarily based, the second rule (.storkcontainer span) is taken into account extra particular than the primary rule, and the third rule (.stork-container .stork-msg) extra particular than the second. How does this work?
Inline types are king
In phrases of CSS specificity, that’s. If you recall from earlier on this chapter, we talked about that inline types take pleasure in hardly ever conflicting with the dad or mum web page. Now it’s clear why: they’re prioritized over each different sort of normal CSS rule (excluding these with the !necessary key phrase). If you’re writing a very easy widget, it may not be a nasty thought to make use of inline kinds; you’ll keep away from most CSS specificity conflicts.
The browser makes use of a easy scoring system to find out which rule takes precedence. For a given rule, every selector composing that rule is value a sure worth. Those values are summed to create a specificity rating. When a number of guidelines have an effect on the identical component, the browser compares every rule’s specificity rating, and the rule with the very best rating takes precedence. In the case of a tie, the rule that was outlined final wins. Inline type attributes: a thousand; IDs: a hundred; lessons, pseudo-courses and attributes: 10, parts and pseudo-components: 1.
So, trying again at our earlier instance, these CSS guidelines would have been assigned the next scores, with the best-scoring rule being prioritized by the browser:You’ll shortly discover these aren’t abnormal numbers. A specificity rating is definitely a tuple of the shape (a , b , c , d ), with a being extra helpful than b , b being extra worthwhile than c , and so forth. That signifies that a method brought on by a single inline model attribute (1, 0, 0, 0) has larger specificity than a rule with 100 ID selectors (0, a hundred, 0, 0).
- .stork-container (0,0,1,0—one class selector)
- .stork-container span (0,0,1,1—one class selector, one ingredient selector)
- .stork-container .stork-msg (0,0,2,0—two class selectors)
At this level, you must have an excellent deal with on how CSS specificity works, and why the browser prioritizes some guidelines over others. You’ll subsequent put this data to make use of, as we discover some approaches for writing CSS that stands tall within the face of conflicting writer types.
The first and easiest method to writing CSS that doesn’t battle with the writer’s web page is to overspecify your guidelines. This means declaring further selectors to spice up the specificity of your guidelines, such that when the browser compares your guidelines towards these from the mum or dad web page, they’re prone to rating larger and be prioritized.
Let’s have a look at this in observe. Consider this revised instance of the Stork widget container, now sporting two container components, every with a singular ID:
<div id="stork-most important"> <div id="stork-container"> <h3>Mikon E90 Digital SLR</h3> <img src="<a href="http://camerastork.com/img/merchandise/1337-small.png">http://camerastork.com/img/merchandise/1337-small.png</a>"/> <p>$599</p> <p>4.3/5.0 • 176 Reviews</p> </div> </div>
The accompanying CSS for this HTML may then appear like this:
#stork-principal #stork-container ... #stork-fundamental #stork-container .stork-product ... #stork-primary #stork-container .stork-worth ...
By redundantly specifying each container IDs as guardian selectors of all of your CSS guidelines, you’re successfully giving every of your CSS guidelines a minimal specificity rating of (0,2,0,0). Afterward, the writer’s generic #web page rule from earlier will now not battle along with your widget, as a result of it solely makes use of a single ID . Neither will any purely class- or component-based mostly guidelines battle, as a result of these are a complete CSS weight class beneath ID s. Even although, for choice functions, it’s utterly pointless to specify a second ID to your guidelines, right here it really works as an efficient gadget for enhancing specificity.
Preserve your sanity with a CSS preprocessor
Writing overspecified CSS could be a actual drag: it’s a must to always rewrite the identical IDs time and again for every one among your CSS guidelines. You can treatment this through the use of a CSS preprocessor, which extends the CSS language with extra options like the flexibility to declare nested hierarchies of guidelines. For instance, utilizing the LESS CSS preprocessor, you would write the earlier instance like this:
#stork-principal #stork-container .stork-product ... .stork-value ...
On the flip facet, this instance requires that your widget use high-degree containers with IDs, which gained’t be sensible for widgets that may be rendered a number of instances on the identical web page. Additionally, it’s nonetheless not bulletproof: a writer may observe your lead and overspecify their very own CSS guidelines, leading to the identical downside you had earlier than.
But that is an unlikely situation, particularly because you’ve redundantly specified two IDs in every of the foundations. You may alternatively use one, however this may in fact be extra susceptible. The actuality is that almost all publishers use sane CSS guidelines, and overspecifying your guidelines like this will likely be appropriate with most of them.
Overspecifying CSS doesn’t combine with code high quality instruments
If you are taking to overspecifying your CSS like this, you would possibly discover an unlikely enemy: instruments that consider the standard of your CSS code, comparable to CSS Lint, Google Page Speed, and Yahoo’s YSlow. These instruments will point out that you simply’re making redundant CSS selectors, and so they’ll advise you to take away such selectors to scale back file dimension and enhance browsers’ CSS efficiency. Unfortunately, these instruments aren’t programmed with third-occasion scripts in thoughts, and don’t pretty consider the usefulness of overspecifying CSS. The advantages of overspecification for third-celebration purposes will outweigh the additional file dimension and minuscule efficiency hit.
If you’re feeling that overspecifying your CSS with further ID or class selectors doesn’t go far sufficient, you possibly can get away the nuclear possibility: the !essential key phrase. Properties inside a CSS rule that sport the !vital key phrase are prioritized highest of all, even above inline kinds. This is as a result of the !vital key phrase was designed to offer browser customers a surefire solution to override “writer” (writer) types, within the case of browser plugins or web site-particular types. You can abuse !necessary by utilizing it on your entire CSS properties, successfully prioritizing them over all different guidelines.
Here’s the way you would possibly use the !necessary key phrase on a single CSS rule:
.stork-value font-measurement: 11px !necessary; colour: #888 !vital; textual content-ornament: none !essential; show: block !essential;
Since it’s per property, the !essential key phrase must be repeated like this, which may grow to be a drag over a protracted and sophisticated stylesheet. But, in alternate, you get a rock-strong set of stylesheets which might be not possible to be reset by the writer’s web page.
It’s nonetheless conceivable that the writer may in flip use !vital to focus on your components and set their very own kinds, at which level they’re doubtless purposely focusing on your components for personalization. On one hand, that may be irritating for those who’re attempting to take care of a constant feel and look. But, when you’ve determined to permit publishers to customise your widget, that is in all probability desired conduct.
One factor needs to be clear: sharing the DOM with the writer could make it notably tough to render a persistently styled widget. Although you possibly can take steps to overspecify your CSS guidelines to scale back the probability of conflicts, it’s at all times potential for the writer to focus on your components with their guidelines, both by chance or purposely.
But if sharing the DOM with the writer is what’s inflicting a lot grief, is it potential to render your widget off of the DOM? Why, sure—sure you possibly can.
But simply getting HTML and CSS on the web page isn’t sufficient. You have to acknowledge that components you introduce to the DOM can battle with the dad or mum web page. You additionally should think about how your kinds may battle with current kinds outlined by the writer. You can use numerous methods for decreasing the affect of father or mother types in your widget: by overspecifying your CSS guidelines or presenting your content material behind an iframe, whether or not it’s a src-much less iframe or one which accommodates an exterior HTML doc.
What strategies do you utilize when producing CSS and HTML for third events? Do you ever fall again on !essential? Let us know within the feedback.