How to get the caret position on a textarea element in pixels

Let's assume that you have a <textarea> component and that you want to get the caret position of it in pixels:

<textarea onkeyup = 'getCaretPos(event)' id = 'textarea' rows = '1'></textarea>

The idea is to create a dummy element and to play with the dimensions/coordinates of it using getClientsRects() and getBoundingClientRect().

const getCaretPos = (e) => {
    // Getting the textarea element
    let textarea = document.getElementById('textarea');  

	// Adjusting textarea to prevent scrolling = `${}px`
    // Appending element to the DOM after textarea
    textarea.insertAdjacentHTML('afterend', `<span id = 'dummy'>${textarea.value}</span>`);
    // Getting position info of the rectangles inside dummy element
    let rectangles = document.getElementById('dummy').getClientRects();
	let last = rectangles[rectangles.length - 1];
	// Getting position info of the textarea
	let text = document.getElementById('textarea').getBoundingClientRect();
    // Setting coordinates
    let x = last.x + last.width;
    let y = text.y + text.height - last.height;
	// Removing dummy
    // Returning variables
    return [x, y];

And here is the CSS:

	width: 200px;
#dummy, #textarea{
	box-sizing: border-box;
    font: 14px/1 monospace;
    border: 1px solid #999;
    white-space: pre-wrap;
    margin: 0;
	overflow: hidden;
    width: 100%;


You could add a function to draw a marker on top of the caret to verify if the returning variables are correct.


const drawSquare = (x, y) => {
	// Deleting previous square;
	// Inserting new one
    textarea.insertAdjacentHTML('afterend', `<div id = 'square'></div>`);
	// Modifying position of it
	document.getElementById('square').style.left = `${x}px`;
	document.getElementById('square')  = `${y}px`;

And here is the CSS:

	background: #4CAF50;
	border-radius: 50%;
	height: 5px;
	position: absolute;
	width: 5px;

You can see the full example at CodePen.

Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.