The selectionStart DOM property
selectionStart is a JavaScript property that returns where the selected text begins in a text field. No HTML attribute of that name exists. The index is zero-based, it equals the caret position when nothing is selected, and it is null on email and number inputs.
Overview
selectionStart is a JavaScript property that gives the index where a field's text selection begins. It exists on text <input> and <textarea> elements. It is not an HTML attribute, so writing it in your markup has no effect. You read or set it on the element in script.
The index is zero-based and counted in UTF-16 code units. When nothing is selected, selectionStart equals selectionEnd and both give the caret position, which is how you find where the user is typing. input.value.slice(input.selectionStart, input.selectionEnd) returns the selected text.
It works on inputs of type text, search, url, tel and password, and on every textarea. On an email or number input it returns null, and assigning to it throws an InvalidStateError. Elements with contenteditable don't have the property at all.
Setting selectionStart moves the start of the selection. If the new start is past selectionEnd, the end moves with it, and numbers beyond the value's length are clamped to the end. To set both ends in one call, use setSelectionRange(start, end).
Syntax
<label for="name">Greeting</label>
<input type="text" id="name" value="Hello world">
<script>
const field = document.getElementById('name');
const caret = field.selectionStart;
field.selectionStart = 6;
</script>
Values
| Value |
|---|
| An integer character offset. |
Example
<label for="msg">Message</label>
<input type="text" id="msg" value="Hello world" size="28">
<button type="button" id="ins">Insert a name at the cursor</button>
<p id="pos"></p>
<script>
const msg = document.getElementById('msg');
function show() {
document.getElementById('pos').textContent = 'selectionStart is ' + msg.selectionStart + ', selectionEnd is ' + msg.selectionEnd;
}
document.getElementById('ins').addEventListener('click', function () {
const at = msg.selectionStart;
msg.value = msg.value.slice(0, at) + 'Sam ' + msg.value.slice(msg.selectionEnd);
msg.focus();
msg.setSelectionRange(at + 4, at + 4);
show();
});
['select', 'keyup', 'click'].forEach(function (type) {
msg.addEventListener(type, show);
});
show();
</script>
Best practices
- Check for
nullbefore usingselectionStarton inputs whose type may change. Email and number inputs returnnull. - Read
selectionStartandselectionEndtogether. A collapsed selection has them equal, and that value is the caret. - Call
focus()before setting the selection if the user should see it. The values update without focus, but the highlight only shows on a focused field. - Use
setSelectionRange()to change both ends in one call. Setting the start alone can drag the end along with it.
Frequently asked questions
What does selectionStart return?
Why is selectionStart null?
How do I get the cursor position in an input with JavaScript?
How do I move the cursor to a specific position in an input?
input.setSelectionRange(pos, pos) does both at once, and calling focus() first makes the caret visible.