Skip to main content

Non-standard CSS selectors that can be used in Policy

Modified on: Fri, 14 Aug, 2026 at 6:59 PM

Summary

Use these non-standard CSS selectors in Policy when standard CSS selectors do not provide the matching behavior you need. The reference covers CsQuery selectors for position, occurrence, descendants, and text, plus Siteimprove selectors for case-insensitive text, direct text, and character length.

Applies to

  • Product: Siteimprove Policy
  • Rule type: CSS Selector
  • Selector categories: CsQuery selectors and Siteimprove’s own selectors

Selector overview

In addition to the Standard CSS selectors, the following categories of CSS selectors can also be used in Policy:

  • CsQuery selectors based on jQuery selectors as described in GitHub.
    • :gt(N) & :lt(N)
    • :eq(N)
    • :has(selector)
    • :contains("text")
  • Siteimprove’s own selectors based on CsQuery selectors.
    • :contains-i("text")
    • :contains-own("text")
    • :length-gt(N), :length-lt(N) & :length-eq(N)

CsQuery selectors

Here is a walk-through of the most useful CsQuery selectors that are based on jQuery selectors as described in GitHub.

:gt(N) & :lt(N)

Matches all occurrences of an element greater than (gt) or less than (lt) N on the entire page. This is a good way to find pages with e.g. more than one h1 element, using h1:gt(0). Note: The first occurrence counts as zero.

In the code below, div span:gt(0) matches span elements that come after the first occurrence, i.e. the elements “Bravo”, “Charlie” and “Delta”.

Following the same logic, div span:lt(2) matches elements zero and one, i.e. “Alfa” and “Bravo”:

<div>
<span>Alfa</span>
<span>Bravo</span>
</div>

<div>
<span>Charlie</span>
<span>Delta</span>
</div>

:eq(N)

Matches the Nth occurrence of an element on the entire page. Note: The first occurrence counts as zero.

In the code below, div span:eq(0) matches the element with the text “Alfa”, and div span:eq(3) matches “Delta”.

<div>
<span>Alfa</span>
<span>Bravo</span>
</div>

<div>
<span>Charlie</span>
<span>Delta</span>
</div>

:has(selector)

Matches an element that contains the specified element.

In the code below, div:has(strong) matches only the first div element, since strong is its descendant. However, div:has(em) matches the two last div elements, since they are both ancestors of em.

<div>
<span>
<strong>Alfa</strong>
</span>
<span>Bravo</span>
</div>

<div>
<div>
<em>Charlie</em>
</div>
<span>Delta</span>
</div>

:contains("text")

Matches an element that contains the specified string of text and also all matching ancestors elements.

Note 1: The search is case-sensitive by default – see :contains-i("text") below.

Note 2: It is not recommended to use this selector to match a div element, since that can match an unnecessarily large number of elements (see the first example below). In those cases, the selector div:contains-own("text") is better, since it does not match ancestor elements.

In the code below, div:contains("text") matches all three div elements: the one that contains the string “text” plus the two div elements that are its ancestors.

<div>
<div>
<div>Some text or other</div>
</div>
</div>

If you don’t want to specify which element(s) to match, you can leave out the element and search for just :contains("text")That matches the element(s) that contains the string “text” and every ancestor element all the way up to body, which can make it almost useless.

Siteimprove’s own selectors

:contains-i("text")

This selector is the same as :contains("text") above, but it’s case-insensitive.

One important difference to :contains("text") is that :contains-i("text") must be used with an explicit element, e.g. p:contains-i("text"). If you leave out the p, you will get the error message “This Policy doesn't seem to be working. Please contact support“.

:contains-own("text")

Matches only the specific element(s) that contains the string, and not any matching ancestor elements.

Note: This selector and its variations cannot be used without an element. For more details, see the note for :contains-i("text") above.

In the code below, div:contains-own("text") matches only the single div that contains the string “text”. This makes it much more precise than :contains("text"). This selector also has the case-insensitive alternative :contains-own-i("text").

<div>
<div>
<div>Some text or other</div>
</div>
</div>

:length-gt(N), :length-lt(N) & :length-eq(N)

Matches elements that contain more than (gt), fewer than (lt) or exactly (eq) N characters, including spaces – but excluding any HTML code.

Note 1: These selectors cannot be used without an element. For more details, see the note for :contains-i("text") above.

Note 2: These selectors ignore HTML code, so p:length-eq(3) will match both <p>Hi!</p> and <p><strong>Hi!</strong></p>.

In the code below, span:length-gt(4) matches the elements with the text “Bravo”, “Charlie” and “Delta”, and span:length-eq(4) matches “Alfa”. The selectors can be stacked to define a minimum and maximum: span:length-gt(4):length-lt(7) matches “Bravo” and “Delta”.

<div>
<span>Alfa</span>
<span>Bravo</span>
</div>

<div>
<span>Charlie</span>
<span>Delta</span>
</div>

Did you find it helpful? Yes No

Send feedback
Sorry we couldn't be helpful. Help us improve this article with your feedback.