0
# Textarea Caret Position
1
2
Cross-browser JavaScript library that calculates precise pixel coordinates of the text caret (cursor) position in HTML textarea and input elements. Uses an invisible mirror div technique to replicate element styling and determine exact caret positioning for building sophisticated text input interfaces.
3
4
## Package Information
5
6
- **Package Name**: textarea-caret
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install textarea-caret`
10
11
## Core Imports
12
13
```javascript
14
const getCaretCoordinates = require('textarea-caret');
15
```
16
17
For ES modules:
18
19
```javascript
20
import getCaretCoordinates from 'textarea-caret';
21
```
22
23
Browser (global with UMD pattern):
24
25
```html
26
<script src="path/to/textarea-caret/index.js"></script>
27
<script>
28
// Function available as window.getCaretCoordinates
29
</script>
30
```
31
32
## Basic Usage
33
34
```javascript
35
const getCaretCoordinates = require('textarea-caret');
36
37
// Get caret coordinates for a textarea
38
const textarea = document.querySelector('textarea');
39
textarea.addEventListener('input', function() {
40
const caret = getCaretCoordinates(this, this.selectionEnd);
41
console.log(`Caret at (${caret.left}, ${caret.top}) with height ${caret.height}px`);
42
});
43
44
// Get caret coordinates for an input
45
const input = document.querySelector('input[type="text"]');
46
const position = input.selectionStart;
47
const coordinates = getCaretCoordinates(input, position);
48
49
// Position a dropdown at the caret
50
const dropdown = document.getElementById('autocomplete');
51
dropdown.style.position = 'absolute';
52
dropdown.style.left = coordinates.left + 'px';
53
dropdown.style.top = (coordinates.top + coordinates.height) + 'px';
54
```
55
56
## Capabilities
57
58
### Caret Coordinate Calculation
59
60
Calculates the precise pixel coordinates of the text caret position in textarea and input elements.
61
62
```javascript { .api }
63
/**
64
* Calculate pixel coordinates of text caret position in textarea/input elements
65
* @param element - HTML element (must be textarea or input type="text")
66
* @param position - Integer caret position (typically selectionStart or selectionEnd)
67
* @param options - Optional configuration object
68
* @returns Object with top, left, and height properties in pixels
69
*/
70
function getCaretCoordinates(element, position, options);
71
```
72
73
**Parameters:**
74
75
- `element` (HTMLElement, required): DOM element - must be `<textarea>` or `<input type="text">`
76
- `position` (number, required): Integer caret position (0-based index into the text content)
77
- `options` (object, optional): Configuration object with the following properties:
78
- `debug` (boolean): If true, keeps the mirror div visible for debugging purposes (default: false)
79
80
**Return Value:**
81
82
```javascript { .api }
83
interface CaretCoordinates {
84
/** Offset in pixels from element's top edge (including border) */
85
top: number;
86
/** Offset in pixels from element's left edge (including border) */
87
left: number;
88
/** Height of the caret in pixels (typically the line height) */
89
height: number;
90
}
91
```
92
93
**Advanced Features:**
94
95
- **Multi-line Support**: Handles text wrapping in textareas with precise line positioning
96
- **Font Compatibility**: Works with any font family, size, weight, and style variations
97
- **Text Transformations**: Supports uppercase, lowercase, and other CSS text transforms
98
- **Spacing**: Handles letter-spacing, word-spacing, and tab characters
99
- **Border/Padding**: Accounts for all border widths and padding values
100
- **Scrolling**: Correctly positions caret even when element content is scrolled
101
- **RTL Support**: Right-to-left text direction compatibility
102
- **Cross-browser**: Works on Chrome, Safari, Firefox, Opera, and IE9+ with browser-specific handling
103
104
**Usage Examples:**
105
106
```javascript
107
// Basic autocomplete positioning
108
function showAutocomplete(textarea) {
109
const position = textarea.selectionStart;
110
const coords = getCaretCoordinates(textarea, position);
111
112
const dropdown = document.getElementById('autocomplete');
113
dropdown.style.left = coords.left + 'px';
114
dropdown.style.top = (coords.top + coords.height + 2) + 'px';
115
dropdown.style.display = 'block';
116
}
117
118
// Mention system (@username)
119
function handleAtMention(textarea) {
120
const text = textarea.value;
121
const cursorPos = textarea.selectionStart;
122
123
// Find @ symbol before cursor
124
const atIndex = text.lastIndexOf('@', cursorPos - 1);
125
if (atIndex !== -1) {
126
const coords = getCaretCoordinates(textarea, cursorPos);
127
showMentionDropdown(coords.left, coords.top + coords.height);
128
}
129
}
130
131
// Debug mode to visualize the mirror div
132
function debugCaretPosition(element, position) {
133
const coords = getCaretCoordinates(element, position, { debug: true });
134
console.log('Caret coordinates:', coords);
135
// Mirror div remains visible with highlighted caret position
136
}
137
138
// Input field with floating label
139
function updateFloatingLabel(input) {
140
const coords = getCaretCoordinates(input, input.selectionStart);
141
const label = document.getElementById('floating-label');
142
143
if (input.value.length > 0) {
144
label.style.left = coords.left + 'px';
145
label.style.top = (coords.top - 20) + 'px';
146
}
147
}
148
```
149
150
**Error Handling:**
151
152
The function throws an error if called in a non-browser environment:
153
154
```javascript
155
// Throws: 'textarea-caret-position#getCaretCoordinates should only be called in a browser'
156
try {
157
const coords = getCaretCoordinates(element, position);
158
} catch (error) {
159
console.error('Must be called in browser environment:', error.message);
160
}
161
```
162
163
**Browser Compatibility:**
164
165
- Chrome, Safari, Firefox, Opera (full support)
166
- Internet Explorer 9+ (with currentStyle fallback)
167
- Mobile browsers with touch support
168
- Universal Module Definition (UMD) pattern for broad compatibility
169
170
**Known Limitations:**
171
172
- Off-by-one positioning with spaces at end of lines in textareas (browser rendering issue)
173
- Tab characters not supported in IE9
174
- Edge cases with right-to-left text selection longer than input width
175
- Firefox requires special overflow property handling
176
177
## Implementation Details
178
179
The library works by creating an invisible mirror div that exactly replicates the styling of the target element:
180
181
1. **Mirror Creation**: Creates a `<div>` positioned off-screen with identical styling
182
2. **Property Copying**: Copies 47+ CSS properties from the original element (fonts, spacing, borders, etc.)
183
3. **Text Replication**: Copies text content up to the caret position into the mirror
184
4. **Caret Marking**: Inserts a `<span>` at the caret position with remaining text
185
5. **Coordinate Calculation**: Uses the span's offset position to determine caret coordinates
186
6. **Cleanup**: Removes the mirror div (unless debug mode is enabled)
187
188
This technique ensures pixel-perfect accuracy across different browsers and styling configurations.