May sound odd, but I'm looking for a simple way to test if any mediaqueries are supported on a browser.
I know there is respondjs, which comes with a window.matchMedia polyfill, but even using it, I still have to query specific queries like:
window.matchMedia("all and (min-width: 400px"));
which returns an obj.matches = true/false.
What I'm looking for is a generic way to test, "if mediaQueries are supported", yes or no.
I'm currently using:
window.matchMedia("screen and (orienation:landscape),
screen and (orientation:portrait)");
but I don't really like this way of testing.
I also tried:
window.matchMedia("all");
but this (of course) returns true in IE8 when using the matchMedia polyfill. Also, I can't test for matchMedia itself, because I would miss out on a lot of browsers that support media queries, but not window.matchMedia (caniuse).
Question:
Is there a nice and simple way to test for media query support? If possible, I would not want to use window.matchMedia at all to do that.
EDIT:
I also checked Modernizr, which also tests for a specific mediaQuery condition (mq):
testMediaQuery = function( mq ) {
var matchMedia = window.matchMedia || window.msMatchMedia;
if ( matchMedia ) {
return matchMedia(mq).matches;
}
var bool;
injectElementWithStyles('#media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
bool = (window.getComputedStyle ?
getComputedStyle(node, null) :
node.currentStyle)['position'] == 'absolute';
});
return bool;
},
So no generic test, if mediaQueries are supported.
U can choose this option in modernizr
http://modernizr.com/download/
Related
Is there a way to detect, using Javascript or jQuery, whether the browser supports position:sticky or not?
I know most modern browsers support it, but some older browsers and some mobile browsers don't.
I'm not interested in a polyfill. I want to take certain actions only if position:sticky works, otherwise just leave things as they are.
A great and powerful way to check if a CSS feature is available is to use the CSS.supports JavaScript function:
if (CSS && CSS.supports && CSS.supports("position", "sticky")) {
// awesome: position:sticky is supported on this browser!
} else {
// fallback: I cannot rely on position:sticky!
}
I hope this answers your question, but I think it's worth mentioning that if you're tempted to use CSS.supports() you should at least consider responding to a lack of feature just using CSS alone. While JavaScript is a great way to make dynamic changes to a page, you often don't need it to have your page respond to a lack of a feature. This is especially for CSS features like sticky.
E.g.
/*
...
Basic styles for old browsers that don't support sticky go here.
...
*/
#supports (position:sticky) {
/* Overrides to the above styles for modern "sticky" browsers go here */
}
And even then, you often don't even need to go this fancy. For example, let's say you have a nav bar that you would like to be position:sticky if possible, but otherwise just position:absolute. Even though some browsers don't understand sticky, you can say:
.my-nav-bar {
/* The fallback goes first */
position: absolute;
/* This 'enhancement' is ignored if not understood, */
/* but overrides the previous value if the browser supports it. */
position: sticky;
top: 50px;
/* ... etc ... */
}
From modernizr:
/*!
{
"name": "CSS position: sticky",
"property": "csspositionsticky",
"tags": ["css"],
"builderAliases": ["css_positionsticky"],
"notes": [{
"name": "Chrome bug report",
"href":"https://bugs.chromium.org/p/chromium/issues/detail?id=322972"
}],
"warnings": ["using position:sticky on anything but top aligned elements is buggy in Chrome < 37 and iOS <=7+"]
}
!*/
define(['Modernizr', 'createElement', 'prefixes'], function(Modernizr, createElement, prefixes) {
// Sticky positioning - constrains an element to be positioned inside the
// intersection of its container box, and the viewport.
Modernizr.addTest('csspositionsticky', function() {
var prop = 'position:';
var value = 'sticky';
var el = createElement('a');
var mStyle = el.style;
mStyle.cssText = prop + prefixes.join(value + ';' + prop).slice(0, -prop.length);
return mStyle.position.indexOf(value) !== -1;
});
});
Source: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/css/positionsticky.js
with:
prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
Source: https://github.com/Modernizr/Modernizr/blob/master/src/prefixes.js
Working example (w/o Modernizr dependencies):
function browserSupportsPositionSticky() {
var prop = 'position:';
var value = 'sticky';
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var el = document.createElement('a');
var mStyle = el.style;
mStyle.cssText = prop + prefixes.join(value + ';' + prop).slice(0, - prop.length);
return mStyle.position.indexOf(value) !== -1;
};
console.log(browserSupportsPositionSticky());
I'm looking for a solution how we can detect the support of css flex-box and flex-wrap by JavaScript.
I'm aware of modernizr which can do the job but my client does not allow us to load any scripts inside the head section, unfortunately this does not work when loading in the footer.
What is a proper way to achieve this detection on all kind of browsers / devices?
how we can detect the support of css flex-box and flex-wrap by
JavaScript.
Create an element and check the style property. If it is supported, it will return nothing i.e. '' else it will return undefined.
For example, if you run the below snippet in Chrome you will get undefined for columns and '' for flex-wrap.
Snippet:
console.log('flex = ' + document.createElement("p").style.flex);
console.log('columns = ' + document.createElement("p").style.columns);
console.log('flex-wrap = ' + document.createElement("p").style.flexWrap);
Although you have mentioned only Javascript in your question, but there is a CSS way of feature detection as well.
The #supports rule, also called CSS Feature Queries.
You provide the CSS declaration as the condition and the browser will execute that to return whether it supports or not. For example, the following CSS will apply green background color if flex is supported.
#supports (display: flex) {
div { background-color: #0f0; }
}
The browser support is good amongst all modern browsers, barring IE (as usual). For IE and (Safari < 9), you will need to keep a fallback option when #supports rule fails.
Combining the above two, there is an API around that as well which you can use in Javascript to do feature detection.
var isColumnSupported = CSS.supports('columns', '');
console.log('columns supported: ' + isColumnSupported);
var isFlexWrapSupported = CSS.supports('flex-wrap', 'wrap');
console.log('flex-wrap supported: ' + isFlexWrapSupported);
Since CSS.supports() is not supported on IE
This robust method can test any property:value support:
var cssPropertySupported = (function(){
var mem = {}; // save test results for efficient future calls with same parameters
return function cssPropertySupported(prop, values) {
if( mem[prop+values] )
return mem[prop+values];
var element = document.createElement('p'),
index = values.length,
name,
result = false;
try {
while (index--) {
name = values[index];
element.style.display = name;
if (element.style.display === name){
result = true;
break;
}
}
}
catch (pError) {}
mem[prop+values] = result;
return result;
}
})();
///////// TEST: ////////////////////
console.log(
cssPropertySupported('display', ['-ms-flexbox', '-webkit-box', 'flex'])
)
You manually need to provide the test function all the possible property names since the code cannot guess (too many possibilities). This keeps the test code slim instead of it have all possible property names already within it.
I am wondering if there is a way to use media queries in javascript like i use it in CSS ?
i want to handle device-width or orientation and fire a function .
now i am using this code :
window.onresize = function(event) {
/* test for various sizes */
};
but it is no good for me , i don't know how to make it work .
i need it to work in latest chrome without third parity libraries , i'm not sure if it is possible .
I would suggest using window.matchMedia method , wich allows you to test for a particular media query and add an event listener whenever it's matched or not .
Example :
var mq = window.matchMedia("(max-width: 600px)");
mq.addListener(function(event){
if (event.matches) {
console.log("Small Screen mode !");
}
});
Example 2:
onOrientationChange = function(event){
if (event.matches) {
console.log("Portrait mode!");
}
};
var mq = window.matchMedia("(orientation: portrait)");
mq.addListener(onOrientationChange);
/* ... /*
/* When you no longer need to receive notifications , you can remove the listener */
mq.removeListener(onOrientationChange);
This API is supported in : Chrome 9+ , Firefox 6+ , IE10+
Additional info on MDN
Check out Responsive JavaScript. Sounds like it will do what you're looking for.
Try to use matchMedia (jQuery)
// media query event handler
if (matchMedia) {
var mq = window.matchMedia("(min-width: 500px)");
mq.addListener(WidthChange);
WidthChange(mq);
}
// media query change
function WidthChange(mq) {
if (mq.matches) {
// window width is at least 500px
}
else {
// window width is less than 500px
}
}
I'm looking for any javascript library that like modernizr (which actually does not) enables flexbox for "older browsers" (a polyfill).
Yea I know this is a really new feature (infact "there aren't" is a valid answer), but I'm hoping for something like this, I always have hard time with horizontal + vertical centering, this will really help and shorten the work.
I mean this flexbox: http://weblog.bocoup.com/dive-into-flexbox/ (the newest)
It might be too early for this. WebKit implemented it fairly recently, there's no hint of support in any mobile WebKit at all, Opera just released support for it, and Gecko's implementation is still in alpha. IE? Hah.
But as far as I can tell, no, there's no polyfill for the new flexbox. Flexie supports the old flexbox, and has a ticket open to support the new syntax... maybe you could give them a hand?
You could always use the old flexbox, I suppose, but then you're obsolete out of the gate. Sucky situation.
You're going to have to create your own.
http://www.sitepoint.com/detect-css3-property-browser-support/ has a section titled "Rolling Your Own Detection Code"
Basically you'll need something like this:
// detect CSS display:flex support in JavaScript
var detector = document.createElement("detect");
detector.style.display = "flex";
if (detector.style.display === "flex") {
console.log("Flex is supported");
}
else
{
console.log("Flex is not supported");
}
To expand on that and create a function:
function DetectDisplayValue(val)
{
// detect CSS display:val support in JavaScript
//
var detector = document.createElement("detect");
detector.style.display = val;
if (detector.style.display === val) {
console.log("Display value: " + val + " is supported");
}
else
{
console.log("Display value: " + val + " is not supported");
}
}
How do I detect if a browser supports HTML5 by
JS
(or)
jquery AND mootools.
Use modernizr to detect HTML5 and CSS features.
As the other suggested the best option is to use Modernizr, because it was created especially to do this work.
I don't know any plugin in jQuery that covers this functionality (jQuery.supports doesn't check much) but if you want you could try mooModernizr witch extends MooTools Browser.Features object
Another completely valid option is to check Modernizrs source code, and implment that with the features you want to detect.
To detect the video tag support is quite easy:
if (typeof HTMLVideoElement == 'function') {
alert('<video> tag supported');
}
That's in my opinion a simplistic version. Here is how the many times mentioned modernizr does it, which is a bit more bullet proof probably:
function supportsVideo() {
var elem = document.createElement('video'),
bool = false;
// IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
try {
if ( bool = !!elem.canPlayType ) {
bool = new Boolean(bool);
bool.ogg = elem.canPlayType('video/ogg; codecs="theora"');
// Workaround required for IE9, which doesn't report video support without audio codec specified.
// bug 599718 # msft connect
var h264 = 'video/mp4; codecs="avc1.42E01E';
bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
}
} catch(e) { }
return bool;
}
Check out modernizr. It is an open source javascript library that specializes in detection of html5 / css3 features:
http://www.modernizr.com/