Skip to content

Commit ab0cb47

Browse files
authored
fix: chrome zoom bug (#1426)
* fix: chrome zoom bug * fix: use a wrapper element to guarantee elements do not affect layout
1 parent 8b8526f commit ab0cb47

File tree

2 files changed

+22
-57
lines changed

2 files changed

+22
-57
lines changed

packages/core/src/editor/editor.css

+11-51
Original file line numberDiff line numberDiff line change
@@ -77,66 +77,26 @@ Tippy popups that are appended to document.body directly
7777
opacity: 0.001;
7878
}
7979

80-
/**
81-
Here be dragons!
82-
83-
The collaboration cursor caret needs to:
84-
- exist in the dom as a non-zero width element, so that when hovering over it, the label can display
85-
- yet, effectively not take up space in the dom, so that it doesn't cause wrapping or otherwise effect layout of the page
86-
87-
To achieve this, it took quite a bit of fiddling to figure out how to do this.
88-
89-
The caret is a span which has a before and after pseudo element.
90-
The before element is what actually takes up space in the dom, and is colored via a border.
91-
The color is actually set by reading the current color from the `.collaboration-cursor__caret` element. Allowing for dynamic coloring from JS.
92-
93-
There are a number of browser specific quirks with these hacks:
94-
- Firefox differs from Chrome & Safari in that it will split a word that is wrapping if not displayed as inline-block (whereas the others need display: inline)
95-
- Safari differs from Chrome & Firefox in that it needs the pseudo element to be position: relative to display a pseudo-element element with a negative margin
96-
97-
The word-joiner char (\u2060) is used to make sure the caret doesn't wrap around the text.
98-
99-
Therefore if modifying this code, please test in all major browsers to ensure that the caret is rendered correctly in all browsers.
100-
**/
101-
102-
/* Give a remote user a caret */
103-
.collaboration-cursor__caret {
104-
position: relative;
105-
word-break: normal;
106-
white-space: nowrap !important;
107-
}
108-
109-
/* Allow the caret to be colored & hovered over */
110-
.collaboration-cursor__caret::before {
111-
/* Use currentColor to grab the color from the caret in set by JS */
112-
border-left: 2px solid currentColor;
113-
/* Make the cursor not actually take up the 2px of space within the element */
114-
margin-left: -2px;
115-
/* Fixes Safari's rendering of negative margin elements */
80+
.collaboration-cursor__base {
11681
position: relative;
11782
}
11883

119-
/* Firefox will split a word that is wrapping if not displayed as inline-block */
120-
@-moz-document url-prefix() {
121-
.collaboration-cursor__caret::before {
122-
display: inline-block;
123-
}
124-
}
125-
126-
/* Add a word-joiner (\u2060) char to each side of the caret */
127-
.collaboration-cursor__caret::after,
128-
.collaboration-cursor__caret::before {
129-
content: "⁠";
84+
.collaboration-cursor__caret {
85+
position: absolute;
86+
width: 2px;
87+
top: 1px;
88+
bottom: -2px;
89+
left: -1px;
13090
}
13191

132-
/* Render the username above the caret */
13392
.collaboration-cursor__label {
93+
pointer-events: none;
13494
border-radius: 0 1.5px 1.5px 0;
13595
font-size: 12px;
13696
font-style: normal;
13797
font-weight: 600;
13898
line-height: normal;
139-
left: -2px;
99+
left: 0;
140100
overflow: hidden;
141101
position: absolute;
142102
white-space: nowrap;
@@ -150,13 +110,13 @@ Therefore if modifying this code, please test in all major browsers to ensure th
150110
transition: all 0.2s;
151111
}
152112

153-
.collaboration-cursor__caret[data-active] > .collaboration-cursor__label {
113+
.collaboration-cursor__base[data-active] .collaboration-cursor__label {
154114
color: #0d0d0d;
155115
max-height: 1.1rem;
156116
max-width: 20rem;
157117
padding: 0.1rem 0.3rem;
158118
top: -17px;
159-
left: -2px;
119+
left: 0;
160120
border-radius: 3px 3px 3px 0;
161121

162122
transition: all 0.2s;

packages/core/src/extensions/Collaboration/createCollaborationExtensions.ts

+11-6
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,24 @@ export const createCollaborationExtensions = (collaboration: {
6565
const renderCursor = (user: { name: string; color: string }) => {
6666
const cursorElement = document.createElement("span");
6767

68-
cursorElement.classList.add("collaboration-cursor__caret");
69-
cursorElement.setAttribute("style", `color: ${user.color}`);
70-
if (collaboration?.showCursorLabels === "always") {
71-
cursorElement.setAttribute("data-active", "");
72-
}
68+
cursorElement.classList.add("collaboration-cursor__base");
69+
70+
const caretElement = document.createElement("span");
71+
caretElement.setAttribute("contentedEditable", "false");
72+
caretElement.classList.add("collaboration-cursor__caret");
73+
caretElement.setAttribute("style", `background-color: ${user.color}`);
7374

7475
const labelElement = document.createElement("span");
7576

7677
labelElement.classList.add("collaboration-cursor__label");
7778
labelElement.setAttribute("style", `background-color: ${user.color}`);
7879
labelElement.insertBefore(document.createTextNode(user.name), null);
7980

80-
cursorElement.insertBefore(labelElement, null);
81+
caretElement.insertBefore(labelElement, null);
82+
83+
cursorElement.insertBefore(document.createTextNode("\u2060"), null); // Non-breaking space
84+
cursorElement.insertBefore(caretElement, null);
85+
cursorElement.insertBefore(document.createTextNode("\u2060"), null); // Non-breaking space
8186

8287
return cursorElement;
8388
};

0 commit comments

Comments
 (0)