Skip to content

Add :has() pseudo-class support - #3755

Open
RF1705 wants to merge 3 commits into
dompdf:masterfrom
RF1705:has-pseudo-class-pr
Open

Add :has() pseudo-class support#3755
RF1705 wants to merge 3 commits into
dompdf:masterfrom
RF1705:has-pseudo-class-pr

Conversation

@RF1705

@RF1705 RF1705 commented Sep 4, 2026

Copy link
Copy Markdown

Summary

This PR adds support for the CSS Selectors Level 4 :has() relational pseudo-class.

It supports relative selector lists and reuses Dompdf's existing selector-to-XPath compiler for selectors inside :has().

Examples:

li:has(> strong:first-child)
article:has(.target)
h2:has(+ p.note)
h2:has(~ p.note)
section:has(> img.hero, > table.featured)

Implementation

  • Parses functional pseudo-class arguments, including nested parentheses and quoted content.
  • Splits top-level selector lists inside :has().
  • Supports relative descendant, child (>), adjacent sibling (+), and subsequent sibling (~) selectors.
  • Reuses the existing selector compiler for classes, IDs, attributes, and supported pseudo-classes such as :first-child and :nth-child().
  • Rejects nested :has() and pseudo-elements inside :has().
  • Converts the relative selectors to XPath predicates evaluated from the candidate element.

Tests

Regression tests cover:

  • direct child selectors combined with :first-child;
  • descendant selectors;
  • adjacent sibling selectors;
  • subsequent sibling selectors;
  • selector lists;
  • nested functional pseudo-classes such as :nth-child();
  • compound selectors;
  • attribute selectors;
  • invalid or nested :has() expressions.

@bsweeney bsweeney added this to the 4.0.0 milestone Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants