or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-textarea-caret

Cross-browser library for calculating precise pixel coordinates of textarea and input caret positions

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/textarea-caret@3.1.x

To install, run

npx @tessl/cli install tessl/npm-textarea-caret@3.1.0

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.