How to use Javascript to check and load CSS if not loaded?

JavascriptJqueryCss

Javascript Problem Overview


I need to check (in Javascript) if a CSS file is loaded and if not then to load it. jQuery is fine.

Javascript Solutions


Solution 1 - Javascript

Just check to see if a <link> element exists with the href attribute set to your CSS file's URL:

if (!$("link[href='/path/to.css']").length)
    $('<link href="/path/to.css" rel="stylesheet">').appendTo("head");

The plain ol' JS method is simple too, using the document.styleSheets collection:

function loadCSSIfNotAlreadyLoadedForSomeReason () {
    var ss = document.styleSheets;
    for (var i = 0, max = ss.length; i < max; i++) {
        if (ss[i].href == "/path/to.css")
            return;
    }
    var link = document.createElement("link");
    link.rel = "stylesheet";
    link.href = "/path/to.css";

    document.getElementsByTagName("head")[0].appendChild(link);
}
loadCSSIfNotAlreadyLoadedForSomeReason();

Solution 2 - Javascript

I just had to write something like that and I wanted to share it. This one is prepared for multiple cases.

  • If there is no request for the css file (css file isn't linked ...)
  • If there is a request for the css file, but if it failed (css file is no longer available ...)


var styles = document.styleSheets;
for (var i = 0; i < styles.length; i++) {
	// checking if there is a request for template.css
	if (styles[i].href.match("template")) {
		console.log("(Iteration: " + i + ") Request for template.css is found.");
		// checking if the request is not successful
		// when it is successful .cssRules property is set to null
		if (styles[i].cssRules != null && styles[i].cssRules.length == 0) {
			console.log("(Iteration: " + i + ") Request for template.css failed.");
			// fallback, make your modification
			// since the request failed, we don't need to iterate through other stylesheets
			break;
		} else {
			console.log("(Iteration: " + i + ") Request for template.css is successful.");
			// template.css is loaded successfully, we don't need to iterate through other stylesheets
			break;
		}
	}
	// if there isn't a request, we fallback
	// but we need to fallback when the iteration is done
	// because we don't want to apply the fallback each iteration
	// it's not like our css file is the first css to be loaded
	else if (i == styles.length-1) {
		console.log("(Iteration: " + i + ") There is no request for template.css.");
		// fallback, make your modification
	}
}

TL;DR version

var styles = document.styleSheets;
for (var i = 0; i < styles.length; i++) {
	if (styles[i].href.match("css-file-name-here")) {
		if (styles[i].cssRules != null && styles[i].cssRules.length == 0) {
			// request for css file failed, make modification
			break;
		}
	} else if (i == styles.length-1) {
		// there is no request for the css file, make modification
	}
}


Update: Since my answer got a few upvotes and this led me to revise the code, I decided to update it.

// document.styleSheets holds the style sheets from LINK and STYLE elements
for (var i = 0; i < document.styleSheets.length; i++) {
	
	// Checking if there is a request for the css file
	// We iterate the style sheets with href attribute that are created from LINK elements
	// STYLE elements don't have href attribute, so we ignore them
	// We also check if the href contains the css file name
	if (document.styleSheets[i].href && document.styleSheets[i].href.match("/template.css")) {
		
		console.log("There is a request for the css file.");
		
		// Checking if the request is unsuccessful
		// There is a request for the css file, but is it loaded?
		// If it is, the length of styleSheets.cssRules should be greater than 0
		// styleSheets.cssRules contains all of the rules in the css file
		// E.g. b { color: red; } that's a rule
		if (document.styleSheets[i].cssRules.length == 0) {
			
			// There is no rule in styleSheets.cssRules, this suggests two things
			// Either the browser couldn't load the css file, that the request failed
			// or the css file is empty. Browser might have loaded the css file,
			// but if it's empty, .cssRules will be empty. I couldn't find a way to
			// detect if the request for the css file failed or if the css file is empty
			
			console.log("Request for the css file failed.");
			
			// There is a request for the css file, but it failed. Fallback
			// We don't need to check other sheets, so we break;
			break;
		} else {
			// If styleSheets.cssRules.length is not 0 (>0), this means 
			// rules from css file is loaded and the request is successful
			console.log("Request for the css file is successful.");
			break;
		}
	}
	// If there isn't a request for the css file, we fallback
	// But only when the iteration is done
	// Because we don't want to apply the fallback at each iteration
	else if (i == document.styleSheets.length - 1) {
		// Fallback
		console.log("There is no request for the css file.");
	}
}

TL;DR

for (var i = 0; i < document.styleSheets.length; i++) {
	if (document.styleSheets[i].href && document.styleSheets[i].href.match("/template.css")) {
		if (document.styleSheets[i].cssRules.length == 0) {
			// Fallback. There is a request for the css file, but it failed.
			break;
		}
	} else if (i == document.styleSheets.length - 1) {
		// Fallback. There is no request for the css file.
	}
}

Solution 3 - Javascript

Something like this will do (using jQuery):

function checkStyleSheet(url){
   var found = false;
   for(var i = 0; i < document.styleSheets.length; i++){
      if(document.styleSheets[i].href==url){
          found=true;
          break;
      }
   }
   if(!found){
       $('head').append(
           $('<link rel="stylesheet" type="text/css" href="' + url + '" />')
       );
   }
}

Solution 4 - Javascript

Peer to the comment made by JFK about the accepted answer:

> I understood the question as "how to check whether a css file is > loaded or not" rather than "how to check if the element > exists". > > The element may exist (and the path may be correct too) but it > doesn't mean that the css file was successful loaded.

If you access a link Element via getElementById you'll not be able to check/read the style defined inside the CSS file.

In order to check if a style has been successfully loaded we have to use getComputedStyle (or currentStyle for IE).

HTML

//somewhere in your html document

<div id="css_anchor"></div>

CSS

//somewhere in your main stylesheet

#css_anchor{display:none;}

JAVASCRIPT

//js function to check the computed value of a style element
    
function get_computed_style(id, name){

		var element = document.getElementById(id);

		return element.currentStyle ? element.currentStyle[name] : window.getComputedStyle ? window.getComputedStyle(element, null).getPropertyValue(name) : null;

}

 //on document ready check if #css_anchor has been loaded

    $(document).ready( function() {
    	
    		if(get_computed_style('css_anchor', 'display')!='none'){

            //if #css_anchor style doesn't exist append an alternate stylesheet
    		
    			var alternateCssUrl = 'http://example.com/my_alternate_stylesheet.css';
    
    			var stylesheet = document.createElement('link');
    			
    			stylesheet.href = alternateCssUrl;
    			stylesheet.rel = 'stylesheet';
    			stylesheet.type = 'text/css';
    			document.getElementsByTagName('head')[0].appendChild(stylesheet);
    			
    		}
    });

Part of the answer comes from: https://stackoverflow.com/questions/16748813/mydiv-style-display-returns-blank-when-set-in-master-stylesheet

Demo here: http://jsfiddle.net/R9F7R/

Solution 5 - Javascript

Apart from all the nice answers above, you can simply put a dummy element inside your markup and in your css file, give it any style other than default. Then in the code check if the attribute is applied to the dummy element, and if not, load the css. Just a thought though, not a neat way to do that thing you want done.

Solution 6 - Javascript

My 2 cents. This checks whether there are any rules set on the css or not, meaning that it was or not successfully loaded

if(jQuery("link[href='/style.css']").prop('sheet').cssRules.length == 0){
    //Load the css you want
}

Solution 7 - Javascript

The document object contains a stylesheet collection with all the loaded stylesheets.

For a reference see http://www.javascriptkit.com/domref/stylesheet.shtml

You can loop this collection to verify that the stylesheet you want to verify is in it and thus loaded by the browser.

document.styleSheets[0] //access the first external style sheet on the page

There are some browser incompatibilities you should look out for though.

Solution 8 - Javascript

One way: use document.getElementsByTagName("link") iterate over each and check if its href is equal to the CSS file you check.

Another way: if you know some CSS rule being set only in that file, check if this rule really apply e.g. check if background of something is really red.

Solution 9 - Javascript

var links = document.getElementsByTagName('link');
var file  = 'my/file.css';
var found = false;

for ( var i in links )
{
    if ( links[i].type == 'text/css' && file == links[i].href ) {
        found = true; break;
    }
}

if ( !( found ) ) {
    var styles = document.getElementsByTagName('style');
    var regexp = new RegExp('/\@import url\("?' + file + '"?\);/');

    for ( var i in styles )
    {
        if ( styles[i].src == file ) {
            found = true; break;
        } else if ( styles[i].innerHTML.match(regexp) ) {
            found = true; break;
        }
    }
}

if ( !( found ) ) {
    var elm = document.createElement('link');
        elm.href = file;
    document.documentElement.appendChild(elm);
}

Solution 10 - Javascript

You can either check if the filename is within your markup, like:

var lnks    = document.getElementsByTagName('link'),
    loadcss = true;

for(var link in lnks) {
    href = link.getAttribute('href');
    	
    if( href.indexOf('foooobar.css') > -1) ){
            loadcss = false;
            return false;
    }
});

