Invert a whole webpage with CSS only

I recently saw Paul Irish’s jQuery invert page plugin. It inverts every color on a webpage including images or CSS. This reminded me of the invert color keyword that’s allowed on outlines (and sadly only supported by Opera and IE9+). So I wondered how it could be exploited to achieve the same effect through CSS alone. Turned out to be quite simple actually:

body:before { 
	content:"";
	position:fixed;
	top:50%; left: 50%;
	z-index:9999;
	width:1px; height: 1px;
	outline:2999px solid invert;
}

Not even pointer-events:none; is needed, since outlines don’t receive pointer events anyway, and there’s no issue with scrollbars since they don’t contribute to scrolling. So this is not even CSS3, it’s just plain ol’ CSS 2.1.

And here’s a bookmarklet to inject it into any given page: Invert page

Note:This will only work on Opera and IE9+ since they’re currently the only ones supporting the color keyword ‘invert’ on outlines. However, it’s probably possible to add Firefox support too with SVG filters, since they support them on HTML elements as well.

As for why would someone want to invert a page… I guess it could be useful for people that can read white text on dark backgrounds more easily, April fools jokes, konami code fun and stuff like that.

Update: Mozilla is planning to never support invert because there’s a loophole in the CSS 2.1 spec that allows them to do that. However, you can push them to support it by voting on the relevant issue.

  • Rob Steward

    I was lucky enough to catch a retweet of this from @nimbuin. This blows my mind. You legend!

  • I love the simplicity of this, nice one 🙂

  • Pingback: xhtml css templates – Invert a whole webpage with CSS only | Lea Verou | XHTML CSS - Style sheet and html programming tutorial and guides()

  • If this isn’t “cutting edge front-end development”, what is!?

  • Anonymous

    FF4 button doesn’t work 🙁

    Wow google chrome works funny too! Windows OS

    • I wrote it only works on Opera and IE9 at this time.

      • Anonymous

        My bad 🙂

        Also heres bookmarklet with paul`s plugin

        javascript:(function(){function getScript(url,callback){var head=document.documentElement,script=document.createElement(‘script’);script.src=url;var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState===’loaded’||this.readyState===’complete’)){done=true;callback();script.onload=script.onreadystatechange=null;if(head&&script.parentNode){head.removeChild(script);}}};head.insertBefore(script,head.firstChild);}
        getScript(‘//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js’,function(){getScript(‘//gist.github.com/raw/373253/a7da8e03c06a0a5d5724e0afd777ccbfe666fea9/gistfile1.js’,function(){$(‘body’,’html’).invert();});});})();

  • Pingback: Max Degterev > Invert webpage colors()

  • Cnecochea

    this would actually be really useful for people with low vision who have an easier time reading light text on dark backgrounds.

  • why not top:0; left:0; ?

    • That’s how I originally had it, but it wastes half of the outline.

      • but what about the pixel in center of the screen?

        • I didn’t consider it that big of a problem. If you do, it’s very easy to change this so that the pixel is at a corner, so nobody notices. (and if you want to make it even less noticeable, color it gray which is the color with the minimum maximum distance from all others).

          If negative outline-offset was supported by Opera and IE9+, then we could do that, but sadly it’s not (and I’m not even sure whether it’s a bug, so that I report it. The spec is unclear)

        • Anyway, this is a demonstration of elegant and simple approach. When I read the headline, expecting to see at least a few hundred lines of code =) Thanks for the motivation.

        • Why have the pixel at all, it seems to be working fine when both its width and height are zero…

        • hhhhhh

          fffffffffffff

  • Nice techdemo, but pretty useless if not even supported in Firefox or Safari.

  • Pingback: Linkdump #41: CySySy. « Tomasz Kowalczyk()

  • Michal Čaplygin

    Just for record and nostalgic whining, Mozilla used to support the “invert” (XOR filter value of the outline property)  till Firefox 3.0; I remember I’ve played with it some time ago and alike many others am surprised it does not work any more. See https://developer.mozilla.org/en/CSS/outline-color#Browser_compatibility .

  • Michal Čaplygin

    Just for record and nostalgic whining, Mozilla used to support the “invert” (XOR filter value of the outline property)  till Firefox 3.0; I remember I’ve played with it some time ago and alike many others am surprised it does not work any more. See https://developer.mozilla.org/en/CSS/outline-color#Browser_compatibility .

  • For the record, this webkit bug was raised by Lea when she authored this post: https://bugs.webkit.org/show_bug.cgi?id=58567

    • Thanks for writing a patch for it!

  • Luís de Sousa

    Hi. I’m partially colourblind, and although I can read black on white, I find white backgrounds extremely aggressive, and can’t bear them for long periods. Apart from that, light characters on dark backgrounds was what I was taught to use at computer science school. So far I’ve been working with the User Styles plugin for Firefox, but it forces you to edit the CSS of every single website you use.

    Indeed it would be great if this kind of solution would work on Firefox or Chrome.

    Regards.

    • In the future you’ll be able to just use filter: invert();
      You can experiment with it now in WebKit, it’s been supported for a while (behind a -webkit- prefix on the property)

  • Pingback: CSS печатной версии страницы | Фрилансер Кирилл Куликов()

  • Pingback: CSS печатной версии страницы | i-adept()

  • leosok

    My Version of this (working on Chrome and Firefox):

    javascript:(function(){var css=’html {-webkit-filter: invert(100%);’+’-moz-filter: invert(100%);’+’-o-filter: invert(100%);’+’-ms-filter: invert(100%); }’,head=document.getElementsByTagName(‘head’)[0],style=document.createElement(‘style’);if(!window.counter){window.counter=1;}else{window.counter++;if(window.counter%2==0){var css=’html {-webkit-filter: invert(0%); -moz-filter: invert(0%); -o-filter: invert(0%); -ms-filter: invert(0%); }’}};style.type=’text/css’;if(style.styleSheet){style.styleSheet.cssText=css;}else{style.appendChild(document.createTextNode(css));}head.appendChild(style);})();

    • asdlgjksadg

      These days, please try not to use JS if you can handle the same thing with CSS3

  • Sarat

    Simply Awesome… saved my time 🙂

  • Pingback: satta matka()

  • Pingback: angara fahise()

  • Pingback: accident()

  • Pingback: roidsmall.net legit()

  • Pingback: ankara escort()

  • Pingback: best online steroids()

  • Pingback: amazing blog()

  • Pingback: Life Insurance()

  • Pingback: https://tribot.org()

  • Pingback: get cash for surveys review()

  • Pingback: hand carved sofa()

  • Pingback: Film İzle()

  • Pingback: Matka Result()

  • Pingback: more()

  • Pingback: nandrolone phenylpropionate()

  • Pingback: british dragon products()