CSS Independent Content: Difference between revisions

From GreaseSpot Wiki
Jump to navigationJump to search
Ecmanaut (talk | contribs)
m More correct.
m Reverted edits by Ashok323 (talk) to last revision by Arantius
 
(9 intermediate revisions by 6 users not shown)
Line 1: Line 1:
Any HTML you inject into a site is subject to the CSS rules of that site. This is often what you want: the elements you inject will fit in nicely. But if you inject something – perhaps a configuration panel – that should look the same to pages where styles can vary wildly (e.g. MySpace, eBay) or across multiple sites (e.g. @include *), you may find that you want it exempt from the site CSS.
Any HTML you inject into a site is subject to the CSS rules of that site.
This is often what you want: the elements you inject will fit in nicely.
But if you inject something – perhaps a configuration panel – that should look the same in pages where styles can vary wildly (e.g. MySpace, eBay) or across multiple sites (e.g. @include *), you may find that you want it exempt from the site CSS.


The solution is to add your panel inside an iframe. Example code:
The solution is to add your panel inside an iframe.
Example code:


// position:fixed means stay fixed even the page scrolls. z-index keeps your iframe on top.
<pre class='sample'>
// The remainder of the line smacks the panel into the bottom left corner, out of your way.
// position:fixed means stay fixed even when the page scrolls. z-index keeps your iframe on top.
// Overflow (in combination with the setTimeout) ensures the iframe fits your entire panel.
// The remainder of the line smacks the panel into the bottom left corner, out of your way.
var css = 'position:fixed; z-index:9999; bottom:0; left:0; border:0; margin:0; padding:0; ' +
// Overflow (in combination with the setTimeout) ensures the iframe fits your entire panel.
          'overflow:hidden;'
var css = 'position:fixed; z-index:9999; bottom:0px; left:0px; border:0; margin:0; padding:0; ' +
          'overflow:hidden;'
var iframe = document.createElement('iframe');
iframe.setAttribute('style', css);
// The about:blank page becomes a blank(!) canvas to modify
iframe.src = 'about:blank';
document.body.appendChild(iframe);
// Make sure Firefox initializes the DOM before we try to use it.
iframe.addEventListener("load", function() {
    var doc = iframe.contentDocument;
    doc.body.style.background = 'red';
    doc.body.innerHTML = 'Test.';
    iframe.style.width = doc.body.offsetWidth + "px";
    iframe.style.height = doc.body.offsetHeight + "px";
}, false);


The above code will result in a minimal panel always-on-top in the bottom left corner, that grows to contain its contents. For a more intrusive lightbox-style panel mid-screen, just drop the two <code>iframe.style</code> lines and change the CSS to e.g.:
var iframe = document.createElement('iframe');
iframe.setAttribute('style', css);


// Margin, top, left, width and height center the iframe horizontally and vertically:
// The about:blank page becomes a blank(!) canvas to modify
var css = 'position:fixed; z-index:9999; border:1px solid black; ' +
iframe.src = 'about:blank';
          'top:50%; left:50%; width:30em; margin:-15em; 0 0 -10em; height:20em;';


As Firefox's iframe handling is [https://bugzilla.mozilla.org/show_bug.cgi?id=295813 rather] [https://bugzilla.mozilla.org/show_bug.cgi?id=388714 buggy], you may want to spare yourself much pain by using [http://ecmanaut.googlecode.com/svn/trunk/lib/make-iframe.js this handy library] for roughly the above, though better pampering those bugs, and use code like this instead:
document.body.appendChild(iframe);


makeFrame(gotFrame);
// Make sure Firefox initializes the DOM before we try to use it.
iframe.addEventListener("load", function() {
function gotGrame(iframe, win, doc) {
    var doc = iframe.contentDocument;
  iframe.height = "50";
    doc.body.style.background = 'red';
  iframe.style.position = "fixed";
    doc.body.innerHTML = 'Test.';
  frame.style.bottom = iframe.style.left = "0";
    // It seems Firefox (at least 3.6) has a bug. It will report offsetWidth less than clientWidth.
  doc.body.innerHTML = "Hello world!";
    // So try clientWidth and clientHeight instead of offsetWidth and offsetHeight
}
    iframe.style.width = doc.body.offsetWidth + "px";
    iframe.style.height = doc.body.offsetHeight + "px";
}, false);
</pre>
 
