I really want to make use of multiple background support (Webkit, Firefox 3.6+), but I would like to provide an alternative solution for browsers that don't support it. (IE, Firefox 3.5-).
Is there any way to detect support for this CSS feature? Or will I have to resort to browser sniffing?
EDIT: Javascript solutions are welcome
I know this is a relatively old question but I thought I would add a JS snippet that can be used to sniff this. The code is taken from the Modernizr source but has been modified a bit:
function multipleBgTest(){
var el_style = document.createElement("div").style;
el_style.cssText = 'background:url(//:),url(//:),red url(//:)';
// If the UA supports multiple backgrounds, there should be three occurrences
// of the string "url(" in the return value for el_style.background
return new RegExp("(url\\s*\\(.*?){3}").test(el_style.background);
}
If the function returns true then it is supported otherwise it will return false.
Use http://www.modernizr.com/. This is a piece of javascript that will set up classes depending on what features the browser have. You can then use these classes in CSS.
No there is no way in pure css to detect if multiple backgrounds are supported. But you can specify default background and then specify multiple backgrounds which resolves error with processing value and keeps old if it isn't supported.
Related
I need to determine whether a browser supports CSS' #page rule or not...
I first thought that I may be able to do this easily with CSS' #supports() rule. But my understanding now is that you cannot nest one rule in another and are only able to check the support of classic property/ value declarations.
Now I am trying to use vanilla JS to detect support:
if ('CSS' in window && CSS.supports('#page')) { ... }
However, this always returns false regardless of browser support.
Does anyone know an alternative way that I can accurately test client support for CSS' #page using vanilla JS?
TY.
What is the best way to detect browser compatibility for HTML 5 syntax? And prompt the user if the browser is not compatible?
I understand the tutorial which shows how to test browser compatibility for HTML5. But I am curious to know if that is the only way? Do I need to inspect each and every element?
Have a look at Modernizr:
Taking advantage of the new capabilities of HTML5 and CSS3 can mean
sacrificing control over the experience in older browsers. Modernizr 2
is your starting point for making the best websites and applications
that work exactly right no matter what browser or device your visitors
use.
Thanks to the new Media Query tests and built-in YepNope.js
micro-library as Modernizr.load(), you can now combine feature
detection with media queries and conditional resource loading. That
gives you the power and flexibility to optimize for every
circumstance.
It has a lot of built in methods to test for browser features and provides a useful way of providing fallback code for when features you want to use are not supported.
More info: http://www.modernizr.com/
"HTML5 compatibility" is a very vague thing.
When people ask about HTML5 compatibility, they generally mean "what browsers support these new-ish browser features X, Y and Z which I want to use?"
There are a whole raft of features which have been added to browsers in the last couple of years, and which are now commonly referred to as "HTML5".
In fact, there aren't any browsers which support every new feature out there.
What you need to do is work out which features have wide enough support to make them worth using, which features you'd like to use but are happy to work around if you encounter a browser that doesn't support them, and which features you absolutely have to use to achieve what you want to do.
A fairly comprehensive list of new browser features, along with browser support charts for them all is available at http://caniuse.com/ (if you scroll to the bottom, you'll see in the overall compatibility table that the very best current browsers only support 89% of features they've tested. This will improve over time as new versions are released... but of course, also new features will be introduced too)
For determining at run-time whether the user's browser supports a given feature, you can use Modernizr. This is a Javascript-based tool which will give you a set of CSS classes and Javascript flags which tell you what features are supported. You can use this to trigger alternate behaviour in your site if the browser doesn't support a feature you want. (Modernizr also includes the HTML5Shim functionality, which allows IE to at least cope with HTML pages containing new HTML5 elements).
For more cross-browser compatibility, there are a whole range of hacks which have been written to allow older browsers (mainly IE to be fair) to support a range of newer features. You can see a fairly comprehensive list of them here: https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills
Obviously, trying to run more than a few of these at once in IE will severely impare your site's performance, but it can be handy if you need to support one or two features. My favourite at the moment is CSS3Pie, which gives IE6/7/8 support for CSS rounded corners, shadows and gradients.
Hope that helps.
Here is a tutorial of detecting HTML5 compatibility & capabilities :
http://diveintohtml5.ep.io/detect.html
There are alternative HTML5 detectors using similar techniques, but I would suggest to use Modernizr.
To sum up the "score" of HTML5, you can design your own "marking scheme". Sum up weighted score gives you the total score.
The simplest method : in JS you create a new element, and set the attributes to be a colorpicker (HTML5) in JS, and return the type of the element (it is a picker only if the browser ic HTML5 compatible) :
var element = document.createElement("input");
element.setAttribute("type", "color");
return element.type !== "text";
do I need to inspect each and every element?
Nope. Only the parts you want to use that aren’t backwards-compatible.
See Five Things You Should Know About HTML5, especially points 1 and 4.
I would suggest you can try using <audio>Anything within Audio tag here</audio>.
Any text written inside the between <audio> and </audio> will be displayed in browsers that do not support the <audio> tag.
Since the audio tag is newly added in HTML5.
This works on IE 11 (and hopefully other browsers too).
// Detect HTML v5 compatibility
var isHtml5Compatible = document.createElement('canvas').getContext != undefined;
It's a take from Clement's answer and the link from Shivan (http://diveintohtml5.info/detect.html). Clement's answer didn't work in IE 11.
In my case I use jQuery UI for everything so don't need Modernizr (also it seemed slower). Reading the rather negative "How to use Modernizr" blog comments supports this assumption.
But now jQuery have split browser compatibility between v1 and v2 development streams, its necessary for people wanting to support non-HTML v5 browsers to load EITHER the v1 or v2 jQuery core script at the start. So this "one liner" HTML v5 detection is perfect. Here's how I load jQuery properly using the result:
// Use jQuery v2 for HTML v5 browsers else v1 to support old browsers
var jQueryScriptPath = (isHtml5Compatible)
? "/Scripts/jquery-2.0.3.js"
: "/Scripts/jquery-1.10.2.js";
document.writeln("<script src=\"" + jQueryScriptPath + "\" type=\"text/javascript\"><\/script>");
If you vote this answer up please also vote clement and Shivan's answers too :-)
I've been curious for a while with this now.
The css3 properties are not yet standardized, yet can be implemented by browsers, using a prefix for the particular browser.
For example, border-radius can be used, and it works fine on modern browsers. However, for previous versions of the browser vendors, we can use the vendor specific properties like -moz, -webkit, etc. prefixes to work.
Now, for my page, I have used gradients and border-radius, made a couple of classes that use them and applied these classes throught.
Which of the following is better to do?
Using javascript to find whether the support is there, and use the properties if they are supported, if above is false, check the user agent and apply vendor specific properties accordingly.
Using all the browser prefixes in the classes and let the browser use whichever suits it.
What I am curious and concerned about, is the performance and time for DOM loading.
Which of the following is better to do?
Using javascript to find whether the support is there, and use the properties if they are supported, if above is false, check the user agent and apply vendor specific properties accordingly.
Using all the browser prefixes in the classes and let the browser use whichever suits it.
Option 1 consists of using JavaScript to detect support, then conditionally writing out the CSS code with or without the prefixes and letting the browser apply the styles.
Option 2 consists of simply using CSS and relying on the browser to ignore prefixes/declarations it doesn’t understand.
As you can see, option 1 introduces an extra layer (JavaScript) which is not necessary if you just want to use some CSS3 features where possible. Option 2 will be the most performant solution.
As always with this kind of question, the answer is - it depends. It depends on which prefixes you're using, how often they occur in the HTML, which browser you're testing against, etc.
The solution is to write the code, profile it, and find out. Very often, you will find that the performance is acceptable either way.
I use option 2 - add all the browser prefixes (as well as the non-prefixed version) to the CSS:
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
Browsers will skip declarations they don't understand without any problems (although your CSS won't validate) while still applying the styles. It's probably best to use a CSS generator to avoid having to type out every prefix.
You should avoid using Javscript to detect CSS features since this breaks separation of concerns - CSS is for presentation and Javascript is for behaviour.
I used css 3, html 5 in a web page and I want to use Modernizr to show some html5 attributes and some css 3 such as border-radius on old browsers,
Does Modernizr help in this and how run it.
Modernizr will only help you detect certain features, so you'll have to add the JS fixes yourself.
In case you want to go for a pre-packaged solution this might be of help: https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills
In your case this might be the way to go: http://css3pie.com/
Modernizr doesn’t add missing functionality to older browsers other than the HTML5 Shiv so that you can use and style the new semantic elements from HTML5. The other answers already show some polyfill options, however, I recommend you reconsider adding purely-visual effects like border-radius to older browsers that way. Polyfills slow the older browsers down (sometimes very significantly) and make the overall experience much worse for those users.
You can use modernizr to detect what's available, e.g. rounded corners. If it's not, you can degrade gracefully via the modernizr API, or even use a plug-in to smoke and mirrors the feature.
<script type="text/javascript">
Modernizr.load({
test: Modernizr.borderradius,
nope: 'script/jquery.corner.js',
callback: function () {
$('article').corner();
$('figure').corner();
}
});
</script>
Code snippet taken from http://blogs.msdn.com/b/jennifer/archive/2011/08/04/html5-part-4-using-html5-while-retaining-support-for-older-browsers.aspx
Modernizr does not help with CSS3. (You could use Selectivizr for this, but it has some cross-domain issues you'll want to read about.)
Modernizr does have IEPP for HTML5 shim support and it comes with YepNope.js as Modernizr.load, which is a great polyfills loader mechanism so you can load your own support for older browsers. That will help you drop in support for attributes like pattern and placeholder without overloading browsers that have native support for it.
Modernizr internally uses the same JS code that you would use otherwise..
e.g. If you want to check for "input" placeholder support, using Native way, you would use;
function support_input_placeholder() {
var i = document.createElement('input');
return 'placeholder' in i;
}
While the Modernizr way to check would be like
function support_input_modern() {
if (Modernizr.input.placeholder)
return true;
else
return false;
}
But the above code has the same internal working as the native way...
So ideally, I would prefer native way for simpler and lesser amount of checking...
Only for very complex things, should we go for Modernizr
Where do I place this script in my HTML for it to work? And what changes do I have to make to it?
<script type="text/javascript">
var browser=navigator.appName;
if(browser="Microsoft Internet Explorer")
{
document.getElementById("html").innerHTML="\
<body><p>Your browser is IE.</p></body>";
}
</script>
Could I make a slightly alternate suggestion, skipping the spoofable UA string, and using a Microsoft-implemented (and standards-compliant) strategy:
<!--[if ie]>
<script type="text/javascript">
document.getElementyId("html").innerHTML = "<body><p>Your browser is IE.</p></body>";
</script>
<![endif]-->
To use this put it in the head of the document. I don't think it can be placed inside script tags (since it's based on html comment syntax, not JavaScript).
This uses conditional comments (Quirksmode.org link).
If at all possible, I would suggest avoiding direct browser detection.
Almost every case where someone wants to detect a specific browser (usually IE), it is because there is a particular feature that they want to use which isn't available in that browser, or has bugs.
But browser detection fails as a strategy here for a number of reasons:
You don't know whether a future version of that browser may correct the problem, in which case your code to fix the issue may itself cause problems.
If another browser also has a problem with that feature, you would have to detect that browser as well. Taken to the logical extreme, since no two browsers have exactly the same set of features, you end up having to detect every possible combination of browser, version and operating system.
Browser detection is virtually impossible to guarantee to be accurate. Most browser detection scripts are based on hacks that trigger quirks that only affect a particular browser, and most are pretty un-reliable.
Even just IE detecting isn't good enough. There is a big difference between IE6, IE7 and IE8. And IE9 is just around the corner, which will be massively different again.
So what should you do instead of browser detection?
Detect the feature. There are a number of ways of doing this, but the best solution I know of is a script called Modernizr. Place this script in your site, and your page will be given a bunch of CSS classes and Javascript properties which you can use to determine whether a given feature is available or not.For example, if you want to use gradients on your site, most browsers can use CSS for this, but IE and older versions of other browsers cannot. For these browsers you easily can use a background image instead. Modernizr will give you a CSS class of either cssgradients or no-cssgradients, and you can style these two classes accordingly.
Add the missing features to the browser. This is more tricky, but for certain features it can be done, particularly for IE. A good example is CSS3Pie which is a hack that allows IE to use the CSS border-radius feature (and one or two other features too) which is available in all other browsers. There are whole range of other little scripts like this which can improve the functionality of IE.
Use a library like JQuery which does all this work for you. With JQuery, you can be much more confident that most of your Javascript code is going to work across all browsers.
If you must use browser detection to tell if the user is running IE (and I accept that there are some occasions when it is necessary), then use conditional comments, as per #David Thomas's answer. But do so sparingly, after considering any other ways around it.
if(browser=="Microsoft Internet Explorer")
== for comparison, = for assignment
Place it in the head tags.