Test If a Browser Supports a CSS Selector

Test if a browser supports a CSS selector

Workaround for your case:

<input type=checkbox checked=checked>

css:

input{
font-family:'arial';
}
input:checked{
font-family:'sans-serif';
}

checking procedure: js

alert($('input').css('font-family')=='sans-serif'?'supported':'not supported');

How to check if css value is supported by the browser?

I assume you meant to check whether the vh value is supported, not whether specifically DIV#id bears it?

function cssPropertyValueSupported(prop, value) {
var d = document.createElement('div');
d.style[prop] = value;
return d.style[prop] === value;
}
cssPropertyValueSupported('width', '1px');
// => true
cssPropertyValueSupported('width', '1vh');
// => maybe true, maybe false (true for me)
cssPropertyValueSupported('width', '1foobar');
// => false

How to detect if browser support specified css pseudo-class?

You can simply check if your style with pseudo-class was applied.

Something like this: http://jsfiddle.net/qPmT2/1/

How do I test CSS selectors in JavaScript?

The simplest traditional way by far is to not use JavaScript at all, and just set up a test page by hand where you can test selectors to your heart's content. The test cases you see on the Web (like the well-known CSS3.info Selectors Test) are really just souped-up versions hosted online.

But if you're looking for a JavaScript method, you can try the Selectors API. It's available in modern DOM implementations (IE8+ and others) and it provides a JavaScript frontend for querying the DOM for element nodes using CSS selectors, as well as testing CSS selectors natively supported by a given browser.

(For browsers that don't implement the Selectors API, you'll have to rely on jQuery, but remember that it provides support for a different set of selectors than what a browser supports as well as its own non-standard extensions which aren't found in the Selectors spec. An example of using jQuery with Chrome's JavaScript console to test a selector can be found here.)

Call querySelector() or querySelectorAll() depending on what you want to test, and check the return value (preferably in your browser's developer tools since you're just testing):

  • If matches are found, the former method returns the first Element matched while the latter returns all elements matched as a NodeList.

  • If nothing is found, the former returns null while the latter returns an empty NodeList.

  • If the selector is invalid, an exception will be thrown which you can catch.

Here are some examples with the command editor (multiline) in Firebug's console on Firefox 10, tested on this very question:

  • Finding the first h1 in body:

    var h1 = document.body.querySelector('h1');
    console.log(h1);
    <h1 itemprop="name">
  • Querying descendants of that h1 element we just found:

    var subnodes = h1.querySelectorAll('*');
    console.log(subnodes[0]);
    <a class="question-hyperlink" href="/questions/9165859/how-do-i-test-css-selectors-in-javascript">
  • Testing the :-moz-any() pseudo-class in Firefox (:-webkit-any() in Safari/Chrome):

    // This selector works identically to h1 > a, li > a
    var hyperlinks = document.querySelectorAll(':-moz-any(h1, li) > a');
    console.log(hyperlinks);
    [a#nav-questions /questions, a#nav-tags /tags, a#nav-users /users, a#nav-badges /badges, a#nav-unanswered /unanswered, a#nav-askquestion /questions/ask, a.question-hyperlink /questio...vascript]
  • Testing a nonexistent selector (that perhaps many of us wish did exist):

    // :first-of-class doesn't exist!
    var selector = 'div.answer:first-of-class';

    try {
    var firstAnswer = document.querySelector(selector);
    console.log(firstAnswer);
    } catch (e) {
    console.log('Invalid selector: ' + selector);
    }
    Invalid selector: div.answer:first-of-class

What is the most practical way to check for @supports support using only CSS?

@supports currently only tests property/value combinations, and nothing else. Your other options don't work because none of them are valid (including the last one with just the at-keyword followed by the opening brace!). The property/value pair requirement is dictated by the grammar for @supports, which you can find in the spec.

Simply test for a property/value pair that you know is guaranteed to work across all user agents whether or not @supports is implemented. This (sort of) eliminates the possibility that you'll run into a user agent that implements @supports but not that property/value combination, focusing on its support for @supports instead.

Your given example of display: block will suffice. Your use of the cascade to check if a browser does not implement @supports by overriding declarations within a @supports rule for browsers that do support it is also acceptable (being the only obvious way to do it anyway).

What happens when the browser doesn't support a CSS pseudo-class?

Browsers currently make no distinction between unrecognized or unsupported selectors, and invalid selectors. If a browser recognizes a selector, generally it'll have implemented it to the best of its ability (and any behavior that's not to spec can be classified as a bug on its bug tracker), even if it doesn't implement all other features in the same level of Selectors (as is currently the case with :dir() for example, and historically Internet Explorer 7 and 8 with level 3 attribute selectors, and Internet Explorer 6 with the universal selector). If it doesn't recognize the selector, it follows CSS2.1 §4.1.7 to the letter and drops the entire ruleset, no questions asked. Notice that it says

When a user agent cannot parse the selector (i.e., it is not valid CSS 2.1), it must ignore the selector and the following declaration block (if any) as well.

which implies that if a user agent cannot parse a selector, it must therefore be invalid CSS2.1 (or invalid in some other level of Selectors); and inversely that if it can parse a selector, it must therefore be valid. But this assumes the user agent conforms fully to the standard; we all know that in reality, different implementations have different levels of conformance to each standard, and certain implementations even have their own vendor-specific selectors which are not part of any standard. So I treat this as "When a user agent cannot parse the selector" without the parenthetical, and I imagine browser vendors do the same.

In fact, Selectors itself makes no distinction between a pseudo-class token with an ident or function that doesn't correspond to a valid pseudo-class, and a series of characters that cannot even be parsed as a pseudo-class — they're both equally invalid — see section 12 of css3-selectors and section 3.9 of selectors-4. Essentially, this means that the current browser behavior is in full compliance with the standard, and not just an arbitrary decision agreed upon by browser vendors.

I've not heard of any browser that recognizes a pseudo-class as valid for the purposes of error handling, and proceeds to ignore either just that pseudo-class or the entire complex selector (leaving other complex selectors in the selector-list unaffected). WebKit did use to have a really bad habit of accepting CSS rules with unrecognized pseudo-elements, allowing things like ::selection, ::-moz-selection, which proved useless anyway because every other layout engine followed the spec more strictly. I believe WebKit no longer does this, however, but you know how WebKit is with these things. But AFAIK it has never done this with pseudo-classes.

On the standards side, selectors-4 appears set to change this with the introduction of the static and dynamic profiles. My email on the subject was addressed in a CSSWG telecon; you can find the minutes here (search for "Behavior of Selectors not in Fast Profile"). However, it was resolved that selectors not in the dynamic (previously fast) profile should be treated as invalid and cause the entire CSS rule to be dropped, as usual. See section 2.1:

CSS implementations conformant to Selectors Level 4 must use the dynamic profile for CSS selection. Implementations using the dynamic profile must treat selectors that are not included in the profile as unknown and invalid.

Detecting CSS Selector Support of Browser with jQuery

You are right that selecting an element with a jQuery selector will work even in browsers that do not support that selector in CSS.

However, you could apply a style with a CSS3 selector, and then select an element with jQuery to determine if that style has been applied.

For instance in CSS:

#myid > p {
display: none;
}

and then in jQuery:

if ( $( '#myid > p' ).css('display') != 'none' ) {
// blah
}

However be careful because .css() may not return what you expect. For instance if you apply a color like 'red', it will return rgb(255, 0, 0).

Sorry I know this isn't as perfect of a solution as Modernizr, but I hope it helps you in your situation.



Related Topics



Leave a reply



Submit