[csswg-drafts] [css-ui] Allow customization of the text cursor selected by `cursor: auto` (#14178)

ylemkimon has just created a new issue for https://github.com/w3c/csswg-drafts:

== [css-ui] Allow customization of the text cursor selected by `cursor: auto` ==
## Problem

CSS allows authors to specify a custom cursor:

```css
.editor {
  cursor: url("custom-ibeam.svg") 8 12, text;
}
```

However, CSS selectors cannot select text nodes.

An author therefore cannot express:

```text
Apply this custom cursor when the pointer is over a selectable text node.
```

Using `cursor: auto` as the fallback does not provide this behavior:

```css
.editor {
  cursor: url("custom-ibeam.svg") 8 12, auto;
}
```

The custom image is selected first. `auto` is used only if the image cannot be used.

There is no way to customize only the text cursor that the browser selects as part of `cursor: auto`.

## Chromium behavior

Chromium performs a hit test and may identify a text node directly. Its logic is:

```cpp
bool EventHandler::ShouldShowIBeamForNode(const Node* node,
                                          const HitTestResult& result) {
  if (!node)
    return false;

  if (node->IsTextNode() && (node->CanStartSelection() || result.IsOverLink()))
    return true;

  return IsEditable(*node);
}

```
https://github.com/chromium/chromium/blob/6a5b476f4d08479557fb700b0528e33fede76623/third_party/blink/renderer/core/input/event_handler.cc#L560-L569

For `cursor: auto`, Chromium displays a text cursor when this check succeeds.

This uses information unavailable to CSS, including whether the hit-tested node is a text node and whether selection can start from it.

## Why existing CSS and JavaScript are insufficient

CSS selectors cannot match text nodes (#2208). Wrapping every text node in an element is not generally practical and still would not reproduce the browser’s selection logic.

JavaScript cannot fully reproduce the behavior either:

* `elementFromPoint()` returns an element rather than the complete internal hit-test result;
* `getComputedStyle().cursor` returns `auto`, not the final selected cursor;
* internal checks such as `CanStartSelection()` are not exposed;
* native controls, generated content, shadow trees, and internal layout objects may affect cursor selection;
* emulating this with continuous pointer-move hit testing and style updates may also introduce unnecessary performance overhead and cursor flicker.

The browser already determines when a text cursor is appropriate, but CSS cannot customize the result of that determination.

## Proposal

Add a `text-cursor` property:

```css
.editor {
  cursor: auto;
  text-cursor: url("custom-ibeam.svg") 8 12, text;
}
```

Conceptually:

```css
text-cursor: auto | [ <cursor-image>, ]* text;
```

When the browser’s automatic cursor-selection algorithm chooses a text cursor, it would use the value of `text-cursor`.

Otherwise, normal cursor behavior would remain unchanged.

```text
cursor = resolve cursor normally

if cursor was automatically resolved to text
    and text-cursor is not auto:
  cursor = resolve text-cursor
```

The initial value would be `auto`, meaning the platform text cursor.

The property should inherit, like `cursor`.

## Alternative: `cursor-auto`

A more general alternative would allow authors to replace any predefined cursor selected by `auto`:

```css
.editor {
  cursor: auto;
  cursor-auto:
    text: url("custom-ibeam.svg") 8 12, text;
}
```

This is more extensible, but also introduces a larger and more complex feature.

> **Disclaimer:** This proposal was drafted with assistance from an LLM.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/14178 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 14 July 2026 02:54:49 UTC