Difference between CSS selector and jQuery filter?

It is possible to pass CSS selectors to the jQuery function such as:

jQuery('h1 + h2');

jQuery also has some filters such as :even and :odd:

jQuery('tr:even');

I was looking for some sort of syntax rule which differentiates the two and I was thinking that maybe the jQuery filters always use a :.

However, some CSS selectors also use a :. For example:

  • :last-child
  • :root
  • :empty
  • :target

Does anyone have any smart tips for knowing if it is a CSS selector or a jQuery filter being used?


Solution 1:

I was looking for some sort of syntax rule which differentiates the two and I was thinking that maybe the jQuery filters always use a :.

However, some CSS selectors also use a :.

Does anyone have any smart tips for knowing if it is a CSS selector or a jQuery filter being used?

This is one of the most annoying things about selector libraries adopting CSS syntax within their own extensions: because both match-based filters and true pseudo-classes are lumped together in an umbrella term known as "pseudo-selectors" (which basically means "selectors that begin with a :"), the only way to tell whether a "pseudo-selector" is a filter or a true simple selector is by knowing what it does, which if you're unfamiliar with the selector often means referring to the jQuery documentation as mentioned by others here. You'll notice that most of these match-based filters will have the word "match" somewhere in their descriptions; that is a reasonable indicator that a "pseudo-selector" works as a match-based filter.

There is a subcategory of Selectors in jQuery called Basic Filters, however the name is completely misleading and the selectors themselves poorly categorized; not all of them are actual filters but some of them function like standard pseudo-classes! At least the jQuery Extensions category has a proper name — because these selectors are non-standard.

What I call a "match-based filter" is basically a selector that matches an element based on the entire complex selector leading up to that selector. Sound confusing? That's because it is.

In fact, for the sake of easy reference, here is a list of jQuery selectors that work as match-based filters:

  • :eq()
  • :gt()
  • :lt()
  • :even
  • :odd
  • :first
  • :last

These selectors return the nth element(s) among a set of matches, as opposed to other, standard selectors which take each element and make deductions of what it is based solely on the information about the element, provided by the DOM or otherwise, and not based on the rest of the selector string. While they are very often compared to :first-child, :last-child, :nth-child() and :nth-last-child(), they are vastly different in terms of functionality. Be very careful in choosing which selector to use.

For example, the following selector, using jQuery's :first:

$('ul > li:first')

Matches only one element: the first element matching the selector ul > li, regardless of how many ul and li elements there are in the DOM. This selector notation can be written as a method call like so:

$('ul > li').first()

Which makes it much clearer what it actually does. It differs from :first-child:

$('ul > li:first-child')

In that :first-child will select every li that is the first child of its parent ul, and can therefore potentially return one or more li elements, as opposed to exactly one with :first.

Also worth mentioning is the :not() selector; although I don't consider it as the same kind of filter as the above selectors, it's important to remember that jQuery extends it from what's actually offered in CSS. The differences are detailed in this question. I imagine that it's categorized under Basic Filters anyway because of .not(), which is most definitely for all its intents and purposes a filter method, and the antithesis of .filter().