if( loadcss ) {
    	var lnk     = document.createElement('link'),
        	head   	= document.getElementsByTagName('head')[0] || document.documentElement;        

        lnk.rel     = 'stylesheet';
        lnk.type    = 'text/css';
        lnk.href    = '//' + location.host + 'foooobar.css';            
        
        head.insertBefore(lnk, head.firstChild);
}

or you could check for a specific className which should be available, if the stylesheet was loaded. This probably comes a little closer to a feature detection.

Solution 11 - Javascript

For a nice consistent and repeatable experience, I've written these two jQuery plugins that mimic the $.getScript(url, callback) jQuery method (however they will NOT force reloading from the server like $.getScript(). There are two methods: one that will load a CSS file anytime it's called, and one that will only load it once. I find the former handy during development when I'm making changes, and the latter great for a speedy deployment.

/**
 * An AJAX method to asynchronously load a CACHED CSS resource
 * Note: This removes the jQuery default behaviour of forcing a refresh by means
 * of appending a datestamp to the request URL. Actual caching WILL be subject to
 * server/browser policies
 */
$.getCachedCss = function getCachedCss(url, callback)
{
	$('<link>',{rel:'stylesheet', type:'text/css', 'href':url, media:'screen'}).appendTo('head');

	if (typeof callback == 'function')
		callback();
}

