Closed Bug 1865242 Opened 2 years ago Closed 1 years ago

Cursor doesn't ignore pseudo element inside contentEditable

Categories

(Core :: DOM: Editor, defect)

defect

Tracking

()

RESOLVED INVALID

People

(Reporter: kwei88, Unassigned)

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/119.0

Steps to reproduce:

Given this:

.code {
      font-family: monospace;
      background: rgba(0, 0, 0, 0.05);
    }

    .pseudo-ele::after {
      content: "3";
    }

    <div contenteditable>
      <span>`</span><span class="code pseudo-ele">12</span><span>`</span>
    </div>

Step #1
Place cursor like this

`123`|

Step #2
Press left arrow 2 times.

Actual results:

The cursor landed on the right side of 2

 `12|3`

Expected results:

The cursor should have landed on the left side of 2

 `1|23`

The Bugbug bot thinks this bug should belong to the 'Core::Layout: Text and Fonts' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: Untriaged → Layout: Text and Fonts
Product: Firefox → Core

The severity field is not set for this bug.
:TYLin, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(aethanyc)
Flags: needinfo?(aethanyc)

I can see Google Chrome and Safari both have the expected results described in comment 0, but I don't know whether the behavior is good or not. For example, in Firefox, the cursor can be moved to the position after 3 at

`123|`

so that the user can enter more characters there, but it's impossible in other browsers.

(Switched to DOM: Editor to get more insight.)

Status: UNCONFIRMED → NEW
Component: Layout: Text and Fonts → DOM: Editor
Ever confirmed: true
Version: Firefox 119 → Trunk

IMO, Firefox's behavior here is better; it should be possible to place the cursor on either side of the pseudo-element. There's no reason it should skip the position after 3 in this example.

Firefox does (correctly, I think) skip over the actual content of the pseudo-element, so the cursor cannot be placed inside it. This can more clearly be seen if you give it something like content: "345" rather than just a single character: moving with left- or right-arrow will skip over 345 as a unit, but the cursor can be placed immediately before 3 or immediately after 5.

Thanks all for the input.

The visual discrepancy in Firefox for this case can be observed if the content of the pseudo-element is empty

.pseudo-element::after {
     content: "";
}

Demo:
https://jsfiddle.net/yo5ex83q/

Steps to reproduce:

  1. Place cursor like this
`12`|
  1. Press left arrow 2 times.

Actual result:
On second press, the cursor is stuck at the same position from the first press.

Expected result:
On second press, the cursor should be placed immediately before 2

`1|2`

Yeah, Firefox allows users to type character immediately after the pseudo content, so, it's better behavior.

Even if it's empty, it should be more reasonable to be able to type text both side of the pseudo element. Although it may fail in some similar edge cases, I think that this can be marked as invalid.

the cursor is stuck at the same position from the first press.

When you type a character after pressing left arrow key once or twice, you'll see different result. I agree with the visual feedback may users confused, but I think it's not a serious issue rather than cannot type text into a specific side of the pseudo content.

But empty pseudo-element has many use cases. Also, ::after pseudo-element is "cosmetic" and

If the content property is not specified, has an invalid value, or has normal or none as a value, then the ::after pseudo-element is not rendered. It behaves as if display: none is set. - Source (emphasis mine)

content: "" is neither of those cases tho.

If you modify your jsfiddle example to use content: normal or content: none instead of content: "" (which is not the same thing), you'll see that the "anomaly" in cursor movement no longer happens.

A pseudo-element with content: "" is still present in the rendering, even though it has no visible content; you can confirm this (for example) by adding outline: 5px solid red to it. Changing it to have content: none does indeed remove it from the rendering.

Status: NEW → RESOLVED
Closed: 1 years ago
Resolution: --- → INVALID

Still, pseudo-elements with empty content(content: "") are commonly utilized for styling(such as borders) and visual effects(in my case, its a fake cursor haha)

Alright, I will figure something out on my end.

Sorry for the noise and thank you all for your attention and time.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: