Custom Carets and Users: When The Caret Is No Longer a Stick (Yes, That’s a Poor Attempt at a Pun)

Animated example Blinking vertical line in a text box, then the word “Wikipedia” is typed into the box.
First, let’s define caret. For the scope of this post, I am not talking about the ^ symbol, which evolved from the circumflex. I’m also not talking about the proofreader mark, sometimes rendered as ‸, ⁁, or ⎀. I am talking about the navigation symbol (or insertion caret), typically a vertical line, that shows the position of the cursor in a chunk of text or text entry box.

The most common kind of caret most users see is a simple vertical line; a stick. Yes, I am trying to make the post title work by calling it a stick.

But new CSS features will allow you to change properties of the insertion caret, specifically its shape, color (ok, not new, but see next property), and animate it.

You can play with these today if you have Chrome 140 or later. Go to chrome://flags#enable-experimental-web-platform-features to enable it (and ostensibly everything else that’s experimental in the browser).

Where Users Encounter Insertion Carets

I find folks forget that carets appear in more than just forms.

Fields

The most common place users see insertion carets is in text fields — the <input type="text">, its text siblings (date, time, password, etc.), and <textarea>. I stuffed a text field after this paragraph as an example. The caret is particularly useful when editing a value or when focus is automatically moved to the next field in a series (phone number, social security, credit card, etc).

Editables

Any content on a page with contenteditable="true", such as this paragraph, accepts the insertion caret (and allows you to edit the text). This is common in a WYSIWYG editor and in many content management systems that let authorized users make content changes. Or, in more offensive sites, as text fields made from <div>s.

Browsing

Less common is caret browsing. I go into more detail in the “Activate Caret Browsing in Chrome, Edge, or Firefox” section of my post Keyboard-Only Scrolling Areas. Essentially, if you press F7 in those browsers, you can move an insertion caret (text cursor) through the page content with arrow keys. I included a video from that post, and if you follow the green arrows starting at about 0:10, you can see the barely-visible caret moving through the content.

Safari also lets you do it without pressing F7, but there’s no visual cue (no caret).

WCAG Risk

Making changes to default browser or system caret has some WCAG implications.

2.4.7

Under WCAG SC 2.4.7 Focus Visible, the system caret alone is considered sufficient to pass (G149) for a default text field with no other cues. Once an author makes a change to the system caret, it’s not longer the system caret and G149 is arguably mooted.

1.4.11

The same system caret is also the only indicator needed to pass SC 1.4.11 Non-text Contrast for a field with no other passing visual cues. The Understanding doc refers to it as a sufficiently strong visual indication, implying the caret contrast is what provides that visual indication. An author change to that caret can break that visual indication.

2.3.1

SC 2.3.1: Three Flashes or Below Threshold says nothing on the page can blink more than 3 times per second. This can impact a zoomed user if an author creates a more rapid animation, particularly if the caret shape is a block (taking up more of their field of view). G176 (flashing size) limits whether you can fail this. To the CSSWG’s credit, it links to Guideline 2.3 Seizures, but in WCAG 2.0 spec from 2008.

CSSWG

Otherwise (and sadly), the CSS draft caret spec suggests a user who is disturbed by or has adverse reactions to blinking or flashing visuals can rely on user stylesheets to disable it (while acknowledging browsers may not offer that feature). This spec is aimed at authors, not users. As such, this would be the place to counsel authors to wrap their animations in a prefers-reduced-motion: no-preference query.

User Preferences

Microsoft Windows 11 allows you to customize the insertion caret, which it calls the text cursor (and part of why I keep rotating terms in this post).

The Windows 11 settings screen, showing controls and examples for any caret changes.
As seen in Windows 11 in the dark theme.

Windows lets you to add colored bells to the ends of the caret so it looks like a barbell(-ends). These are retained when in Firefox, Chrome, and Edge whenever the caret appears. It is not impacted by the caret color when set by CSS in Chrome (the only supporting browser when the experimental feature is enabled).

Windows also lets you set the caret thickness. This is not honored by Firefox, Chrome, or Edge. That suggests that when authors set a caret that is too narrow to be visible, there is no way for the user to override it from system preferences.

A text cursor in a string of text; it has a purple bell on the top and bottom and is the width of a letter, with an inverted letter showing through the bar.
A thickened, barbell-ended caret in Windows 11.

Meanwhile, macOS seems to only offer the option to “Prefer non-blinking cursor,” which prevents the system insertion caret from flashing. This appears to have no impact on animated carets in Chrome (with the feature enabled).

What this means is that there are currently no ways for user preferences to override the caret when set by CSS. Whether because the operating system offers no or few options or because browser makers and spec authors chose to ignore the limited preference a user can provide (size, blinking). I am hoping we’ll see motion preferences factor into cursor animation styles (at least from authors if not by the spec).

Wrap-up

I’d feel better if the CSSWG did a better job of outlining risks and best practices, at least beyond stale WCAG links and suggestions that user style sheets are the best approach to get around forcing animations on users. Granted, the CSSWG had shown a certain amount of ignoring the Priority of Constituencies of late, so I’m also not terribly surprised.

As an author, if you feel the burning desire to implement custom cursors, I encourage you to:

No comments? Be the first!

Leave a Comment or Response

  • The form doesn’t support Markdown.
  • This form allows limited HTML.
  • Allowed HTML elements are <a href>, <blockquote>, <code>, <del>, <em>, <ins>, <q>, <strong>, and maybe some others. WordPress is fickle and randomly blocks or allows some.
  • If you want to include HTML examples in your comment, then HTML encode them. E.g. <code>&lt;div&gt;</code> (you can copy and paste that chunk).