SHARE
Facebook X Pinterest WhatsApp

Create Custom CSS Selectors in jQuery

Written By
thumbnail
Rob Gravelle
Rob Gravelle
Sep 18, 2017

jQuery’s powerful selectors are considered to be one of its best features. Not only do they closely resemble natural CSS, but jQuery beefs them up with a bunch of their own pseudo-class selectors. The icing on the cake is that jQuery’s pseudo-class selectors are fully extendable. In today’s tutorial we’ll learn how to assign functions to the expr[‘:’] object to create our own custom selectors.

How jQuery’s Pseudo-class Selectors Work

A CSS pseudo-class is a colon-prefixed keyword added to a selector that specifies a special state of the selected element(s). For example, “:hover” matches an element such as a link or button when the user hovers over it. These can be used with other information or on their own – i.e “button:hover” vs. “:hover”. jQuery’s own pseudo-class selectors include :button, :checkbox, :eq(), :even, :file, :first, :gt(), :has(), :header, :hidden, :image, :input, :last, :lt(), :odd, :parent, :password, :radio, :reset, :selected, :submit, :text, and :visible.

Here’s some code that selects all <button> elements and <input> elements of “type=’button'” and hides them:

$(":button").hide();

Note that extension selectors cannot take advantage of the performance boost offered by the native DOM querySelectorAll() method. Therefore jQuery’s documentation recommends that you first select some elements using a pure CSS selector and then pass the pseudo-class selector to the jQuery filter() function to achieve optimal performance. With that in mind, here’s some code that sets the background color of all odd-indexed table rows to blue:

$('tr').filter(':odd').css('background-color', 'blue');

Defining Custom Selectors

jQuery implements pseudo-class selectors as properties of the expr[‘:’] object, which is an alias for Sizzle.selectors.filters. It uses the following syntax:

$.expr[':'].selectorName = function(elem, [index], [match]) { /* ... */ }

This above syntax specifies selectorName as an attribute of expr[‘:’]. The anonymous function assigned to this property is invoked for each element in the current collection with the element. It behaves as a filter, returning true to keep the element in the collection or false to remove it from the collection. Note that the element’s index in the collection and a match array as arguments are both optional.

Here’s a selector that targets all elements that can receive focus, i.e. links, buttons, form elements (excluding type=’hidden’), having a tab index:

$.expr[':'].focusable = function (el) {
    return $(el).is('a, button, :input[type!=hidden], [tabindex]');
}

The focusable() function above cleverly delegates to one of jQuery’s own selectors: is() checks the current matched set of elements against a selector, element, or jQuery object and returns true if at least one of these elements matches the given arguments.

In fact, employing more generic selectors within our own is a pattern that should be considered a best practice in custom selector creation.

Now you can use your selector just like you would jQuery’s built-in selectors:

//turn all focusable fields red!
$(':focusable').css('color', 'red');

Defining Multiple Selectors at Once

If you’d like to define all of your custom selectors in one fell swoop, you can use the jQuery.extend() function. Just pass all of your functions in an object literal like so:

jQuery.extend(jQuery.expr[':'], {
    focusable: function (el) {
        return $(el).is('a, button, :input[type!=hidden], [tabindex]');
    },
    notopborder: function(el) {
        return $(el).css("border-top-style") == "none";
    }
});

Using the Match Parameter

The match parameter is actually an array that carries meta information about our selector. Here is what it would contain:

$('a:test(argument)');
//match would carry the following info:
[
    ':test(argument)', // full selector
    'test',            // only selector
    '',                // quotes used
    'argument'         // parameters
]

//for:
$('a:test("arg1, arg2")');
//match would carry the following info:
[
    ':test('arg1, arg2')', // full selector
    'test',                // only selector
    '"',                   // quotes used
    ['arg1, arg2']         // parameters
]

As an example, let’s define a custom selector that targets elements based on their border type. It would be passed to the function within the third element of the match parameter.

We could then do something to the matched elements such as change their border styles:

//match would carry the following info:
/*    
[
   "borderstyle", 
   "borderstyle", 
   "", 
   "solid"
]
*/
borderstyle: function(elem, index, match) {
    return $(elem).css("border-top-style") == match[3];
}

$('#btnChangeBorder').click(function() {
  $(":borderstyle('solid')").css("border-style", "dashed");
});

Here‘s a demo of today’s examples.

Conclusion

The ability to extend the expr[‘:’] object to create our own custom selectors is just one of the reasons that the jQuery library remains a major player in JavaScript development. Combined with its other DOM methods, it makes manipulating page elements a snap!

Recommended for you...

Importing Custom Less Styles at Run-time in Angular
Rob Gravelle
Jun 14, 2022
Setting CSS Values from Less Variables in Angular
Rob Gravelle
Jun 4, 2022
Color Manipulation with JavaScript
Rob Gravelle
May 21, 2022
An Introduction to CSS-in-JS
Rob Gravelle
May 14, 2022
HTML Goodies Logo

The original home of HTML tutorials. HTMLGoodies is a website dedicated to publishing tutorials that cover every aspect of being a web developer. We cover programming and web development tutorials on languages and technologies such as HTML, JavaScript, and CSS. In addition, our articles cover web frameworks like Angular and React.JS, as well as popular Content Management Systems (CMS) that include WordPress, Drupal, and Joomla. Website development platforms like Shopify, Squarespace, and Wix are also featured. Topics related to solid web design and Internet Marketing also find a home on HTMLGoodies, as we discuss UX/UI Design, Search Engine Optimization (SEO), and web dev best practices.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.