The purpose of this pair of functions is to allow capture and re-use of specific identifiers within a selector-list. After writing this, I also found previous, closely related discussion in #10567.
:capture() is a functional pseudo-class taking a modified complex-selector as an argument. In place of any identifier, an asterisk may be used to capture values. :capture() restricts the matches of a selector in the same way the provided complex-selector argument would, ignoring any identifiers replaced with an asterisk. For example, h1:capture(#*.cls) would match the same elements as h1.cls.
:group() is a corresponding functional pseudo-class taking a list of integer number-tokens, and appears in the same selector-list as at least one :capture(). The numbers refer to :capture() classes in the order that they appear. :group() restricts the selector by the elements which the referent capture would match. For example, table:capture(.*:hover) :group(1) would match any descendants of a table with :hover, where the descendants also share a class with an element with :hover.
To expand on this example, say a document has exactly 5 classes: cls1, cls2, cls3, cls4, cls5.
table:capture(.*:hover) td:group(1) could then be equivalently written:
:root:has(.cls1:hover) table:hover td.cls1,
:root:has(.cls2:hover) table:hover td.cls2,
:root:has(.cls3:hover) table:hover td.cls3,
:root:has(.cls4:hover) table:hover td.cls4,
:root:has(.cls5:hover) table:hover td.cls5
note how this is different from:
:root:has(.cls1:hover, .cls2:hover, .cls3:hover, .cls4:hover, .cls5:hover)
table:hover
td:is(.cls1, .cls2, .cls3, .cls4, .cls5)
example
The argument to :capture() may include multiple asterisks. In this case, the corresponding :group() must match at least one identifier from each asterisk. For example, say :capture(*.*#id1) captures div, h1, and cls1, cls2, cls3. The corresponding :group(1) will now restrict matches to one of div.cls1, div.cls2, div.cls3, h1.cls1, h1.cls2, and h1.cls3. Each application must also be unique, for example :capture(*.*.*#id1) with the same captures would give a :group(1) with restricts things to div.cls1.cls2, div.cls1.cls3, div.cls2.cls3, h1.cls1.cls2, h1.cls1.cls3, and h1.cls2.cls3.
There may be multiple numeric arguments to :group(). In this case, only one group must match. For example, say :capture(*#id1):capture(.*#id2) captures div, h1, h2, and cls1, cls2. The corresponding :group(1, 2) will now restrict matches to any of div, h1, h2, .cls1, or .cls2; this means a.cls2 and div.cls5 both match.
:group() may come before the :capture() it references in a selector list, but the complex selector in :capture() may not contain any :group() calls. If a :capture() appears inside a :capture(), the outer :capture() retains asterisks from the inner one. For example, :capture(*:capture(.*#id1)) would result in a :group(1) which matches :capture(*.*#id1) and a :group(2) which matches :capture(.*#id1).
:capture() may capture any identifier in the complex-selector.
- namespace:
*|
- type:
*
- id:
#*
- class:
.*
- attribute:
[*]
- value:
[foo=*]
- attribute with a value:
[*="foo"], [*|="foo" s], [*$="foo" i], [**="foo"], etc.
- pseudo-classes (non-function ones):
:*
- pseudo-elements:
::*
The purpose of this pair of functions is to allow capture and re-use of specific identifiers within a selector-list. After writing this, I also found previous, closely related discussion in #10567.
:capture()is a functional pseudo-class taking a modified complex-selector as an argument. In place of any identifier, an asterisk may be used to capture values.:capture()restricts the matches of a selector in the same way the provided complex-selector argument would, ignoring any identifiers replaced with an asterisk. For example,h1:capture(#*.cls)would match the same elements ash1.cls.:group()is a corresponding functional pseudo-class taking a list of integer number-tokens, and appears in the same selector-list as at least one:capture(). The numbers refer to:capture()classes in the order that they appear.:group()restricts the selector by the elements which the referent capture would match. For example,table:capture(.*:hover) :group(1)would match any descendants of a table with:hover, where the descendants also share a class with an element with:hover.To expand on this example, say a document has exactly 5 classes:
cls1,cls2,cls3,cls4,cls5.table:capture(.*:hover) td:group(1)could then be equivalently written:note how this is different from:
example
The argument to
:capture()may include multiple asterisks. In this case, the corresponding:group()must match at least one identifier from each asterisk. For example, say:capture(*.*#id1)capturesdiv,h1, andcls1,cls2,cls3. The corresponding:group(1)will now restrict matches to one ofdiv.cls1,div.cls2,div.cls3,h1.cls1,h1.cls2, andh1.cls3. Each application must also be unique, for example:capture(*.*.*#id1)with the same captures would give a:group(1)with restricts things todiv.cls1.cls2,div.cls1.cls3,div.cls2.cls3,h1.cls1.cls2,h1.cls1.cls3, andh1.cls2.cls3.There may be multiple numeric arguments to
:group(). In this case, only one group must match. For example, say:capture(*#id1):capture(.*#id2)capturesdiv,h1,h2, andcls1,cls2. The corresponding:group(1, 2)will now restrict matches to any ofdiv,h1,h2,.cls1, or.cls2; this meansa.cls2anddiv.cls5both match.:group()may come before the:capture()it references in a selector list, but the complex selector in:capture()may not contain any:group()calls. If a:capture()appears inside a:capture(), the outer:capture()retains asterisks from the inner one. For example,:capture(*:capture(.*#id1))would result in a:group(1)which matches:capture(*.*#id1)and a:group(2)which matches:capture(.*#id1).:capture()may capture any identifier in the complex-selector.*|*#*.*[*][foo=*][*="foo"],[*|="foo" s],[*$="foo" i],[**="foo"], etc.:*::*