I have 2 <input>s and tried to select <input>s by setting 2 joined attribute selectors to 1 :not() and 2 separate attribute selectors to 2 :not()s respectively with querySelectorAll() as shown below:
<input type="text" name="first-name" id="fn" value="John">
<input type="text" name="last-name" id="ln" value="Smith">
<script>
// 2 joined attribute selectors to 1 ":not()"
document.querySelectorAll('input:not([name="first-name"][id="ln"])');
// 2 separate attribute selectors to 2 `:not()`s
document.querySelectorAll('input:not([name="first-name"]):not([id="ln"])');
</script>
Then, 2 joined attribute selectors with 1 :not() selects John's <input> and Smith's <input> and 2 separate attribute selectors with 2 :not()s selects nothing as shown below:
// 2 joined attribute selectors to 1 ":not()"
document.querySelectorAll('input:not([name="first-name"][id="ln"])');
// John's <input> and Smith's <input>
// 2 separate attribute selectors to 2 `:not()`s
document.querySelectorAll('input:not([name="first-name"]):not([id="ln"])');
// Nothing
So, what is the difference between 2 joined attribute selectors with 1 :not() and 2 separate attribute selectors with 2 :not()s?
input:not([name="first-name"][id="ln"])selects both the input elements because no element on the page has both the name attribute set to "first-name" and id attribute set to "ln". Thus, all of them match. ([name="first-name"][id="ln"]matches nothing, so inverting that matches everything.)input:not([name="first-name"]):not([id="ln"])selects nothing because there is only one element with the name attribute not set to "first-name", but its id attribute is "ln" which cannot match:not([id="ln"]).