Injecting dynamic CSS before page load with Chrome’s content-script

I came across a rather unusual feature that had to be implemented; I needed to inject a custom CSS file dynamically based on a certain set of rules to each page (using Chrome Extension’s content-script).

The rules I was asked to consider could not be implemented using match patterns (read more about content-scripts and match patterns in Google’s documentation), so I had to inject a Javascript page that will perform the relevant tests.

First thought was to perform the test and inject the CSS before the page loads, but I soon found out that there is not page to inject the CSS to yet.

So I tried doing the same but after the page loads, which resulted in horrible flickering when the CSS rules took effect.

So my solution was to perform the test before the page loads, listen for DOM changes until I’m sure I have a HEAD element to which I can inject my CSS, and lastly remove the listener I created:

(function(){

    var loc = document.location.href;
    if( /* ---- Perform your test here ---- */ /www\.google/.test(loc)){

        document.addEventListener('DOMSubtreeModified', injectCSS, false);

        function injectCSS(){
            if(document.head){
                document.removeEventListener('DOMSubtreeModified', injectCSS, false);

                var style = document.createElement("style");
                style.innerHTML = "background: red";
                document.head.appendChild(style);
            }
        }
    }

})()

This option provided the best result without any flickering of CSS.

1 comment

Leave a Reply

Your email address will not be published. Required fields are marked *