If you’ve been following along with recent jQuery releases, we have been working on how to address the recent addition of some new selectors in browsers, especially
:has. jQuery 3.6.3 settled on the strategy of using native
CSS.supports to determined whether a selector should be passed directly to
querySelectorAll or instead go through jQuery’s selector engine, as might be the case when using jQuery selector extensions, complex
:not(), or other selectors that are valid in jQuery but not in the browser. That all technically worked fine, but came with a downside. Fortunately for us, the fix is no longer necessary and we can go back to the old way. More on that below.
As usual, the release is available on our cdn and the npm package manager. Other third party CDNs will probably have it soon as well, but remember that we don’t control their release schedules and they will need some time. Here are the highlights for jQuery 3.6.4.
The Difference Between What Is Right and What Is Allowed
Whenever you use a selector in CSS, or JS, there is more than one spec involved. There’s a spec to determine whether a selector is valid (i.e. Selectors) and there’s a spec to guide implementers in how a selector should be parsed (i.e. the parser algorithm for consuming a simple block). The parser implementation is more forgiving than the selector spec itself, to allow for things like attribute selectors missing the last
When we addressed an issue with some selectors that were being added to modern browsers—specifically
:has—we started making use of another API available in most of our supported browsers—
CSS.supports—to determine whether a selector could safely be passed to native
querySelectorAll or whether it needed to go through jQuery’s selector engine. Selectors may need to bypass
qSA for multiple reasons. It may be a jQuery-only selector extension (
:contains), a standard selector that jQuery supports in a more robust way (
:not(complex)), or a selector we know to be buggy sometimes (
:disabled). Whatever the reason, the introduction of “forgiving parsing” in selectors like
:has made our previous way of determining that an issue because the browser would no longer throw errors for some truly invalid selectors. For instance,
:has(:contains) no longer threw an error when passed to
querySelectorAll. Neither did
:has(:monkey) for that matter.
CSS.supports seemed to be the answer.
And yet, every solution can have a trade-off. The problem now was that selectors that were technically invalid according to the Selectors spec were throwing errors. But these same selectors used to work fine because the parsers were more, for lack of a better term, forgiving. Essentially,
CSS.supports is not as forgiving as the parser.
Meanwhile, in our discussions with spec writers and vendors, it was agreed that we needed to prevent issues similar to the one with
:has from happening again in the future. What does that mean? It means we can go back to the old way . . . mostly. While the spec has been updated, browsers will need some time to update their implementations. And because of that, we still recommend upgrading jQuery to the latest version.
We do not expect compatibility issues when upgrading from a jQuery 3.0+ version. To upgrade, have a look at the new 3.5 Upgrade Guide. If you haven’t yet upgraded to jQuery 3+, first have a look at the 3.0 Upgrade Guide.
The jQuery Migrate plugin will help you to identify compatibility issues in your code. Please try out this new release and let us know about any issues you experienced.
If you can’t yet upgrade to 3.5+, Daniel Ruf has kindly provided patches for previous jQuery versions.
You can get the files from the jQuery CDN, or link to them directly:
You can also get this release from npm:
npm install firstname.lastname@example.org
Sometimes you don’t need ajax, or you prefer to use one of the many standalone libraries that focus on ajax requests. And often it is simpler to use a combination of CSS and class manipulation for web animations. Along with the regular version of jQuery that includes the ajax and effects modules, we’ve released a “slim” version that excludes these modules. The size of jQuery is very rarely a load performance concern these days, but the slim build is about 6k gzipped bytes smaller than the regular version. These files are also available in the npm package and on the CDN:
These updates are already available as the current versions on npm and Bower. Information on all the ways to get jQuery is available at https://jquery.com/download/. Public CDNs receive their copies today, please give them a few days to post the files. If you’re anxious to get a quick start, use the files on our CDN until they have a chance to update.
Thank you to all of you who participated in this release by submitting patches, reporting bugs, or testing, including Michal Golebiowski-Owczarek and the whole jQuery team.
We’re on Mastodon!
jQuery now has its very own Mastodon account. We will be cross posting to both Twitter and Mastodon from now on. Also, you may be interested in following some of our team members that have Mastodon accounts.
Full changelog: 3.6.4