将插入符号定位在 Chrome 中具有较大行高的 contenteditable
Positioning the caret in a contenteditable with large line-height in Chrome
在 macOS 上 Chrome 和 Linux 上的 Chromium 在可编辑区域内单击以获得更大的行高时,插入符号的位置不合理。
在此示例中,我们为 <span>
个元素设置了 line-height
的值。由于其他应用程序要求,主要是使用 Quill.js 富文本编辑器,因此无法将其关闭并从父元素继承。每行可能有多个 <span>
具有不同的字体大小,但没有嵌套元素。
p {
display: inline-block;
margin: 0;
background: lightgrey;
}
span {
line-height: 2.5;
font-size: 50px;
background: lightblue;
}
span.small {
font-size: 25px;
}
<p contenteditable><span>some </span><span class="small">text</span><br/><span>some text</span></p>
在 Firefox 中,如果您单击灰色区域(标记 <p>
元素),插入符号将始终位于最近的字符处。如果您在行之间单击,插入符号也会合理定位。
在 Chrome 中,仅当您在蓝色区域内单击(标记元素)时,插入符号才会定位到最近的字符。在灰色区域,插入符号结束于下一行的开头,或者如果您在最后一个跨度下方单击,则结束于最后一行。
如何使用 Chrome 复制 Firefox 的行为?
注意:按照建议 display: inline-block
给跨度 并不能解决问题。
如您所知,它与 Chrome 以及它如何处理行高有关。
尽管如此,我已经编写了一个似乎在 Linux(Chrome、Firefox)和 Windows(Chrome、Firefox、Edge ).
对于 vertical-align: text-bottom
,除第一行外,所有行似乎都按预期工作。所以我的想法是添加一个换行符(然后用 font-size: 0
取消它)
p::before {
content: "\A";
white-space: pre;
display: inline;
}
p::first-line {
font-size: 0px;
}
这在 Chrome(Linux 和 Windows)上工作得很好,但是在 Firefox 上 我没能否定额外的换行符。所以,因为它最初工作得很好,所以我使用 firefox-only 规则来隐藏额外的换行符。
因此,我们的解决方法适用于 Chrome 和 Firefox(Windows 和 Linux)但是 Edge 在vertical-align
所以(再一次)我使用 ms only 规则 unset
vertical-align
.
结果(正在处理 Chrome Windows/Linux、Firefox Windows/Linux、Edge Windows)
p {
display: inline-block;
margin: 0;
background: lightgrey;
}
span {
line-height: 2.5;
font-size: 30px;
background: lightblue;
vertical-align: text-bottom;
}
p::before {
content: "\A";
white-space: pre;
display: inline;
}
p::first-line {
font-size: 0px;
}
/* Firefox only */
@-moz-document url-prefix() {
p::before {
display: none;
}
}
/* Edge only */
@supports (-ms-ime-align:auto) {
span {
vertical-align: unset;
}
}
<p contenteditable><span>some text</span><br/><span>some text</span></p>
更新
在更新的测试用例中,每行有多种字体大小,您将需要跳过 vertical-align: bottom|text-bottom
并妥协于将额外的 space "allocated" 添加到下面的行(仅在 Chrome - Linux 中)。
请注意,第一行仍然需要前面提到的 "hack",以便所有行之间具有一致的行为。
看看这个 codepen 更新的测试用例。
Chrome 和 Linux 上的 Chromium 在可编辑区域内单击以获得更大的行高时,插入符号的位置不合理。
在此示例中,我们为 <span>
个元素设置了 line-height
的值。由于其他应用程序要求,主要是使用 Quill.js 富文本编辑器,因此无法将其关闭并从父元素继承。每行可能有多个 <span>
具有不同的字体大小,但没有嵌套元素。
p {
display: inline-block;
margin: 0;
background: lightgrey;
}
span {
line-height: 2.5;
font-size: 50px;
background: lightblue;
}
span.small {
font-size: 25px;
}
<p contenteditable><span>some </span><span class="small">text</span><br/><span>some text</span></p>
在 Firefox 中,如果您单击灰色区域(标记 <p>
元素),插入符号将始终位于最近的字符处。如果您在行之间单击,插入符号也会合理定位。
在 Chrome 中,仅当您在蓝色区域内单击(标记元素)时,插入符号才会定位到最近的字符。在灰色区域,插入符号结束于下一行的开头,或者如果您在最后一个跨度下方单击,则结束于最后一行。
如何使用 Chrome 复制 Firefox 的行为?
注意:按照建议 display: inline-block
给跨度
如您所知,它与 Chrome 以及它如何处理行高有关。
尽管如此,我已经编写了一个似乎在 Linux(Chrome、Firefox)和 Windows(Chrome、Firefox、Edge ).
对于 vertical-align: text-bottom
,除第一行外,所有行似乎都按预期工作。所以我的想法是添加一个换行符(然后用 font-size: 0
取消它)
p::before {
content: "\A";
white-space: pre;
display: inline;
}
p::first-line {
font-size: 0px;
}
这在 Chrome(Linux 和 Windows)上工作得很好,但是在 Firefox 上 我没能否定额外的换行符。所以,因为它最初工作得很好,所以我使用 firefox-only 规则来隐藏额外的换行符。
因此,我们的解决方法适用于 Chrome 和 Firefox(Windows 和 Linux)但是 Edge 在vertical-align
所以(再一次)我使用 ms only 规则 unset
vertical-align
.
结果(正在处理 Chrome Windows/Linux、Firefox Windows/Linux、Edge Windows)
p {
display: inline-block;
margin: 0;
background: lightgrey;
}
span {
line-height: 2.5;
font-size: 30px;
background: lightblue;
vertical-align: text-bottom;
}
p::before {
content: "\A";
white-space: pre;
display: inline;
}
p::first-line {
font-size: 0px;
}
/* Firefox only */
@-moz-document url-prefix() {
p::before {
display: none;
}
}
/* Edge only */
@supports (-ms-ime-align:auto) {
span {
vertical-align: unset;
}
}
<p contenteditable><span>some text</span><br/><span>some text</span></p>
更新
在更新的测试用例中,每行有多种字体大小,您将需要跳过 vertical-align: bottom|text-bottom
并妥协于将额外的 space "allocated" 添加到下面的行(仅在 Chrome - Linux 中)。
请注意,第一行仍然需要前面提到的 "hack",以便所有行之间具有一致的行为。
看看这个 codepen 更新的测试用例。