How to Load CSS Rules Dynamically in Webkit (Safari/Chrome)

How do I load css rules dynamically in Webkit (Safari/Chrome)?

I think it's a better practice to append a "link" tag to the head of your document. If that isn't possible, try to append a "style" tag to the head. Style tags shouldn't be in the body (Doesn't even validate).

Append link tag:

var link = document.createElement('link');

link.setAttribute('rel', 'stylesheet');

link.type = 'text/css';

link.href = 'http://example.com/stylesheet.css';

document.head.appendChild(link);

Append style tag:

var style = document.createElement('style');

style.innerHTML = 'body { background-color: #F00; }';

document.head.appendChild(style);

Webkit - dynamically created stylesheet - when does it really load?

Dynamically loading CSS stylesheets is still an area filled with browser quirks, unfortunately. In Webkit, <style> and <link> elements will both fire load and error events when loading stylesheets. However, the load event itself means only that the stylesheet resource has been loaded, not necessarily that it has been added to document.styleSheets.

The require-css RequireJS loader deals with this issue by branching its loading mechanism based on userAgent sniffing (it is nearly impossible to feature-detect whether or not the <link> tag will fire its load event properly). Specifically for Webkit, the detection resorts to using setTimeout to find when the StyleSheet object has been attached to document.styleSheets

var webkitLoadCheck = function(link, callback) {
setTimeout(function() {
for (var i = 0; i < document.styleSheets.length; i++) {
var sheet = document.styleSheets[i];
if (sheet.href == link.href)
return callback();
}
webkitLoadCheck(link, callback);
}, 10);
}

So while the load event will fire on Webkit, it is unreliable for the purposes of being able to access the corresponding StyleSheet instance.
Currently the only engine that supports stylesheet load events properly is Firefox 18+.

Disclosure: I am a contributor to require-css

References:

  • http://pieisgood.org/test/script-link-events/
  • https://bugs.webkit.org/show_bug.cgi?id=56436
  • https://bugs.webkit.org/show_bug.cgi?id=38995
  • https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link

jquery ajax load() does not load internal css for webkit browsers

Loading css rules dynamically in Webkit (Safari/Chrome)

Loading Browser Specific Style Sheets in Modern Browsers

Some suggestions:

Server-side detection

Depending on the server serving the CSS files, you may configure/customize it to serve the file you want depending on the User-Agent header.

Link to CSS depending on the browser

See answer from scunliffe

Single CSS with class on body and overridden rules

Detect the browser, and add a class on the body according to the browser, for example document.body.className += " msie"

Then override the rules you want in your css

body.msie someTag { /*msie specific rules*/ }

I recommend to use a library for browser detection, they are usually more tested. I just found WhichBrowser which seems to do that very well.

Why does webkit (Chrome/Safari) render wonky focus on this element?

Try adding vertical-align: top to the img. That gap looks suspiciously like the usual problem.

Dynamically loading css file using javascript with callback without jQuery

Unfortunately there is no onload support for stylesheets in most modern browsers. There is a solution I found with a little Googling.

Cited from: http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof

The basics

The most basic implementation of this can be done in a measely 30 lines of — framework independent — JavaScript code:

function loadStyleSheet( path, fn, scope ) {
var head = document.getElementsByTagName( 'head' )[0], // reference to document.head for appending/ removing link nodes
link = document.createElement( 'link' ); // create the link node
link.setAttribute( 'href', path );
link.setAttribute( 'rel', 'stylesheet' );
link.setAttribute( 'type', 'text/css' );

var sheet, cssRules;
// get the correct properties to check for depending on the browser
if ( 'sheet' in link ) {
sheet = 'sheet'; cssRules = 'cssRules';
}
else {
sheet = 'styleSheet'; cssRules = 'rules';
}

var interval_id = setInterval( function() { // start checking whether the style sheet has successfully loaded
try {
if ( link[sheet] && link[sheet][cssRules].length ) { // SUCCESS! our style sheet has loaded
clearInterval( interval_id ); // clear the counters
clearTimeout( timeout_id );
fn.call( scope || window, true, link ); // fire the callback with success == true
}
} catch( e ) {} finally {}
}, 10 ), // how often to check if the stylesheet is loaded
timeout_id = setTimeout( function() { // start counting down till fail
clearInterval( interval_id ); // clear the counters
clearTimeout( timeout_id );
head.removeChild( link ); // since the style sheet didn't load, remove the link node from the DOM
fn.call( scope || window, false, link ); // fire the callback with success == false
}, 15000 ); // how long to wait before failing

head.appendChild( link ); // insert the link node into the DOM and start loading the style sheet

return link; // return the link node;
}

This would allow you to load a style sheet with an onload callback function like this:

loadStyleSheet( '/path/to/my/stylesheet.css', function( success, link ) {
if ( success ) {
// code to execute if the style sheet was loaded successfully
}
else {
// code to execute if the style sheet failed to successfully
}
} );

Or if you want to your callback to maintain its scope/ context, you could do something kind of like this:

loadStyleSheet( '/path/to/my/stylesheet.css', this.onComplete, this );

How to set the style -webkit-transform dynamically using JavaScript?

The JavaScript style names are WebkitTransformOrigin and WebkitTransform

element.style.webkitTransform = "rotate(-2deg)";

Check the DOM extension reference for WebKit here.



Related Topics



Leave a reply



Submit