Search code examples
javascriptcss-selectorsselectors-api

Inconsistent selector for querySelectorAll


When using :checked selector in JavaScript, document.querySelectorAll(), I see there is an inconsistent behavior. When the :checked selector is used for checkbox or radio button it doesn't require space before the colon (:), but when this used for select options it requires a space before it. Why is it so?

Here are the examples:-

Checkbox: http://jsbin.com/fehonoho/1/edit?html,js,console

Select: http://jsbin.com/yasotuli/1/edit?html,js,console


Solution

  • From the Selectors spec:

    For example, the :checked pseudo-class initially applies to such elements that have the HTML4 selected and checked attributes as described in Section 17.2.1 of HTML4, but of course the user can toggle "off" such elements in which case the :checked pseudo-class would no longer apply.

    The space preceding the :checked selector is nothing more than a descendant combinator, so the selector that you have is looking for descendants of a select that are :checked, rather than the select itself. These descendants are its option elements.

    The selected attribute is found in option elements, not their parent select. In other words, a select can never match the :checked selector; only its options can. That's why you need a descendant (or child) combinator for it to work, unlike with checkboxes and radio buttons.

    To make this clearer, it's highly recommended that you qualify the :checked selector with a type selector (a universal selector is implied otherwise):

    document.querySelectorAll('[name="aname"] option:checked')
    

    Likewise with the attribute selector for the select element:

    document.querySelectorAll('select[name="aname"] option:checked')