Create your own custom cursor in a text area
Phuoc Nguyen
Posted on December 20, 2023
Have you ever noticed that vertical blinking line that shows where the next character will go when you're typing? That's called a caret. And did you know you can customize it? It's true!
Customizing the caret can be super useful. For example, in a code editor, changing the shape and color of the caret could help with readability and make it easier to see different types of text. And in a chat app, a personalized cursor could add a fun touch to the user experience. You can even use custom cursors to create cool visual effects on a webpage.
By default, the caret is just a plain vertical line. But with CSS, you can change its shape and color using the caret-shape
or caret-color
property. Unfortunately, you can't make it wider or add animations that way.
But don't worry! In this post, we'll show you how to create a custom caret in a text area using JavaScript.
Hiding the default cursor
It's the pretty easy to make the default cursor disappear. All you need to do is set the caret-color
property to a transparent color. This will make the default cursor look like it's vanished into thin air.
.container__textarea {
caret-color: transparent;
}
Creating a fake cursor
If you've been following our post on how to calculate cursor coordinates, you know that we've built the mirror element content using three parts: two text nodes representing the text before and after the cursor position, and an empty element representing the cursor.
But here's the cool part: we can use that empty element as a fake cursor! First, we'll add a special CSS class for it:
const pre = document.createTextNode(textBeforeCursor);
const post = document.createTextNode(textAfterCursor);
const caretEle = document.createElement('span');
caretEle.classList.add('container__cursor');
caretEle.innerHTML = ' ';
mirroredEle.innerHTML = '';
mirroredEle.append(pre, caretEle, post);
Now that we've added the container__cursor
class to the cursor element, we have full control over its appearance. We can add a background or increase the width, like this:
.container__cursor {
background-color: rgb(15 23 42);
width: 4px;
}
And voila! With just a few lines of code, we've created a fake cursor in CSS.
Adding a blink effect to the fake cursor
To make your fake cursor look more realistic, you can make it blink. There are a few ways to achieve this effect, such as repeatedly changing the background color or opacity.
In this example, we'll use the first approach by defining a keyframe named blink
using the @keyframes
rule. This keyframe has three steps: 0%, 50%, and 100%. At 0% and 100%, we set the background color of the cursor to transparent, which makes it disappear. At 50%, we set the background color to a specific color, such as rgb(15 23 42), which makes it visible.
@keyframes blink {
0%, 100% {
background-color: transparent;
}
50% {
background-color: rgb(15 23 42);
}
}
Next, we apply this animation to our cursor element using the animation
property in CSS. We set its value to blink
, specify a duration of 1 second, and make it repeat infinitely by setting its iteration count to infinite
. Feel free to adjust these CSS styles to match your specific needs.
.container__cursor {
animation: blink 1s infinite;
}
With these styles applied, your custom cursor will now blink at a regular interval, giving it a more realistic appearance.
Moving the fake cursor alongside the real one
Now, let's talk about the final piece of the puzzle: moving the fake cursor in sync with the real one.
Usually, there's no built-in event to detect when users move the cursor inside a text area. However, we can use the selectionchange
event, which is triggered when users select text on the page, focus on a text area, or move the cursor inside it.
To re-position the cursor, we handle the selectionchange
event and check whether the text area is currently being focused by comparing the active element (document.activeElement
) with the text area. If they match, we update the mirrored element, which includes the fake cursor element.
Here's a code snippet to give you an idea of how it works:
const handleSelectionChange = () => {
if (document.activeElement === textarea) {
// Re-update the mirrored element ...
}
};
document.addEventListener('selectionchange', handleSelectionChange);
Now let's take a look at our final example of the steps we've been following. You can either click or use the arrow keys to move the cursor, and the fake cursor will instantly move to the position you want it to be.
See also
It's highly recommended that you visit the original post to play with the interactive demos.
If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!
If you want more helpful content like this, feel free to follow me:
Posted on December 20, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
July 24, 2024