In order for my webpage to degrade gracefully, I have some CSS that should only be loaded if its corresponding JavaScript will function.
What is the simplest way to load local CSS if and only if the browser has JavaScript enabled?
Also it's quite a big block of CSS, so I'd rather not have to write a JavaScript line to add each attribute. (Oh, and if necessary I can use jQuery).
Set a class on the body tag of "noJS". Then use Javascript to remove that class.
For the CSS rules that you want to be used when no JS is present, just use .noJS .myRules {}
In the <head> you can include it with document.write(). I've never tried this, but it should work in theory. No script execution means no stylesheet loaded.
<head>
<script type='text/javascript>
document.write("<link rel='stylesheet' href='your.css' media='whatever />");
</script>
</head>
You have a few options.
The one I like is to add the following code to the body tag.
<body id="no-js"><script>document.body.id="js"</script>
Then I can target #no-js and #js from my master CSS.
An additional option is to load an extra stylesheet with JavaScript, but that will slow down you initial load, which I try to avoid.
Check out the body conditionals for html5 boilerplate to see how to employ modernizr.
Also good example here: http://webdesignernotebook.com/css/how-to-use-modernizr/
Then write your css selectors for .no-js .addl-selector {}
I simply do this:
document.documentElement.className = "js"
This adds class js to <html> tag, then you can target your elements by css using:
.js #someid{}
Related
I am using embeded JS code for a service I need included in my website. It is embedding its own <style> CSS along with the HTML elements. It is a new service and there is no support for sending anything else. How can I ignore the <style> so I can use my own CSS to integrate into the theme? I don't want to resort to using !important flags.
As long as you use same classes for your CSS and you include it after the JS code loads it (assuming it loads it synchronously) your classes will override the default settings.
The way the CSS is rendered - if there is a conflict between declaration the instructions passed "later" prevail.
<html>
<head>
YOUR JS HERE
YOUR CSS to override your JS imported rules
</head>
<html>
You need to make sure you understand how CSS assesses the "weight" of the instructions though (important, inline style, id, class, html tag)
https://css-tricks.com/specifics-on-css-specificity/ - here is a decent explanation how it works.
I ended up adding !important to my CSS file since the JS file is loaded asynchronously and it would be more work to keep checking until it is loaded to remove the <style>.
It seems to me that anytime there is a <script src="name1.js"> or a <link href="name2.css"> statement in the <head>, these two files block rendering of the markup.
FWIW, I have tried adding "async" to the <script> tag and it totally messes up some of my jQuery plug-ins
Given that, I really do not understand the phrase "Render-blocking Javascript and CSS".
Thanks!
They block rendering of markup because the browser parses the HTML file from top down.
You can avoid this by placing the script tag before the closing body:
<script src="whatever.js"></script>
</body>
You're out of luck with link elements, unless you just use inline style declarations in the head (probably not a good idea).
You can also use the async attribute in the script tag, or you can use one of any numerous async JavaScript libraries.
You can also try to load the critical css first before loading the main/minified css file to avoid render blocking on CSS files.
I am using the following JS to avoid a flash of unstyled content in a SEO-friendly way:
<script type="text/javascript">
$('#Container').addClass('fouc');
$(document).ready(function() {
$('#Container').show();
});
</script>
Which also has the accompanying CSS: <style> .fouc {display:none;}</style>.
What I am expecting to happen is that on page load, at the very minimum, my div #Container should at the class .fouc added, however, this only occurs if I manually add it via the console.
Do I need some additional code etc in order to get this to function as expected?
FYI, I am already calling JQuery prior to when this script is being called.
Your help is appreciated!
The best way to avoid a FOUC is to put all of your links to your CSS files in the <head> element. This way the styling rules will load before the content, which will then be styled. This is both SEO and user friendly.
I was reading up on some JavaScript to try and create my own slider and I came across something that confused me a little. There was a CSS rule that was as follows:
html.js #slideshow .slides img
{
position: absolute;
}
The explanation said that the rule would only be applied if JavaScript was available. Now I'm a bit confused... Would this rule be applied if JavaScript is available in the browser? Or if the file "html.js" had been included in the html page, or if any JavaScript files were included?
Thanks in advance.
It's a technique where you use javascript to add class 'js' to the html tag. No javascript, no js class. Makes it very easy for your CSS to know if JS is enabled.
Probably in your page you have a script on the head that adds a js class to the root element
this will ensure that the CSS rule will be applied only if javascript is available on the client. Of course if javascript is not available the class won't be inserted by the script.
It's a modern approach used especially to prevent the flash of unstyled content (FOUC)
The page you saw is probably using Modernizr. It is a JavaScript library that detects HTML5 and CSS3 features in the user’s browser and works by adding a class "no-js" to the HTML element and when the page loads Modernizr replace it with set of rules that you're testing.
Check Modernizr website for more details if you want to test specific feature in a browser.
Of ir you don't want to use Modernizr you can do it with JavaScript by placing this directly within your <title> tag :
<script>
document.documentElement.className = document.documentElement.className.replace(/(\s|^)no-js(\s|$)/, '$1' + 'js' + '$2');
</script>
I'm learning Javascript and CSS and have run into an issue where my CSS styles aren't being applied to markup that I'm dynamically generated from XML and writing to document after the page has loaded. I can only assume that the styles aren't being applied because I'm modifying the document after it's already been loaded. Is this correct? If this isn't the case, do you have any ideas as to why the styles aren't being applied?
This javascript code...
$(function()
{
//Dynamically generate markup
strMarkup = GenerateMarkupFromXML();
//Display the dynamically generated markup
document.write(strMarkup);
});
dynamically generates this simple markup...
<div id="accordion"><h3>Title1</h3><h3>Title2</h3></div>
but these styles don't ever seem to be applied and the <h3> tags just get displayed with the default browser style...
h3
{
background-color:#ccc;
color:#003300;
font-size:1.1em;
}
I should also note that when I paste the dynamically generated markup directly into the body, the styles are applied correctly.
Thanks in advance for all your help!
Yes... the styles will be applied to any dynamically added markup.
The document.write() portion of your code may be causing problems here. In general, you should only use document.write() inline as the document is loaded and parsed. If you call it on DomReady as you seem to be doing it will overwrite your entire page, which I guess is what's causing the problem. I haven't tested though.
I'm not that familiar with jQuery, but instead of the document.write() line try doing something along the lines of (untested):
$('body').append('<div id="accordion"><h3>Title1/h3><h3>Title2</h3></div>');
Yes, css applied automatically. Your example don't work because document.write is evil )
It rewrites whole document with your custom styles, I suggest. If you want to use document.write call it in appropriate section of document, not in head. Example:
<head>
<style>
h3
{
background-color:#ccc;
color:#003300;
font-size:1.1em;
}
</style>
</head>
<body>
<script>
document.write('<div id="accordion"><h3>Title1</h3><h3>Title2</h3></div>');
</script>
</body>
Yes, CSS styles are applied to markup that is added after the page loads.
It could be that you aren't actually generating the same code that you think you are. Try selecting the generated code and doing "View Selection Source" in Firefox. This shows you the generated source (i.e. not just the static content that was served when the page was loaded).
Edit
I think there is a problem with using document.write() in the document ready function.. seems to be causing some kind of infinite loop (for me in Firefox, the browser keeps spinning the loading icon on the tab, even though the file is on my local machine). The $('body').append(strMarkup); solution posted by Andy works, though, as does $('body').html(strMarkup);;