在Chrome中以大行高将插入符放置在可编辑的内容中

时间:2019-07-01 14:17:00

标签: html css contenteditable quill

在可编辑区域内单击较大行高时,macOS上的Chrome和Linux上的Chromium不会明智地定位插入符号。

在此示例中,我们为line-height元素的<span>设置了一个值。由于其他应用程序的要求(主要是使用Quill.js RTF编辑器),无法将其保留并从父元素继承是不可能的。每行可能有多个<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行为?

注意:按建议的here给跨度display: inline-block不能解决问题。

1 个答案:

答案 0 :(得分:5)

您已经知道,它与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 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并妥协以将多余的空间“分配”到下面的行中(仅在Chrome-Linux中)。

请注意,第一行仍然需要前面提到的“ hack”,以便所有行之间具有一致的行为。

请查看此codepen,以获取更新的测试用例。