- From: Daniil Sakhapov via GitHub <noreply@w3.org>
- Date: Mon, 07 Jul 2025 09:20:19 +0000
- To: public-css-archive@w3.org
Following the discussion, I gave this issue more thought. Please, take a look and leave a comment, especially about the table! ## Use Cases (from my head) 1. Conditional event listeners or observers: Attaching listener/observer/animation only if a pseudo-element exists and is being rendered. 2. Performance optimization: Avoid computing layout-heavy styles, if the pseudo doesn’t affect rendering. 3. Testing: Checking for the presence of visual pseudo content is valuable. 4. Conditional content generation: Dynamically {insert additional}/{change existing} content in e.g. `::before`, if it’ll actually be used. ## What should `CSSPseudoElement.exists` mean? In most layout-related cases (e.g. `::before`, `::after`, `::marker`), "box is generated" sounds most reasonable. For range-based and semantic pseudos (e.g. `::selection`, `::highlight`, `::cue`, `::grammar-error`, `::checkmark`), a “is active” or “has matching range” approach is better. So, to be future proof and being able to define `CSSPseudoElement` for more pseudo-elements, I suggest: `CSSPseudoElement.exists` to return: true / false / null: - true -> actively present/rendered/... defined on per-pseudo-element basis. - false -> opposite of true. - null -> not applicable or indeterminate (e.g., author shouldn’t be relying on it). This avoids over-promising, while still providing usefulness in most use cases. ## `CSSPseudoElement.exists` Behavior Table | Pseudo-element | When `.exists === true` | Notes | |------------------------|----------------------------------------------------------------------------|----------------------------------------------------------------------| | `::before` / `::after` | `content` is non-`none` and generates a box | `false` for empty or `content: none`, `null` when no style is defined | | `::first-line` | Element has stylable inline text | `false` for empty/non-text elements, `null` when no style is defined | | `::first-letter` | Stylable first character present | same as ::first-letter | | `::placeholder` | Placeholder is visible (no user input yet) | `false` when field is filled, `null` when no style is defined | | `::selection` | There is an active selection in the element | `false` if no text is selected, `null` when no style is defined | | `::highlight(name)` | Named Highlight intersects visible element content | `false` otherwise, `null` when no style is defined | | `::spelling-error` | Spellchecker detects error | Depends on UA/platform support | | `::grammar-error` | Grammar issue detected and styled | Depends on UA/platform support | | `::marker` | Element is styled as `list-item` and marker is rendered | `false` otherwise, `null` when no style is defined | | `::checkmark` | Control renders internal checkmark (e.g., via `appearance: auto`) | Depends on UA and platform conventions | | `::dropdown` | Native dropdown arrow is shown | `false` otherwise, `null` when no style is defined | | `::cue` | Active WebVTT cue is displayed | `false` otherwise, `null` when no style is defined | | `::backdrop` | Element is modal or in fullscreen state | `false` otherwise, `null` when no style is defined | | `::scroll-marker` | `content` is non-`none` and generates a box and `::scroll-marker-group` exists | `false` for empty or `content: none` or no `::scroll-marker-group`, `null` when no style is defined | | `::scroll-marker-group` | Defined in style via property and pseudo style and generates a box | `false` (or `null` for consistency?) when no style is defined | ## Special / Unresolved Cases | Pseudo | Notes | |------------------------|---------------------------------------------------------------------------| | `::target-text` | Possibly `true` when fragment-activated text is present | | `::view-transition-*` | Would need clear phase-specific definitions | | `::part(name)` | Shouldn't be represented as CSSPseudoElement probably? `true` -> shadow tree contains a matching part | | `::slotted(selector)` | Shouldn't be represented as CSSPseudoElement probably? `true` -> one or more matching nodes are slotted | | Unsupported pseudos | CSSPseudoElement won't be obtained for those, but just in case: `.exists === null` if pseudo not applicable in current context | -- GitHub Notification of comment by danielsakhapov Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/12158#issuecomment-3044139876 using your GitHub account -- Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config
Received on Monday, 7 July 2025 09:20:20 UTC