CSS Independent Content

From GreaseSpot Wiki
Revision as of 14:17, 28 February 2008 by Ecmanaut (talk | contribs) (More correct.)
Jump to navigationJump to search

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.

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.
// 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:0; left:0; 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 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 using this handy library for roughly the above, though better pampering those bugs, and use code like this instead:

makeFrame(gotFrame);

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