/**
 * An AJAX method to asynchronously load a CACHED CSS resource Only ONCE.
 * Note: This removes the jQuery default behaviour of forcing a refresh by means
 * of appending a datestamp to the request URL. Actual caching WILL be subject to
 * server/browser policies
 */
$.getCachedCssOnce = function getCachedCssOnce(url, callback)
{
	if (!$("link[href='" + url + "']").length) {
		$.getCachedCss(url, callback);

		if (typeof callback == 'function')
			callback();
	}
}

Usage example:

$(function() {
    $.getCachedCssOnce("pathToMyCss/main.css");
)}

Usage example with callback:

$(function() {
    $.getCachedCssOnce("pathToMyCss/main.css", function() {
        // Do something once the CSS is loaded
});

Solution 12 - Javascript

use .sheet in jQuery:

HTML:

<link rel="stylesheet" href="custom.css">

jQuery:

if($("link[href='custom.css']")[0].sheet.cssRules.length==0){
//custom.css was not loaded, do your backup loading here
}

Solution 13 - Javascript

simple way using javascript..,

loadCssIfNotLoaded('https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css');
loadCssIfNotLoaded('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css');

function loadCssIfNotLoaded(url) {
	var element=document.querySelectorAll('link[href="' + url + '"]');
	if (element.length == 0)
	{
		var link = document.createElement('link');
		link.rel = 'stylesheet';
		link.href = url;
		document.getElementsByTagName("head")[0].appendChild(link);
	}
}

Solution 14 - Javascript

In one line, with jQuery. If the #witness div is visible, we have to load the css file.

In the HTML, we have a:

<div id="witness"></div>

In the CSS file to load, we have:

  #witness{display:none;}

So, if the css file is loaded, the #witness div is not visible. We can check with jQuery and make decision.

!$('#witness').is(':visible') || loadCss() ;

As a snippet:

function loadCss(){
  //...
  console.log('Css file required');
};


!$('#witness').is(':visible') || loadCss();

#witness{display:none;}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<div id="witness"></div>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionforelineView Question on Stackoverflow
Solution 1 - JavascriptAndy EView Answer on Stackoverflow
Solution 2 - JavascriptakinuriView Answer on Stackoverflow
Solution 3 - JavascriptSean Patrick FloydView Answer on Stackoverflow
Solution 4 - JavascriptRafaSashiView Answer on Stackoverflow
Solution 5 - JavascriptSamnanView Answer on Stackoverflow
Solution 6 - JavascriptjpbourbonView Answer on Stackoverflow
Solution 7 - JavascriptPeterView Answer on Stackoverflow
Solution 8 - JavascriptShadow Wizard Says No More WarView Answer on Stackoverflow
Solution 9 - JavascriptjoksnetView Answer on Stackoverflow
Solution 10 - JavascriptjAndyView Answer on Stackoverflow
Solution 11 - Javascriptsean.boyerView Answer on Stackoverflow
Solution 12 - JavascriptxamView Answer on Stackoverflow
Solution 13 - JavascriptAdith SureshView Answer on Stackoverflow
Solution 14 - JavascriptPhilippe PerretView Answer on Stackoverflow