My Goal
I am in the process of creating an input-like content editable div. The idea is to click on tags outside the div and insert them inside the div while still being able to type around these tags.
The Issue and Reproduction Steps
To prevent tag buttons from being selected, I'm using user-select: none (normal and webkit). This works fine in Firefox and Chrome but not in Safari. I've tried adding the -webkit- prefix without success.
Here is a fiddle where you can see the problem in action.
Attempts Made
The main issue was maintaining the caret's position when leaving the content editable div.
I previously experimented with rangy but encountered limitations, especially in Firefox, which had negative effects on UX. You can reference my previous question that led me to explore the user-select: none solution here: Caret disappears in Firefox when saving its position with Rangy
This is how I arrived at the current solution utilizing user-select: none.
Components/JS:
// Vue initialization
new Vue({
el: "#app",
data(){
return {
// Data properties
}
},
name: 'boolean-input',
methods: {
// Methods go here
},
props: [ 'first'],
mounted() {
this.addPlaceholder()
}
})
HTML Structure:
<div id="app">
<!-- HTML structure here -->
</div>
CSS Styling:
/* CSS styles go here */
Note: Ignore the new Vue initialization code as it's copied from the fiddle link provided for inspection.
Expected Outcome vs Actual Results
In Safari, when clicking a tag after typing a word and moving the caret within that word, the tag should be inserted where the selection was made, but instead, it always gets added at the beginning of the content editable div.
In short, Safari doesn't maintain the caret's position when adding tags, resulting in the tag being placed at the start of the div rather than where the caret was located.
Edit 1: Upon investigation using getSelection(), it seems the offset is consistently 0 due to the div losing focus in Safari. https://i.sstatic.net/IEygT.png