The above code will result in a minimal panel always-on-top in the bottom left corner, that does not grows to contain its contents because iframe.style.height has fixed value.
For a more intrusive lightbox-style panel mid-screen, just drop the two <code>iframe.style</code> lines and change the CSS to e.g.:
 
<pre class='sample'>
// Margin, top, left, width and height center the iframe horizontally and vertically:
var css = 'position:fixed; z-index:9999; border:1px solid black; ' +
          'top:50%; left:50%; width:30em; margin:-15em 0 0 -10em; height:20em;';
</pre>
 
As Firefox's iframe handling is [https://bugzilla.mozilla.org/show_bug.cgi?id=295813 rather] [https://bugzilla.mozilla.org/show_bug.cgi?id=388714 buggy], you may want to spare yourself much pain by @require'ing [http://ecmanaut.googlecode.com/svn/trunk/lib/make-iframe.js this handy library] for roughly the above, and use code like this instead:
 
<pre class='sample'>
makeFrame(gotFrame);
 
function gotFrame(iframe, win, doc) {
  iframe.height = "50";
  iframe.style.position = "fixed";
  iframe.style.bottom = iframe.style.left = "0";
  doc.body.innerHTML = "Hello world!";
}
</pre>
 
[[Category:Coding Tips]]
[[Category:@require Library]]

Latest revision as of 22:21, 14 August 2013

Any HTML you inject into a site is subject to the CSS rules of that site. This is often what you want: the elements you inject will fit in nicely. But if you inject something – perhaps a configuration panel – that should look the same in pages where styles can vary wildly (e.g. MySpace, eBay) or across multiple sites (e.g. @include *), you may find that you want it exempt from the site CSS.

The solution is to add your panel inside an iframe. Example code:

// position:fixed means stay fixed even when the page scrolls. z-index keeps your iframe on top.
// The remainder of the line smacks the panel into the bottom left corner, out of your way.
// Overflow (in combination with the setTimeout) ensures the iframe fits your entire panel.
var css = 'position:fixed; z-index:9999; bottom:0px; left:0px; border:0; margin:0; padding:0; ' +
          'overflow:hidden;'

var iframe = document.createElement('iframe');
iframe.setAttribute('style', css);

// The about:blank page becomes a blank(!) canvas to modify
iframe.src = 'about:blank';

document.body.appendChild(iframe);

// Make sure Firefox initializes the DOM before we try to use it.
iframe.addEventListener("load", function() {
    var doc = iframe.contentDocument;
    doc.body.style.background = 'red';
    doc.body.innerHTML = 'Test.';
    // It seems Firefox (at least 3.6) has a bug. It will report offsetWidth less than clientWidth.
    // So try clientWidth and clientHeight instead of offsetWidth and offsetHeight
    iframe.style.width = doc.body.offsetWidth + "px";
    iframe.style.height = doc.body.offsetHeight + "px";
}, false);

The above code will result in a minimal panel always-on-top in the bottom left corner, that does not grows to contain its contents because iframe.style.height has fixed value. For a more intrusive lightbox-style panel mid-screen, just drop the two iframe.style lines and change the CSS to e.g.:

// Margin, top, left, width and height center the iframe horizontally and vertically:
var css = 'position:fixed; z-index:9999; border:1px solid black; ' +
          'top:50%; left:50%; width:30em; margin:-15em 0 0 -10em; height:20em;';

As Firefox's iframe handling is rather buggy, you may want to spare yourself much pain by @require'ing this handy library for roughly the above, and use code like this instead:

makeFrame(gotFrame);

function gotFrame(iframe, win, doc) {
  iframe.height = "50";
  iframe.style.position = "fixed";
  iframe.style.bottom = iframe.style.left = "0";
  doc.body.innerHTML = "Hello world!";
}